<commit_before>/*
 *  Modular - JavaScript AMD framework
 *  Copyright (c) 2012 http://ovms.co. All Rights Reserved.
 *
 *  ====
 *
 *  This file is part of Modular.
 *
 *  Modular is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Modular is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Modular.  If not, see <http://www.gnu.org/licenses/>.
 */

/*global define, require */

(function () {
    "use strict";

    var global = new Function("return this;")(),
        defaults = {},
        pendings = {},
        modules = {};

    function each(obj, callback) {
        var key;

        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                callback.call(obj[key], obj[key], key);
            }
        }

        return obj;
    }

    function extend(target) {
        each([].slice.call(arguments, 1), function () {
            each(this, function (val, key) {
                target[key] = val;
            });
        });

        return target;
    }

    function getType(obj) {
        return {}.toString.call(obj).match(/\[object ([\s\S]*)\]/)[1];
    }

    function isString(str) {
        return typeof str === "string" || getType(str) === "String";
    }

    function isPlainObject(obj) {
        return getType(obj) === "Object";
    }

    function isArray(str) {
        return getType(str) === "Array";
    }

    function isFunction(str) {
        return getType(str) === "Function";
    }

    function getBasePath(path) {
        path = path.replace(/[^\/]+$/, "");

        if (path.charAt(path.length - 1) !== "/") {
            path += "/";
        }

        return path;
    }

    function makePath(path1, path2) {
        // TODO: Resolve parent dir selectors etc.
        var path = getBasePath(path1) + path2,
            previousPath = "";

        path = path.replace(/\/\.\//g, "/"); // Resolve same-directory symbols

        // Resolve parent-directory symbols
        while (previousPath !== path) {
            previousPath = path;
            path = path.replace(/[^\/]*\/\.\.\//, "");
        }

        // Append implicit ".js" extension
        if (path.substr(path.length - 3) !== ".js") {
            path += ".js";
        }

        return path;
    }

    function loadModule(config, path, dependencies, closure) {
        var basePath = path || config.baseUrl || require.getBasePath();

        function allDependenciesLoaded() {
            var moduleValue = null;

            function processDependents() {
                var callbacks;

                modules[path] = moduleValue;

                if (pendings[path]) {
                    callbacks = pendings[path];

                    delete pendings[path];

                    each(callbacks, function (dependencyLoaded) {
                        dependencyLoaded();
                    });
                }
            }

            function evaluateModule() {
                var args = [];

                each(dependencies, function (dependencyPath) {
                    var fullPath = makePath(basePath, dependencyPath);

                    if (dependencyPath === "require") {
                        // TODO: Scoped require
                        /*args.push(function () {
                            alert("TODO: scoped require!");
                        });*/
                    } else {
                        args.push(modules[dependencyPath] || modules[fullPath]);
                    }
                });

                return closure.apply(global, args);
            }

            moduleValue = evaluateModule();

            if (path) {
                // Modules may have no path (eg. an anonymous require(...))
                processDependents();
            }
        }

        function dependencyLoaded() {
            var allResolved = true;

            each(dependencies, function (dependencyPath) {
                var fullPath = makePath(basePath, dependencyPath);

                if (dependencyPath !== "require" && !modules[dependencyPath] && !modules[fullPath]) {
                    allResolved = false;
                }
            });

            if (allResolved) {
                allDependenciesLoaded();
            }
        }

        function checkDependencies() {
            var allResolved = true;

            each(dependencies, function (dependencyPath) {
                var fullPath = makePath(basePath, dependencyPath);

                if (dependencyPath !== "require" && !modules[dependencyPath] && !modules[fullPath]) {
                    if (!pendings[fullPath]) {
                        pendings[fullPath] = [];

                        require.get(fullPath, loadModule);
                    }

                    pendings[fullPath].push(dependencyLoaded);

                    allResolved = false;
                }
            });

            if (allResolved) {
                allDependenciesLoaded();
            }
        }

        config = extend({}, defaults, config);

        checkDependencies();
    }

    function overload(arg1, arg2, arg3, arg4) {
        var config = {},
            path = null,
            dependencies = [],
            closure = function () {};

        if (isPlainObject(arg1)) {
            config = arg1;
        } else if (isString(arg1)) {
            path = arg1;
        } else if (isArray(arg1)) {
            dependencies = arg1;
        } else if (isFunction(arg1)) {
            closure = arg1;
        }

        if (isString(arg2)) {
            path = arg2;
        } else if (isArray(arg2)) {
            dependencies = arg2;
        } else if (isFunction(arg2)) {
            closure = arg2;
        }

        if (isArray(arg3)) {
            dependencies = arg3;
        } else if (isFunction(arg3)) {
            closure = arg3;
        }

        if (isFunction(arg4)) {
            closure = arg4;
        }

        return {
            config: config,
            path: path,
            dependencies: dependencies,
            closure: closure
        };
    }

    function require(arg1, arg2, arg3, arg4) {
        var data = overload(arg1, arg2, arg3, arg4);

        loadModule(data.config, null, data.dependencies, data.closure);
    }

    function define(arg1, arg2, arg3, arg4) {
        var data = overload(arg1, arg2, arg3, arg4);

        if (data.path) {
            loadModule(data.config, data.path, data.dependencies, data.closure);
        } else {
            require.define(data);
        }
    }

    define.amd = {
        jQuery: true
    };

    extend(require, (function () {
        var head = global.document.getElementsByTagName("head")[0],
            defines = [];

        return {
            getBasePath: function () {
                return global.location.pathname;
            },
            // Overridable - called when a module needs to be loaded
            get: function (path, loadModule) {
                var script = global.document.createElement("script");

                script.setAttribute("type", "text/javascript");
                script.setAttribute("src", path);

                script.onload = script.onreadystatechange = function () {
                    var data;

                    if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") {
                        data = defines.pop();

                        loadModule(data.config, data.path || path, data.dependencies, data.closure);
                    }

                    script.onload = script.onreadystatechange = null;
                };

                head.insertBefore(script, head.firstChild);
            },
            define: function (data) {
                defines.push(data);
            }
        };
    }()));

    // Exports
    global.require = require;
    global.define = define;
}());
<commit_msg>Refactored to enable scoped require(...) support<commit_after>/*
 *  Modular - JavaScript AMD framework
 *  Copyright (c) 2012 http://ovms.co. All Rights Reserved.
 *
 *  ====
 *
 *  This file is part of Modular.
 *
 *  Modular is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Modular is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Modular.  If not, see <http://www.gnu.org/licenses/>.
 */

/*global define, require */

(function () {
    "use strict";

    var global = new Function("return this;")(),
        defaults = {},
        pendings = {},
        modules = {};

    function each(obj, callback) {
        var key;

        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                callback.call(obj[key], obj[key], key);
            }
        }

        return obj;
    }

    function extend(target) {
        each([].slice.call(arguments, 1), function () {
            each(this, function (val, key) {
                target[key] = val;
            });
        });

        return target;
    }

    function getType(obj) {
        return {}.toString.call(obj).match(/\[object ([\s\S]*)\]/)[1];
    }

    function isString(str) {
        return typeof str === "string" || getType(str) === "String";
    }

    function isPlainObject(obj) {
        return getType(obj) === "Object";
    }

    function isArray(str) {
        return getType(str) === "Array";
    }

    function isFunction(str) {
        return getType(str) === "Function";
    }

    function getBasePath(path) {
        path = path.replace(/[^\/]+$/, "");

        if (path.charAt(path.length - 1) !== "/") {
            path += "/";
        }

        return path;
    }

    function makePath(path1, path2) {
        // TODO: Resolve parent dir selectors etc.
        var path = getBasePath(path1) + path2,
            previousPath = "";

        path = path.replace(/\/\.\//g, "/"); // Resolve same-directory symbols

        // Resolve parent-directory symbols
        while (previousPath !== path) {
            previousPath = path;
            path = path.replace(/[^\/]*\/\.\.\//, "");
        }

        // Append implicit ".js" extension
        if (path.substr(path.length - 3) !== ".js") {
            path += ".js";
        }

        return path;
    }

    function parse(arg1, arg2, arg3, arg4) {
        var config = {},
            path = null,
            dependencies = [],
            closure = function () {};

        if (isPlainObject(arg1)) {
            config = arg1;
        } else if (isString(arg1)) {
            path = arg1;
        } else if (isArray(arg1)) {
            dependencies = arg1;
        } else if (isFunction(arg1)) {
            closure = arg1;
        }

        if (isString(arg2)) {
            path = arg2;
        } else if (isArray(arg2)) {
            dependencies = arg2;
        } else if (isFunction(arg2)) {
            closure = arg2;
        }

        if (isArray(arg3)) {
            dependencies = arg3;
        } else if (isFunction(arg3)) {
            closure = arg3;
        }

        if (isFunction(arg4)) {
            closure = arg4;
        }

        config = extend({}, defaults, config);

        return {
            config: config,
            path: path,
            dependencies: dependencies,
            closure: closure
        };
    }

    function ready(path, dependencies, closure, fetch) {
        function allDependenciesLoaded() {
            var moduleValue = null;

            function processDependents() {
                var callbacks;

                modules[path] = moduleValue;

                if (pendings[path]) {
                    callbacks = pendings[path];

                    delete pendings[path];

                    each(callbacks, function (dependencyLoaded) {
                        dependencyLoaded();
                    });
                }
            }

            function evaluateModule() {
                var args = [];

                each(dependencies, function (dependencyPath) {
                    var fullPath = makePath(path, dependencyPath);

                    if (dependencyPath === "require") {
                        // TODO: Scoped require
                        args.push(function (arg1, arg2, arg3, arg4) {
                            var args = parse(arg1, arg2, arg3, arg4);

                            global.require(extend({}, args.config, {
                                baseUrl: path
                            }), args.path, args.dependencies, args.closure);
                        });
                    } else {
                        args.push(modules[dependencyPath] || modules[fullPath]);
                    }
                });

                return closure.apply(global, args);
            }

            moduleValue = evaluateModule();

            if (path) {
                // Modules may have no path (eg. an anonymous require(...))
                processDependents();
            }
        }

        function dependencyLoaded() {
            var allResolved = true;

            each(dependencies, function (dependencyPath) {
                var fullPath = makePath(path, dependencyPath);

                if (dependencyPath !== "require" && !modules[dependencyPath] && !modules[fullPath]) {
                    allResolved = false;
                }
            });

            if (allResolved) {
                allDependenciesLoaded();
            }
        }

        function checkDependencies() {
            var allResolved = true;

            each(dependencies, function (dependencyPath) {
                var fullPath = makePath(path, dependencyPath);

                if (dependencyPath !== "require" && !modules[dependencyPath] && !modules[fullPath]) {
                    if (!pendings[fullPath]) {
                        pendings[fullPath] = [];

                        fetch(fullPath, ready);
                    }

                    pendings[fullPath].push(dependencyLoaded);

                    allResolved = false;
                }
            });

            if (allResolved) {
                allDependenciesLoaded();
            }
        }

        checkDependencies();
    }

    // Exports
    global.require = function (arg1, arg2, arg3, arg4) {
        var args = parse(arg1, arg2, arg3, arg4);

        ready(args.path || args.config.baseUrl, args.dependencies, args.closure, args.config.fetch);
    };
    global.define = function (arg1, arg2, arg3, arg4) {
        var args = parse(arg1, arg2, arg3, arg4);

        if (args.path) {
            ready(args.path, args.dependencies, args.closure, args.config.fetch);
        } else {
            args.config.anonymous(args);
        }
    };

    // Publish support for the AMD pattern
    global.define.amd = {
        jQuery: true
    };

    extend(defaults, (function () {
        var head = global.document.getElementsByTagName("head")[0],
            anonymouses = [];

        return {
            baseUrl: global.location.pathname,
            // Overridable - called when a module needs to be loaded
            fetch: function fetch(path, ready) {
                var script = global.document.createElement("script");

                script.setAttribute("type", "text/javascript");
                script.setAttribute("src", path);

                script.onload = script.onreadystatechange = function () {
                    var args;

                    if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") {
                        args = anonymouses.pop();

                        ready(args.path || path, args.dependencies, args.closure, fetch);
                    }

                    script.onload = script.onreadystatechange = null;
                };

                head.insertBefore(script, head.firstChild);
            },
            anonymous: function (args) {
                anonymouses.push(args);
            }
        };
    }()));
}());
<|endoftext|>


<commit_before>#!/usr/bin/env node
var path = require('path');
var badge = require(path.join(__dirname, 'badge.js'));
var svg2img = require(path.join(__dirname, 'svg-to-img.js'));
var colorscheme = require(path.join(__dirname, 'colorscheme.json'));
if (process.argv.length < 4) {
  console.log('Usage: badge subject status [:colorscheme] [.output]');
  console.log('Or:    badge subject status right-color [left-color] [.output]');
  console.log();
  console.log('  colorscheme: one of '
      + Object.keys(colorscheme).join(', ') + '.');
  console.log('  left-color, right-color:');
  console.log('    #xxx (three hex digits)');
  console.log('    #xxxxxx (six hex digits)');
  console.log('    color (CSS color)');
  console.log('  output:');
  console.log('    svg, png, jpg, or gif');
  console.log();
  console.log('Eg: badge cactus grown :green');
  console.log();
  process.exit();
}

// Find a format specifier.
var format = 'svg';
for (var i = 4; i < process.argv.length; i++) {
  if (process.argv[i][0] === '.') {
    format = process.argv[i].slice(1);
    process.argv.splice(i, 1);
  }
}

var subject = process.argv[2];
var status = process.argv[3];
var color = process.argv[4] || ':green';
var colorA = process.argv[5];

var badgeData = {text: [subject, status]};

if (color[0] === ':') {
  color = color.slice(1);
  if (colorscheme[color] == null) {
    // Colorscheme not found.
    console.error('Invalid color scheme.');
    process.exit(1);
  }
  badgeData.colorscheme = color;
} else {
  badgeData.colorB = color;
  if (colorA) { badgeData.colorA = colorA; }
}

badge(badgeData, function produceOutput(svg) {
  if (format === 'svg') {
    console.log(svg);
  } else if (/png|jpg|gif/.test(format)) {
    svg2img(svg, format, process.stdout);
  }
});
<commit_msg>fix colorsche.ejson path in tests<commit_after>#!/usr/bin/env node
var path = require('path');
var badge = require(path.join(__dirname, 'badge.js'));
var svg2img = require(path.join(__dirname, 'svg-to-img.js'));
var colorscheme = require(path.join(__dirname, 'templates', 'default-colorscheme.json'));
if (process.argv.length < 4) {
  console.log('Usage: badge subject status [:colorscheme] [.output]');
  console.log('Or:    badge subject status right-color [left-color] [.output]');
  console.log();
  console.log('  colorscheme: one of '
      + Object.keys(colorscheme).join(', ') + '.');
  console.log('  left-color, right-color:');
  console.log('    #xxx (three hex digits)');
  console.log('    #xxxxxx (six hex digits)');
  console.log('    color (CSS color)');
  console.log('  output:');
  console.log('    svg, png, jpg, or gif');
  console.log();
  console.log('Eg: badge cactus grown :green');
  console.log();
  process.exit();
}

// Find a format specifier.
var format = 'svg';
for (var i = 4; i < process.argv.length; i++) {
  if (process.argv[i][0] === '.') {
    format = process.argv[i].slice(1);
    process.argv.splice(i, 1);
  }
}

var subject = process.argv[2];
var status = process.argv[3];
var color = process.argv[4] || ':green';
var colorA = process.argv[5];

var badgeData = {text: [subject, status]};

if (color[0] === ':') {
  color = color.slice(1);
  if (colorscheme[color] == null) {
    // Colorscheme not found.
    console.error('Invalid color scheme.');
    process.exit(1);
  }
  badgeData.colorscheme = color;
} else {
  badgeData.colorB = color;
  if (colorA) { badgeData.colorA = colorA; }
}

badge(badgeData, function produceOutput(svg) {
  if (format === 'svg') {
    console.log(svg);
  } else if (/png|jpg|gif/.test(format)) {
    svg2img(svg, format, process.stdout);
  }
});
<|endoftext|>


<commit_before>var Crawler = require("crawler");
var url = require('url');

var c = new Crawler({
    maxConnections : 10,
    // This will be called for each crawled page
    callback : function (error, result, $) {
        // $ is Cheerio by default
        //a lean implementation of core jQuery designed specifically for the server
        $('a').each(function(index, a) {
            var toQueueUrl = $(a).attr('href');
            c.queue(toQueueUrl);
        });
    }
});

// Queue just one URL, with default callback
c.queue('http://www.iwrp.net/?view=contestant&id_zawodnik=1');<commit_msg>parsing names from pages<commit_after>var Crawler = require("crawler");
var url = require('url');

var c = new Crawler({
    maxConnections : 10,
    // This will be called for each crawled page
    callback : function (error, result, $) {
        // $ is Cheerio by default
        //a lean implementation of core jQuery designed specifically for the server

        if(result) {
            var page = result.body;
            //console.log(page);
            console.log($('.nazwa_pogrubiona').text());
        }
    }
});

var search = function(search) {
  return 'http://www.iwrp.net/?view=contestant&id_zawodnik=' + search;
};

for(i = 1; i < 34000; i++) {
    c.queue({
        uri: search(i)
    });
}
<|endoftext|>


<commit_before>/*
 *  Modular - JavaScript AMD framework
 *  Copyright (c) 2012 http://ovms.co. All Rights Reserved.
 *
 *  ====
 *
 *  This file is part of Modular.
 *
 *  Modular is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Modular is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Modular.  If not, see <http://www.gnu.org/licenses/>.
 */

/*global define, require */

(function () {
    "use strict";

    var global = new Function("return this;")(),
        defaults = {
            "baseUrl": "",
            "fetch": function (path, ready) {},
            "anonymous": function (args) {}
        },
        pendings = {},
        modules = {};

    function each(obj, callback) {
        var key;

        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                if (callback.call(obj[key], obj[key], key) === false) {
                    break;
                }
            }
        }

        return obj;
    }

    function extend(target) {
        each([].slice.call(arguments, 1), function () {
            each(this, function (val, key) {
                target[key] = val;
            });
        });

        return target;
    }

    function getType(obj) {
        return {}.toString.call(obj).match(/\[object ([\s\S]*)\]/)[1];
    }

    function isString(str) {
        return typeof str === "string" || getType(str) === "String";
    }

    function isPlainObject(obj) {
        return getType(obj) === "Object";
    }

    function isArray(str) {
        return getType(str) === "Array";
    }

    function isFunction(str) {
        return getType(str) === "Function";
    }

    function getBasePath(path) {
        path = path.replace(/[^\/]+$/, "");

        if (path.charAt(path.length - 1) !== "/") {
            path += "/";
        }

        return path;
    }

    function makePath(basePath, currentPath, path, pathMappings) {
        var previousPath = "",
            components = path.split("/");

        each(pathMappings || {}, function (to, from) {
            if (components[0] === from) {
                components[0] = to;
            }
        });

        path = components.join("/");

        path = getBasePath(/^\.\.?\//.test(path) ? currentPath : basePath) + path;

        path = path.replace(/\/\.\//g, "/"); // Resolve same-directory symbols

        // Resolve parent-directory symbols
        while (previousPath !== path) {
            previousPath = path;
            path = path.replace(/[^\/]*\/\.\.\//, "");
        }

        // Append implicit ".js" extension
        if (path.substr(path.length - 3) !== ".js") {
            path += ".js";
        }

        return path;
    }

    function parse(arg1, arg2, arg3, arg4) {
        var config,
            path,
            dependencies,
            closure;

        if (isPlainObject(arg1)) {
            config = arg1;
        } else if (isString(arg1)) {
            path = arg1;
        } else if (isArray(arg1)) {
            dependencies = arg1;
        } else if (isFunction(arg1)) {
            closure = arg1;
        }

        if (isString(arg2)) {
            path = arg2;
        } else if (isArray(arg2)) {
            dependencies = arg2;
        } else if (isFunction(arg2)) {
            closure = arg2;
        }

        if (isArray(arg3)) {
            dependencies = arg3;
        } else if (isFunction(arg3)) {
            closure = arg3;
        }

        if (isFunction(arg4)) {
            closure = arg4;
        }

        if (config && !path && !dependencies && !closure) {
            closure = config;
            config = null;
        }

        return {
            config: config || {},
            path: path || null,
            dependencies: dependencies || [],
            closure: closure || function () {}
        };
    }

    function findModule(names) {
        var result = null;

        each(names, function (name) {
            if (modules.hasOwnProperty(name)) {
                result = name;

                return false;
            }
        });

        return result;
    }

    function getModule(names) {
        var name = findModule(names);

        return name ? modules[name] : null;
    }

    function ready(config, path, dependencies, closure, options) {
        var fetched = false;

        function allDependenciesLoaded() {
            var moduleValue = null;

            function processDependents() {
                var callbacks;

                // Caching may be explicitly disabled, eg. for scoped requires (which would otherwise
                //  overwrite their container module)
                if (options.cache !== false) {
                    modules[path] = moduleValue;
                }

                if (pendings[path]) {
                    callbacks = pendings[path];

                    delete pendings[path];

                    each(callbacks, function (dependencyLoaded) {
                        dependencyLoaded();
                    });
                }
            }

            function evaluateModule() {
                var args = [];

                each(dependencies, function (dependencyPath) {
                    var fullPath = makePath(config.baseUrl, path, dependencyPath, config.paths);

                    // Scoped require support
                    if (dependencyPath === "require") {
                        args.push(function (arg1, arg2, arg3, arg4) {
                            var args = parse(arg1, arg2, arg3, arg4);

                            ready(extend({}, config, args.config), args.path || path, args.dependencies, args.closure, {
                                cache: false
                            });
                        });
                    } else {
                        args.push(getModule([dependencyPath, fullPath]));
                    }
                });

                return isFunction(closure) ? closure.apply(global, args) : closure;
            }

            moduleValue = evaluateModule();

            // Modules may have no path (eg. an anonymous require(...))
            processDependents();
        }

        function checkDependencies() {
            var allResolved = true;

            each(dependencies, function (dependencyPath) {
                var fullPath = makePath(config.baseUrl, path, dependencyPath, config.paths);

                if (dependencyPath !== "require" && !findModule([dependencyPath, fullPath])) {
                    if (!fetched) {
                        if (!pendings[fullPath]) {
                            pendings[fullPath] = [];

                            config.fetch(fullPath, ready);
                        }

                        pendings[fullPath].push(checkDependencies);
                    }

                    allResolved = false;
                }
            });

            fetched = true;

            if (allResolved) {
                allDependenciesLoaded();
            }
        }

        options = options || {};

        checkDependencies();
    }

    function require(arg1, arg2, arg3, arg4) {
        var args = parse(arg1, arg2, arg3, arg4);

        ready(extend({}, defaults, args.config), args.path || args.config.baseUrl, args.dependencies, args.closure);
    }

    function define(arg1, arg2, arg3, arg4) {
        var args = parse(arg1, arg2, arg3, arg4),
            config = extend({}, defaults, args.config);

        if (args.path) {
            ready(config, args.path, args.dependencies, args.closure);
        } else {
            config.anonymous(args);
        }
    }

    extend(require, {
        "config": function (config) {
            extend(defaults, config);
        },
        "onError": function (msg) {
            throw new Error(msg);
        }
    });

    extend(define, {
        // Publish support for the AMD pattern
        "amd": {
            "jQuery": true
        }
    });

    // Exports
    extend(global, {
        "require": require,
        "requirejs": require,
        "define": define
    });

    // Browser environment support
    if (global.document) {
        extend(defaults, (function () {
            var head = global.document.getElementsByTagName("head")[0],
                on = head.addEventListener ? function (node, type, callback) {
                    node.addEventListener(type, callback, false);
                } : function (node, type, callback) {
                    node.attachEvent("on" + type, callback);
                },
                off = head.removeEventListener ? function (node, type, callback) {
                    node.removeEventListener(type, callback, false);
                } : function (node, type, callback) {
                    node.detachEvent("on" + type, callback);
                },
                useOnLoad = head.addEventListener,
                anonymouses = [];

            return {
                "baseUrl": global.location.pathname,
                // Overridable - called when a module needs to be loaded
                "fetch": function (path, ready) {
                    var script = global.document.createElement("script"),
                        config = this;

                    on(script, useOnLoad ? "load" : "readystatechange", function onLoad(evt) {
                        var args;

                        if (evt.type === "load" || this.readyState === "loaded" || this.readyState === "complete") {
                            args = anonymouses.pop();

                            if (args) {
                                ready(extend({}, config, args.config), args.path || path, args.dependencies, args.closure);
                            } else {
                                ready({}, path, [], null);
                            }
                        }

                        off(script, useOnLoad ? "load" : "readystatechange", onLoad);
                    });

                    script.setAttribute("type", "text/javascript");
                    script.setAttribute("src", path);

                    head.insertBefore(script, head.firstChild);
                },
                "anonymous": function (args) {
                    anonymouses.push(args);
                }
            };
        }()));
    }
}());
<commit_msg>Refactored to support data-main attribute<commit_after>/*
 *  Modular - JavaScript AMD framework
 *  Copyright (c) 2012 http://ovms.co. All Rights Reserved.
 *
 *  ====
 *
 *  This file is part of Modular.
 *
 *  Modular is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Modular is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Modular.  If not, see <http://www.gnu.org/licenses/>.
 */

/*global define, require */

(function () {
    "use strict";

    var global = new Function("return this;")(),
        defaults = {
            "baseUrl": "",
            "fetch": function (path, ready) {},
            "anonymous": function (args) {}
        },
        pendings = {},
        modules = {};

    function each(obj, callback) {
        var key,
            length;

        if (!obj) {
            return;
        }

        if (obj.hasOwnProperty("length")) {
            for (key = 0, length = obj.length; key < length; key += 1) { // Keep JSLint happy with "+= 1"
                if (obj.hasOwnProperty(key)) {
                    if (callback.call(obj[key], obj[key], key) === false) {
                        break;
                    }
                }
            }
        } else {
            for (key in obj) {
                if (obj.hasOwnProperty(key)) {
                    if (callback.call(obj[key], obj[key], key) === false) {
                        break;
                    }
                }
            }
        }
    }

    function extend(target) {
        each([].slice.call(arguments, 1), function () {
            each(this, function (val, key) {
                target[key] = val;
            });
        });

        return target;
    }

    function getType(obj) {
        return {}.toString.call(obj).match(/\[object ([\s\S]*)\]/)[1];
    }

    function isString(str) {
        return typeof str === "string" || getType(str) === "String";
    }

    function isPlainObject(obj) {
        return getType(obj) === "Object";
    }

    function isArray(str) {
        return getType(str) === "Array";
    }

    function isFunction(str) {
        return getType(str) === "Function";
    }

    function getBasePath(path) {
        path = path.replace(/[^\/]+$/, "");

        if (path.charAt(path.length - 1) !== "/") {
            path += "/";
        }

        return path;
    }

    function implicitExtension(path) {
        if (path.substr(path.length - 3) !== ".js") {
            path += ".js";
        }

        return path;
    }

    function makePath(basePath, currentPath, path, pathMappings) {
        var previousPath = "",
            components = path.split("/");

        each(pathMappings || {}, function (to, from) {
            if (components[0] === from) {
                components[0] = to;
            }
        });

        path = components.join("/");

        path = getBasePath(/^\.\.?\//.test(path) ? currentPath : basePath) + path;

        path = path.replace(/\/\.\//g, "/"); // Resolve same-directory symbols

        // Resolve parent-directory symbols
        while (previousPath !== path) {
            previousPath = path;
            path = path.replace(/[^\/]*\/\.\.\//, "");
        }

        return implicitExtension(path);
    }

    function parse(arg1, arg2, arg3, arg4) {
        var config,
            path,
            dependencies,
            closure;

        if (isPlainObject(arg1)) {
            config = arg1;
        } else if (isString(arg1)) {
            path = arg1;
        } else if (isArray(arg1)) {
            dependencies = arg1;
        } else if (isFunction(arg1)) {
            closure = arg1;
        }

        if (isString(arg2)) {
            path = arg2;
        } else if (isArray(arg2)) {
            dependencies = arg2;
        } else if (isFunction(arg2)) {
            closure = arg2;
        }

        if (isArray(arg3)) {
            dependencies = arg3;
        } else if (isFunction(arg3)) {
            closure = arg3;
        }

        if (isFunction(arg4)) {
            closure = arg4;
        }

        if (config && !path && !dependencies && !closure) {
            closure = config;
            config = null;
        }

        return {
            config: config || {},
            path: path || null,
            dependencies: dependencies || [],
            closure: closure || function () {}
        };
    }

    function findModule(names) {
        var result = null;

        each(names, function (name) {
            if (modules.hasOwnProperty(name)) {
                result = name;

                return false;
            }
        });

        return result;
    }

    function getModule(names) {
        var name = findModule(names);

        return name ? modules[name] : null;
    }

    function depend(path, fetch, recheck) {
        if (!pendings[path]) {
            pendings[path] = [];

            fetch(path);
        }

        if (recheck) {
            pendings[path].push(recheck);
        }
    }

    function ready(config, path, dependencies, closure, options) {
        var fetched = false;

        function allDependenciesLoaded() {
            var moduleValue = null;

            function processDependents() {
                var callbacks;

                // Caching may be explicitly disabled, eg. for scoped requires (which would otherwise
                //  overwrite their container module)
                if (options.cache !== false) {
                    modules[path] = moduleValue;
                }

                if (pendings[path]) {
                    callbacks = pendings[path];

                    delete pendings[path];

                    each(callbacks, function (dependencyLoaded) {
                        dependencyLoaded();
                    });
                }
            }

            function evaluateModule() {
                var args = [];

                each(dependencies, function (dependencyPath) {
                    var fullPath = makePath(config.baseUrl, path, dependencyPath, config.paths);

                    // Scoped require support
                    if (dependencyPath === "require") {
                        args.push(function (arg1, arg2, arg3, arg4) {
                            var args = parse(arg1, arg2, arg3, arg4);

                            ready(extend({}, config, args.config), args.path || path, args.dependencies, args.closure, {
                                cache: false
                            });
                        });
                    } else {
                        args.push(getModule([dependencyPath, fullPath]));
                    }
                });

                return isFunction(closure) ? closure.apply(global, args) : closure;
            }

            moduleValue = evaluateModule();

            // Modules may have no path (eg. an anonymous require(...))
            processDependents();
        }

        function checkDependencies() {
            var allResolved = true;

            each(dependencies, function (dependencyPath) {
                var fullPath = makePath(config.baseUrl, path, dependencyPath, config.paths);

                if (dependencyPath !== "require" && !findModule([dependencyPath, fullPath])) {
                    if (!fetched) {
                        depend(fullPath, function (path) {
                            config.fetch(path, ready);
                        }, checkDependencies);
                    }

                    allResolved = false;
                }
            });

            fetched = true;

            if (allResolved) {
                allDependenciesLoaded();
            }
        }

        options = options || {};

        checkDependencies();
    }

    function require(arg1, arg2, arg3, arg4) {
        var args = parse(arg1, arg2, arg3, arg4);

        ready(extend({}, defaults, args.config), args.path || args.config.baseUrl, args.dependencies, args.closure);
    }

    function define(arg1, arg2, arg3, arg4) {
        var args = parse(arg1, arg2, arg3, arg4),
            config = extend({}, defaults, args.config);

        if (args.path) {
            ready(config, args.path, args.dependencies, args.closure);
        } else {
            config.anonymous(args);
        }
    }

    extend(require, {
        "config": function (config) {
            extend(defaults, config);
        },
        "onError": function (msg) {
            throw new Error(msg);
        }
    });

    extend(define, {
        // Publish support for the AMD pattern
        "amd": {
            "jQuery": true
        }
    });

    // Exports
    extend(global, {
        "require": require,
        "requirejs": require,
        "define": define
    });

    // Browser environment support
    if (global.document) {
        extend(defaults, (function () {
            var head = global.document.getElementsByTagName("head")[0],
                on = head.addEventListener ? function (node, type, callback) {
                    node.addEventListener(type, callback, false);
                } : function (node, type, callback) {
                    node.attachEvent("on" + type, callback);
                },
                off = head.removeEventListener ? function (node, type, callback) {
                    node.removeEventListener(type, callback, false);
                } : function (node, type, callback) {
                    node.detachEvent("on" + type, callback);
                },
                useOnLoad = head.addEventListener,
                anonymouses = [];

            return {
                "baseUrl": global.location.pathname,
                // Overridable - called when a module needs to be loaded
                "fetch": function (path, ready) {
                    var script = global.document.createElement("script"),
                        config = this;

                    on(script, useOnLoad ? "load" : "readystatechange", function onLoad(evt) {
                        var args;

                        if (evt.type === "load" || this.readyState === "loaded" || this.readyState === "complete") {
                            args = anonymouses.pop();

                            if (args) {
                                ready(extend({}, config, args.config), args.path || path, args.dependencies, args.closure);
                            } else {
                                ready({}, path, [], null);
                            }
                        }

                        off(script, useOnLoad ? "load" : "readystatechange", onLoad);
                    });

                    script.setAttribute("type", "text/javascript");
                    script.setAttribute("src", path);

                    head.insertBefore(script, head.firstChild);
                },
                "anonymous": function (args) {
                    anonymouses.push(args);
                }
            };
        }()));

        each(global.document.getElementsByTagName("script"), function () {
            var main = this.getAttribute("data-main");

            if (main) {
                depend(implicitExtension(main), function (path) {
                    defaults.fetch(path, ready);
                });
            }
        });
    }
}());
<|endoftext|>


<commit_before>var assert = require('assert');
var bn = require('bn.js');
var bcoin = require('../');

function printScript(input) {
  var scripts = [];
  var script = input.script;
  scripts.push(script);
  var prev = input.out.tx.outputs[input.out.index].script;
  scripts.push(prev);
  if (bcoin.script.isScripthash(prev)) {
    var redeem = bcoin.script.decode(input.script[input.script.length - 1]);
    scripts.push(redeem);
  }
  scripts = scripts.map(function(script) {
    return script.map(function(chunk) {
      if (Array.isArray(chunk)) {
        if (chunk.length === 0)
          return [0];
        return [bcoin.utils.toHex(chunk)];
      }
      if (typeof chunk === 'number')
        return [chunk];
      return chunk;
    });
  });
  scripts.forEach(function(script) {
    console.log(script);
  });
}

describe('Wallet', function() {
  it('should generate new key and address', function() {
    var w = bcoin.wallet();
    var addr = w.getAddress();
    assert(addr);
    assert(bcoin.wallet.validateAddress(addr));
  });

  it('should validate existing address', function() {
    assert(bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc'));
  });

  it('should fail to validate invalid address', function() {
    assert(!bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc'));
  });

  it('should sign/verify TX', function() {
    var w = bcoin.wallet();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        address: w.getAddress()
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    w.sign(tx);
    assert(tx.verify());
  });

  it('should multisign/verify TX', function() {
    var w = bcoin.wallet();
    var k2 = bcoin.wallet().getPublicKey();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        minSignatures: 1,
        keys: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
        // keys: [ w.getPublicKey(), k2 ]
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    var maxSize = tx.maxSize();
    w.sign(tx);
    assert(tx.render().length <= maxSize);
    assert(tx.verify());
  });

  it('should have TX pool and be serializable', function() {
    var w = bcoin.wallet();
    var f = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w, 50000).out(w, 1000);
    w.sign(t1);
    var t2 = bcoin.tx().input(t1, 0)
                       .out(w, 24000)
                       .out(w, 24000);
    w.sign(t2);
    var t3 = bcoin.tx().input(t1, 1)
                       .input(t2, 0)
                       .out(w, 23000);
    w.sign(t3);
    var t4 = bcoin.tx().input(t2, 1)
                       .input(t3, 0)
                       .out(w, 11000)
                       .out(w, 11000);
    w.sign(t4);
    var f1 = bcoin.tx().input(t4, 1)
                       .out(f, 10000);
    w.sign(f1);
    var fake = bcoin.tx().input(t1, 1)
                         .out(w, 500);

    // Just for debugging
    t1.hint = 't1';
    t2.hint = 't2';
    t3.hint = 't3';
    t4.hint = 't4';
    f1.hint = 'f1';
    fake.hint = 'fake';

    // Fake TX should temporarly change output
    w.addTX(fake);

    w.addTX(t4);
    assert.equal(w.balance().toString(10), '22500');
    w.addTX(t1);
    assert.equal(w.balance().toString(10), '73000');
    w.addTX(t2);
    assert.equal(w.balance().toString(10), '47000');
    w.addTX(t3);
    assert.equal(w.balance().toString(10), '22000');
    w.addTX(f1);
    assert.equal(w.balance().toString(10), '11000');
    assert(w.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));

    var w2 = bcoin.wallet.fromJSON(w.toJSON());
    assert.equal(w2.balance().toString(10), '11000');
    assert(w2.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));
  });

  it('should fill tx with inputs', function(cb) {
    var w1 = bcoin.wallet();
    var w2 = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);

    // Fake TX should temporarly change output
    w1.addTX(t1);

    // Create new transaction
    var t2 = bcoin.tx().out(w2, 5460);
    w1.fill(t2, function(err) {
      assert(!err);
      assert(t2.verify());

      assert.equal(t2.funds('in').toString(10), 16380);
      // If change < dust and is added to outputs:
      // assert.equal(t2.funds('out').toString(10), 6380);
      // If change < dust and is added to fee:
      assert.equal(t2.funds('out').toString(10), 5460);

      // Create new transaction
      var t3 = bcoin.tx().out(w2, 15000);
      w1.fill(t3, function(err) {
        assert(err);
        assert.equal(err.minBalance.toString(10), 25000);

        cb();
      });
    });
  });

  it('should sign multiple inputs using different keys', function(cb) {
    var w1 = bcoin.wallet();
    var w2 = bcoin.wallet();
    var to = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);
    // Fake TX should temporarly change output
    w1.addTX(t1);
    // Coinbase
    var t2 = bcoin.tx().out(w2, 5460).out(w2, 5460).out(w2, 5460).out(w2, 5460);
    // Fake TX should temporarly change output
    w2.addTX(t2);

    // Create our tx with an output
    var tx = bcoin.tx();
    tx.out(to, 5460);

    var cost = tx.funds('out');
    var total = cost.add(new bn(bcoin.tx.fee));

    var unspent1 = w1.unspent();
    var unspent2 = w2.unspent();

    // Add dummy output (for `left`) to calculate maximum TX size
    tx.out(w1, new bn(0));

    // Add our unspent inputs to sign
    tx.input(unspent1[0]);
    tx.input(unspent1[1]);
    tx.input(unspent2[0]);

    var left = tx.funds('in').sub(total);
    if (left.cmpn(bcoin.tx.dust) < 0) {
      tx.outputs[tx.outputs.length - 2].value.iadd(left);
      left = new bn(0);
    }
    if (left.cmpn(0) === 0)
      tx.outputs.pop();
    else
      tx.outputs[tx.outputs.length - 1].value = left;

    // Sign transaction
    assert.equal(w1.sign(tx), 2);
    assert.equal(w2.sign(tx), 1);

    // Verify
    assert.equal(tx.verify(), true);

    // Sign transaction using `inputs` and `off` params.
    tx.inputs.length = 0;
    tx.input(unspent1[1]);
    tx.input(unspent1[2]);
    tx.input(unspent2[1]);
    assert.equal(w1.sign(tx, 'all', tx.inputs.slice(), 0), 2);
    assert.equal(w2.sign(tx, 'all', tx.inputs.slice(2), 2), 1);

    // Verify
    assert.equal(tx.verify(), true);

    cb();
  });

  it('should verify 2-of-3 p2sh tx', function(cb) {
    var hd = bcoin.hd.priv();
    var hd1 = hd.derive(0);
    var hd2 = hd.derive(1);
    var hd3 = hd.derive(2);

    // Generate 3 key pairs
    var key1 = bcoin.ecdsa.genKeyPair();
    var key2 = bcoin.ecdsa.genKeyPair();
    var key3 = bcoin.ecdsa.genKeyPair();

    // var key1 = hd1;
    // var key2 = hd2;
    // var key3 = hd3;

    // Grab the 3 pubkeys
    var pub1 = key1.getPublic(true, 'array');
    var pub2 = key2.getPublic(true, 'array');
    var pub3 = key3.getPublic(true, 'array');

    // Create 3 2-of-3 wallets with our pubkeys as "shared keys"
    var w1 = bcoin.wallet({
      key: key1,
      multisig: {
        type: 'scripthash',
        keys: [pub2, pub3],
        m: 2,
        n: 3
      }
    });
    var w2 = bcoin.wallet({
      key: key2,
      multisig: {
        type: 'scripthash',
        keys: [pub1, pub3],
        m: 2,
        n: 3
      }
    });
    var w3 = bcoin.wallet({
      key: key3,
      multisig: {
        type: 'scripthash',
        keys: [pub1, pub2],
        m: 2,
        n: 3
      }
    });
    var receive = bcoin.wallet();

    // Our p2sh address
    var addr = w1.getAddress();
    assert.equal(w1.getAddress(), addr);
    assert.equal(w2.getAddress(), addr);
    assert.equal(w3.getAddress(), addr);

    // Add a shared unspent transaction to our wallets
    var utx = bcoin.tx();
    utx.output({ address: addr, value: 5460 * 10 });

    w1.addTX(utx);
    w2.addTX(utx);
    w3.addTX(utx);

    // Create a tx requiring 2 signatures
    var send = bcoin.tx();
    send.output({ address: receive.getAddress(), value: 5460 });
    assert(!send.verify());
    var result = w1.fill(send);
    assert(result);

    // printScript(send.inputs[0]);

    assert(!send.verify());
    w2.sign(send);

    assert(send.verify());

    send.inputs[0].script[2] = [];
    assert(!send.verify());

    cb();
  });
});
<commit_msg>test: check for fee.<commit_after>var assert = require('assert');
var bn = require('bn.js');
var bcoin = require('../');

function printScript(input) {
  var scripts = [];
  var script = input.script;
  scripts.push(script);
  var prev = input.out.tx.outputs[input.out.index].script;
  scripts.push(prev);
  if (bcoin.script.isScripthash(prev)) {
    var redeem = bcoin.script.decode(input.script[input.script.length - 1]);
    scripts.push(redeem);
  }
  scripts = scripts.map(function(script) {
    return script.map(function(chunk) {
      if (Array.isArray(chunk)) {
        if (chunk.length === 0)
          return [0];
        return [bcoin.utils.toHex(chunk)];
      }
      if (typeof chunk === 'number')
        return [chunk];
      return chunk;
    });
  });
  scripts.forEach(function(script) {
    console.log(script);
  });
}

describe('Wallet', function() {
  it('should generate new key and address', function() {
    var w = bcoin.wallet();
    var addr = w.getAddress();
    assert(addr);
    assert(bcoin.wallet.validateAddress(addr));
  });

  it('should validate existing address', function() {
    assert(bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc'));
  });

  it('should fail to validate invalid address', function() {
    assert(!bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc'));
  });

  it('should sign/verify TX', function() {
    var w = bcoin.wallet();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        address: w.getAddress()
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    w.sign(tx);
    assert(tx.verify());
  });

  it('should multisign/verify TX', function() {
    var w = bcoin.wallet();
    var k2 = bcoin.wallet().getPublicKey();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        minSignatures: 1,
        keys: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
        // keys: [ w.getPublicKey(), k2 ]
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    var maxSize = tx.maxSize();
    w.sign(tx);
    assert(tx.render().length <= maxSize);
    assert(tx.verify());
  });

  it('should have TX pool and be serializable', function() {
    var w = bcoin.wallet();
    var f = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w, 50000).out(w, 1000);
    w.sign(t1);
    var t2 = bcoin.tx().input(t1, 0)
                       .out(w, 24000)
                       .out(w, 24000);
    w.sign(t2);
    var t3 = bcoin.tx().input(t1, 1)
                       .input(t2, 0)
                       .out(w, 23000);
    w.sign(t3);
    var t4 = bcoin.tx().input(t2, 1)
                       .input(t3, 0)
                       .out(w, 11000)
                       .out(w, 11000);
    w.sign(t4);
    var f1 = bcoin.tx().input(t4, 1)
                       .out(f, 10000);
    w.sign(f1);
    var fake = bcoin.tx().input(t1, 1)
                         .out(w, 500);

    // Just for debugging
    t1.hint = 't1';
    t2.hint = 't2';
    t3.hint = 't3';
    t4.hint = 't4';
    f1.hint = 'f1';
    fake.hint = 'fake';

    // Fake TX should temporarly change output
    w.addTX(fake);

    w.addTX(t4);
    assert.equal(w.balance().toString(10), '22500');
    w.addTX(t1);
    assert.equal(w.balance().toString(10), '73000');
    w.addTX(t2);
    assert.equal(w.balance().toString(10), '47000');
    w.addTX(t3);
    assert.equal(w.balance().toString(10), '22000');
    w.addTX(f1);
    assert.equal(w.balance().toString(10), '11000');
    assert(w.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));

    var w2 = bcoin.wallet.fromJSON(w.toJSON());
    assert.equal(w2.balance().toString(10), '11000');
    assert(w2.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));
  });

  it('should fill tx with inputs', function(cb) {
    var w1 = bcoin.wallet();
    var w2 = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);

    // Fake TX should temporarly change output
    w1.addTX(t1);

    // Create new transaction
    var t2 = bcoin.tx().out(w2, 5460);
    w1.fill(t2, function(err) {
      assert(!err);
      assert(t2.verify());

      assert.equal(t2.funds('in').toString(10), 16380);
      // If change < dust and is added to outputs:
      // assert.equal(t2.funds('out').toString(10), 6380);
      // If change < dust and is added to fee:
      assert.equal(t2.funds('out').toString(10), 5460);

      // Create new transaction
      var t3 = bcoin.tx().out(w2, 15000);
      w1.fill(t3, function(err) {
        assert(err);
        assert.equal(err.minBalance.toString(10), 25000);

        cb();
      });
    });
  });

  it('should sign multiple inputs using different keys', function(cb) {
    var w1 = bcoin.wallet();
    var w2 = bcoin.wallet();
    var to = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);
    // Fake TX should temporarly change output
    w1.addTX(t1);
    // Coinbase
    var t2 = bcoin.tx().out(w2, 5460).out(w2, 5460).out(w2, 5460).out(w2, 5460);
    // Fake TX should temporarly change output
    w2.addTX(t2);

    // Create our tx with an output
    var tx = bcoin.tx();
    tx.out(to, 5460);

    var cost = tx.funds('out');
    var total = cost.add(new bn(bcoin.tx.fee));

    var unspent1 = w1.unspent();
    var unspent2 = w2.unspent();

    // Add dummy output (for `left`) to calculate maximum TX size
    tx.out(w1, new bn(0));

    // Add our unspent inputs to sign
    tx.input(unspent1[0]);
    tx.input(unspent1[1]);
    tx.input(unspent2[0]);

    var left = tx.funds('in').sub(total);
    if (left.cmpn(bcoin.tx.dust) < 0) {
      tx.outputs[tx.outputs.length - 2].value.iadd(left);
      left = new bn(0);
    }
    if (left.cmpn(0) === 0)
      tx.outputs.pop();
    else
      tx.outputs[tx.outputs.length - 1].value = left;

    // Sign transaction
    assert.equal(w1.sign(tx), 2);
    assert.equal(w2.sign(tx), 1);

    // Verify
    assert.equal(tx.verify(), true);

    // Sign transaction using `inputs` and `off` params.
    tx.inputs.length = 0;
    tx.input(unspent1[1]);
    tx.input(unspent1[2]);
    tx.input(unspent2[1]);
    assert.equal(w1.sign(tx, 'all', tx.inputs.slice(), 0), 2);
    assert.equal(w2.sign(tx, 'all', tx.inputs.slice(2), 2), 1);

    // Verify
    assert.equal(tx.verify(), true);

    cb();
  });

  it('should verify 2-of-3 p2sh tx', function(cb) {
    var hd = bcoin.hd.priv();
    var hd1 = hd.derive(0);
    var hd2 = hd.derive(1);
    var hd3 = hd.derive(2);

    // Generate 3 key pairs
    var key1 = bcoin.ecdsa.genKeyPair();
    var key2 = bcoin.ecdsa.genKeyPair();
    var key3 = bcoin.ecdsa.genKeyPair();

    // var key1 = hd1;
    // var key2 = hd2;
    // var key3 = hd3;

    // Grab the 3 pubkeys
    var pub1 = key1.getPublic(true, 'array');
    var pub2 = key2.getPublic(true, 'array');
    var pub3 = key3.getPublic(true, 'array');

    // Create 3 2-of-3 wallets with our pubkeys as "shared keys"
    var w1 = bcoin.wallet({
      key: key1,
      multisig: {
        type: 'scripthash',
        keys: [pub2, pub3],
        m: 2,
        n: 3
      }
    });
    var w2 = bcoin.wallet({
      key: key2,
      multisig: {
        type: 'scripthash',
        keys: [pub1, pub3],
        m: 2,
        n: 3
      }
    });
    var w3 = bcoin.wallet({
      key: key3,
      multisig: {
        type: 'scripthash',
        keys: [pub1, pub2],
        m: 2,
        n: 3
      }
    });
    var receive = bcoin.wallet();

    // Our p2sh address
    var addr = w1.getAddress();
    assert.equal(w1.getAddress(), addr);
    assert.equal(w2.getAddress(), addr);
    assert.equal(w3.getAddress(), addr);

    // Add a shared unspent transaction to our wallets
    var utx = bcoin.tx();
    utx.output({ address: addr, value: 5460 * 10 });

    w1.addTX(utx);
    w2.addTX(utx);
    w3.addTX(utx);

    // Create a tx requiring 2 signatures
    var send = bcoin.tx();
    send.output({ address: receive.getAddress(), value: 5460 });
    assert(!send.verify());
    var result = w1.fill(send);
    assert(result);

    // printScript(send.inputs[0]);

    assert(!send.verify());
    w2.sign(send);

    assert(send.verify());

    send.inputs[0].script[2] = [];
    assert(!send.verify());
    assert.equal(send.getFee().toNumber(), 10000);

    cb();
  });
});
<|endoftext|>


<commit_before>require.config({
  baseUrl: 'js/lib',
  paths: {
    'test': '../../..',
    'mocha': 'mocha/mocha',
    'chai': 'chai/chai'
  },
  packages: [
    { name: 'ajax', location: '../../../..' },
    { name: 'xhr' },
    { name: 'events' },
    { name: 'url' }
  ],
  shim: {
    'mocha': {
      exports: 'mocha'
    }
  }
});

require(['../suite']);
<commit_msg>Fix tests.<commit_after>require.config({
  baseUrl: 'js/lib',
  paths: {
    'test': '../../..',
    'mocha': 'mocha/mocha',
    'chai': 'chai/chai'
  },
  packages: [
    { name: 'ajax', location: '../../../..', main: 'ajax' },
    { name: 'xhr' },
    { name: 'events' },
    { name: 'url' }
  ],
  shim: {
    'mocha': {
      exports: 'mocha'
    }
  }
});

require(['../suite']);
<|endoftext|>


<commit_before>'use strict';

const views = module.exports = {};

views.documentByType = {
    map: function (doc) {
        emit(doc.$type);
    },
    reduce: '_count'
};

views.entryById = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$id);
    },
    reduce: '_count'
};

views.entryByKind = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$kind);
    },
    reduce: '_count'
};

views.entryByCreationDate = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$creationDate);
    },
    reduce: '_count'
};

views.entryByModificationDate = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$modificationDate);
    },
    reduce: '_count'
};

views.entryByOwner = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        for (var i = 0; i < doc.$owners.length; i++) {
            emit(doc.$owners[i]);
        }
    },
    reduce: '_count'
};

views.entryByLastModification = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$lastModification);
    },
    reduce: '_count'
};

views.ownersById = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$id, doc.$owners);
    }
};

views.entryByOwnerAndId = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit([doc.$owners[0], doc.$id]);
    }
};

views.entryByKindAndId = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit([doc.$kind ? doc.$kind : null, doc.$id]);
    }
};

views.groupByName = {
    map: function (doc) {
        if (doc.$type !== 'group') return;
        emit(doc.name);
    },
    reduce: '_count'
};

views.groupByUser = {
    map: function (doc) {
        if (doc.$type !== 'group') return;
        for (var i = 0; i < doc.users.length; i++) {
            emit(doc.users[i]);
        }
    },
    reduce: '_count'
};

views.groupByUserAndRight = {
    map: function (doc) {
        if (doc.$type !== 'group') return;
        for (var i = 0; i < doc.users.length; i++) {
            for (var j = 0; j < doc.rights.length; j++) {
                emit([doc.users[i], doc.rights[j]], doc.name);
            }
        }
    }
};

views.globalRight = {
    map: function (doc) {
        if (doc._id !== 'rights') return;
        for (var i in doc) {
            if (Array.isArray(doc[i])) {
                for (var j = 0; j < doc[i].length; j++) {
                    emit(i, doc[i][j]);
                }
            }
        }
    }
};

views.logsByEpoch = {
    map: function (doc) {
        if (doc.$type !== 'log') return;
        emit(doc.epoch);
    }
};

views.logsByLevel = {
    map: function (doc) {
        if(doc.$type !== 'log') return;
        emit(doc.level);
    }
};

views.user = {
    map: function (doc) {
        if (doc.$type !== 'user') return;
        if (doc.user) {
            emit(doc.user);
        }
    }
};

views.tokenById = {
    map: function (doc) {
        if (doc.$type !== 'token') return;
        emit(doc.$id);
    }
};

views.tokenByOwner = {
    map: function (doc) {
        if (doc.$type !== 'token') return;
        emit(doc.$owner);
    }
};
<commit_msg>eslint-fix<commit_after>'use strict';

const views = module.exports = {};

views.documentByType = {
    map: function (doc) {
        emit(doc.$type);
    },
    reduce: '_count'
};

views.entryById = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$id);
    },
    reduce: '_count'
};

views.entryByKind = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$kind);
    },
    reduce: '_count'
};

views.entryByCreationDate = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$creationDate);
    },
    reduce: '_count'
};

views.entryByModificationDate = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$modificationDate);
    },
    reduce: '_count'
};

views.entryByOwner = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        for (var i = 0; i < doc.$owners.length; i++) {
            emit(doc.$owners[i]);
        }
    },
    reduce: '_count'
};

views.entryByLastModification = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$lastModification);
    },
    reduce: '_count'
};

views.ownersById = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit(doc.$id, doc.$owners);
    }
};

views.entryByOwnerAndId = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit([doc.$owners[0], doc.$id]);
    }
};

views.entryByKindAndId = {
    map: function (doc) {
        if (doc.$type !== 'entry') return;
        emit([doc.$kind ? doc.$kind : null, doc.$id]);
    }
};

views.groupByName = {
    map: function (doc) {
        if (doc.$type !== 'group') return;
        emit(doc.name);
    },
    reduce: '_count'
};

views.groupByUser = {
    map: function (doc) {
        if (doc.$type !== 'group') return;
        for (var i = 0; i < doc.users.length; i++) {
            emit(doc.users[i]);
        }
    },
    reduce: '_count'
};

views.groupByUserAndRight = {
    map: function (doc) {
        if (doc.$type !== 'group') return;
        for (var i = 0; i < doc.users.length; i++) {
            for (var j = 0; j < doc.rights.length; j++) {
                emit([doc.users[i], doc.rights[j]], doc.name);
            }
        }
    }
};

views.globalRight = {
    map: function (doc) {
        if (doc._id !== 'rights') return;
        for (var i in doc) {
            if (Array.isArray(doc[i])) {
                for (var j = 0; j < doc[i].length; j++) {
                    emit(i, doc[i][j]);
                }
            }
        }
    }
};

views.logsByEpoch = {
    map: function (doc) {
        if (doc.$type !== 'log') return;
        emit(doc.epoch);
    }
};

views.logsByLevel = {
    map: function (doc) {
        if (doc.$type !== 'log') return;
        emit(doc.level);
    }
};

views.user = {
    map: function (doc) {
        if (doc.$type !== 'user') return;
        if (doc.user) {
            emit(doc.user);
        }
    }
};

views.tokenById = {
    map: function (doc) {
        if (doc.$type !== 'token') return;
        emit(doc.$id);
    }
};

views.tokenByOwner = {
    map: function (doc) {
        if (doc.$type !== 'token') return;
        emit(doc.$owner);
    }
};
<|endoftext|>


<commit_before>const rx = require('rx');
const _ = require('underscore-plus');

class PlayerInteraction {
  // Public: Poll players that want to join the game during a specified period
  // of time.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  // maxPlayers - (Optional) The maximum number of players to allow
  //
  // Returns an {Observable} that will `onNext` for each player that joins and
  // `onCompleted` when time expires or the max number of players join.
  static pollPotentialPlayers(messages, channel, scheduler=rx.Scheduler.timeout, timeout=30, maxPlayers=10) {
    let formatMessage = t => `Who wants to play? Respond with 'yes' in this channel in the next ${t} seconds.`;
    let {timeExpired} = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);

    // Look for messages containing the word 'yes' and map them to a unique
    // user ID, constrained to `maxPlayers` number of players.
    let newPlayers = messages.where(e => e.text && e.text.toLowerCase().match(/\byes\b/))
      .map(e => e.user)
      .distinct()
      .take(maxPlayers)
      .publish();

    newPlayers.connect();
    timeExpired.connect();

    // Once our timer has expired, we're done accepting new players.
    return newPlayers.takeUntil(timeExpired);
  }

  // Public: Poll a specific player to take a poker action, within a timeout.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // player - The player being polled
  // previousActions - A map of players to their most recent action
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  //
  // Returns an {Observable} indicating the action the player took. If time
  // expires, a 'timeout' action is returned.
  static getActionForPlayer(messages, channel, player, previousActions,
    scheduler=rx.Scheduler.timeout, timeout=30) {
    let availableActions = PlayerInteraction.getAvailableActions(player, previousActions);
    let formatMessage = t => PlayerInteraction.buildActionMessage(player, availableActions, t);
    let {timeExpired} = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);

    // Look for text that conforms to a player action.
    let playerAction = messages.where(e => e.user === player.id)
      .map(e => PlayerInteraction.actionFromMessage(e.text, availableActions))
      .where(action => action !== null)
      .publish();

    playerAction.connect();
    let disp = timeExpired.connect();

    // If the user times out, they will be auto-folded unless they can check.
    let actionForTimeout = timeExpired.map(() =>
      availableActions.indexOf('check') > -1 ?
        { name: 'check' } :
        { name: 'fold' });

    let botAction = player.isBot ?
      player.getAction(availableActions, previousActions) :
      rx.Observable.never();

    // NB: Take the first result from the player action, the timeout, and a bot
    // action (only applicable to bots).
    return rx.Observable.merge(playerAction, actionForTimeout, botAction)
      .take(1)
      .do(() => disp.dispose());
  }

  // Private: Posts a message to the channel with some timeout, that edits
  // itself each second to provide a countdown.
  //
  // channel - The channel to post in
  // formatMessage - A function that will be invoked once per second with the
  //                 remaining time, and returns the formatted message content
  // scheduler - The scheduler to use for timing events
  // timeout - The duration of the message, in seconds
  //
  // Returns an object with two keys: `timeExpired`, an {Observable} sequence
  // that fires when the message expires, and `message`, the message posted to
  // the channel.
  static postMessageWithTimeout(channel, formatMessage, scheduler, timeout) {
    let timeoutMessage = channel.send(formatMessage(timeout));

    let timeExpired = rx.Observable.timer(0, 1000, scheduler)
      .take(timeout + 1)
      .do((x) => timeoutMessage.updateMessage(formatMessage(`${timeout - x}`)))
      .publishLast();

    return {timeExpired: timeExpired, message: timeoutMessage};
  }

  // Private: Builds up a formatted countdown message containing the available
  // actions.
  //
  // player - The player who is acting
  // availableActions - An array of the actions available to this player
  // timeRemaining - Number of seconds remaining for the player to act
  //
  // Returns the formatted string
  static buildActionMessage(player, availableActions, timeRemaining) {
    let message = `${player.name}, it's your turn. Respond with\n`;
    for (let action of availableActions) {
      message += `*(${action.charAt(0).toUpperCase()})${action.slice(1)}*\t`;
    }
    message += `\nin the next ${timeRemaining} seconds.`;
    return message;
  }

  // Private: Given an array of actions taken previously in the hand, returns
  // an array of available actions.
  //
  // player - The player who is acting
  // previousActions - A map of players to their most recent action
  //
  // Returns an array of strings
  static getAvailableActions(player, previousActions) {
    let actions = _.values(previousActions);
    let betActions = _.filter(actions, a => a.name === 'bet' || a.name === 'raise');
    let hasBet = betActions.length > 0;

    let availableActions = [];

    if (player.hasOption) {
      availableActions.push('check');
      availableActions.push('raise');
    } else if (hasBet) {
      availableActions.push('call');
      availableActions.push('raise');
    } else {
      availableActions.push('check');
      availableActions.push('bet');
    }

    // Prevent players from raising when they don't have enough chips.
    let raiseIndex = availableActions.indexOf('raise');
    if (raiseIndex > -1) {
      let previousWager = player.lastAction ? player.lastAction.amount : 0;
      let availableChips = player.chips + previousWager;

      if (_.max(betActions, a => a.amount).amount >= availableChips) {
        availableActions.splice(raiseIndex, 1);
      }
    }

    availableActions.push('fold');
    return availableActions;
  }

  // Private: Parse player input into a valid action.
  //
  // text - The text that the player entered
  // availableActions - An array of the actions available to this player
  //
  // Returns an object representing the action, with keys for the name and
  // bet amount, or null if the input was invalid.
  static actionFromMessage(text, availableActions) {
    if (!text) return null;

    let input = text.trim().toLowerCase().split(/\s+/);
    if (!input[0]) return null;

    let name = '';
    let amount = 0;

    switch (input[0]) {
    case 'c':
      name = availableActions[0];
      break;
    case 'call':
      name = 'call';
      break;
    case 'check':
      name = 'check';
      break;
    case 'f':
    case 'fold':
      name = 'fold';
      break;
    case 'b':
    case 'bet':
      name = 'bet';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    case 'r':
    case 'raise':
      name = 'raise';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    default:
      return null;
    }

    // NB: Unavailable actions are always invalid.
    return availableActions.indexOf(name) > -1 ?
      { name: name, amount: amount } :
      null;
  }
}

module.exports = PlayerInteraction;
<commit_msg>Make timeout of 0 a special case that never expires.<commit_after>const rx = require('rx');
const _ = require('underscore-plus');

class PlayerInteraction {
  // Public: Poll players that want to join the game during a specified period
  // of time.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  // maxPlayers - (Optional) The maximum number of players to allow
  //
  // Returns an {Observable} that will `onNext` for each player that joins and
  // `onCompleted` when time expires or the max number of players join.
  static pollPotentialPlayers(messages, channel, scheduler=rx.Scheduler.timeout, timeout=30, maxPlayers=10) {
    let formatMessage = t => `Who wants to play? Respond with 'yes' in this channel in the next ${t} seconds.`;
    let timeExpired = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);

    // Look for messages containing the word 'yes' and map them to a unique
    // user ID, constrained to `maxPlayers` number of players.
    let newPlayers = messages.where(e => e.text && e.text.toLowerCase().match(/\byes\b/))
      .map(e => e.user)
      .distinct()
      .take(maxPlayers)
      .publish();

    newPlayers.connect();
    timeExpired.connect();

    // Once our timer has expired, we're done accepting new players.
    return newPlayers.takeUntil(timeExpired);
  }

  // Public: Poll a specific player to take a poker action, within a timeout.
  //
  // messages - An {Observable} representing new messages sent to the channel
  // channel - The {Channel} object, used for posting messages
  // player - The player being polled
  // previousActions - A map of players to their most recent action
  // scheduler - (Optional) The scheduler to use for timing events
  // timeout - (Optional) The amount of time to conduct polling, in seconds
  //
  // Returns an {Observable} indicating the action the player took. If time
  // expires, a 'timeout' action is returned.
  static getActionForPlayer(messages, channel, player, previousActions,
    scheduler=rx.Scheduler.timeout, timeout=30) {
    let availableActions = PlayerInteraction.getAvailableActions(player, previousActions);
    let formatMessage = t => PlayerInteraction.buildActionMessage(player, availableActions, t);

    let timeExpired = null;
    let expiredDisp = null;
    if (timeout > 0) {
      timeExpired = PlayerInteraction.postMessageWithTimeout(channel, formatMessage, scheduler, timeout);
      expiredDisp = timeExpired.connect();
    } else {
      channel.send(formatMessage(0));
      timeExpired = rx.Observable.never();
      expiredDisp = rx.Disposable.empty;
    }

    // Look for text that conforms to a player action.
    let playerAction = messages.where(e => e.user === player.id)
      .map(e => PlayerInteraction.actionFromMessage(e.text, availableActions))
      .where(action => action !== null)
      .publish();

    playerAction.connect();

    // If the user times out, they will be auto-folded unless they can check.
    let actionForTimeout = timeExpired.map(() =>
      availableActions.indexOf('check') > -1 ?
        { name: 'check' } :
        { name: 'fold' });

    let botAction = player.isBot ?
      player.getAction(availableActions, previousActions) :
      rx.Observable.never();

    // NB: Take the first result from the player action, the timeout, and a bot
    // action (only applicable to bots).
    return rx.Observable.merge(playerAction, actionForTimeout, botAction)
      .take(1)
      .do(() => expiredDisp.dispose());
  }

  // Private: Posts a message to the channel with some timeout, that edits
  // itself each second to provide a countdown.
  //
  // channel - The channel to post in
  // formatMessage - A function that will be invoked once per second with the
  //                 remaining time, and returns the formatted message content
  // scheduler - The scheduler to use for timing events
  // timeout - The duration of the message, in seconds
  //
  // Returns an {Observable} sequence that signals expiration of the message
  static postMessageWithTimeout(channel, formatMessage, scheduler, timeout) {
    let timeoutMessage = channel.send(formatMessage(timeout));

    let timeExpired = rx.Observable.timer(0, 1000, scheduler)
      .take(timeout + 1)
      .do((x) => timeoutMessage.updateMessage(formatMessage(`${timeout - x}`)))
      .publishLast();

    return timeExpired;
  }

  // Private: Builds up a formatted countdown message containing the available
  // actions.
  //
  // player - The player who is acting
  // availableActions - An array of the actions available to this player
  // timeRemaining - Number of seconds remaining for the player to act
  //
  // Returns the formatted string
  static buildActionMessage(player, availableActions, timeRemaining) {
    let message = `${player.name}, it's your turn. Respond with:\n`;
    for (let action of availableActions) {
      message += `*(${action.charAt(0).toUpperCase()})${action.slice(1)}*\t`;
    }

    if (timeRemaining > 0) {
      message += `\nin the next ${timeRemaining} seconds.`;
    }

    return message;
  }

  // Private: Given an array of actions taken previously in the hand, returns
  // an array of available actions.
  //
  // player - The player who is acting
  // previousActions - A map of players to their most recent action
  //
  // Returns an array of strings
  static getAvailableActions(player, previousActions) {
    let actions = _.values(previousActions);
    let betActions = _.filter(actions, a => a.name === 'bet' || a.name === 'raise');
    let hasBet = betActions.length > 0;

    let availableActions = [];

    if (player.hasOption) {
      availableActions.push('check');
      availableActions.push('raise');
    } else if (hasBet) {
      availableActions.push('call');
      availableActions.push('raise');
    } else {
      availableActions.push('check');
      availableActions.push('bet');
    }

    // Prevent players from raising when they don't have enough chips.
    let raiseIndex = availableActions.indexOf('raise');
    if (raiseIndex > -1) {
      let previousWager = player.lastAction ? player.lastAction.amount : 0;
      let availableChips = player.chips + previousWager;

      if (_.max(betActions, a => a.amount).amount >= availableChips) {
        availableActions.splice(raiseIndex, 1);
      }
    }

    availableActions.push('fold');
    return availableActions;
  }

  // Private: Parse player input into a valid action.
  //
  // text - The text that the player entered
  // availableActions - An array of the actions available to this player
  //
  // Returns an object representing the action, with keys for the name and
  // bet amount, or null if the input was invalid.
  static actionFromMessage(text, availableActions) {
    if (!text) return null;

    let input = text.trim().toLowerCase().split(/\s+/);
    if (!input[0]) return null;

    let name = '';
    let amount = 0;

    switch (input[0]) {
    case 'c':
      name = availableActions[0];
      break;
    case 'call':
      name = 'call';
      break;
    case 'check':
      name = 'check';
      break;
    case 'f':
    case 'fold':
      name = 'fold';
      break;
    case 'b':
    case 'bet':
      name = 'bet';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    case 'r':
    case 'raise':
      name = 'raise';
      amount = input[1] ? parseInt(input[1]) : NaN;
      break;
    default:
      return null;
    }

    // NB: Unavailable actions are always invalid.
    return availableActions.indexOf(name) > -1 ?
      { name: name, amount: amount } :
      null;
  }
}

module.exports = PlayerInteraction;
<|endoftext|>


<commit_before>import React from 'react';
import SyntaxHighlighter from 'react-syntax-highlighter';
// hacky for now until we run tests in browser
if (process.env.NODE_ENV !== 'test') {
  require('highlight.js/styles/docco.css');
}

const onXClick = (e, close) => {
  e.preventDefault();
  close();
};

const DisplayTest = ({ getTest, shouldShowTest, onKeyPress, hideTest }) => {
  if (!shouldShowTest()) {
    return ;
  }
  const style = {
    position: 'absolute',
    width: 500,
    height: 600,
    right: 25,
    bottom: 80,
    backgroundColor: 'gainsboro',
    color: 'black',
    boxShadow: '2px 2px 5px #888888',
    overflowY: 'auto'
  };
  const xStyle = {
    float: 'right',
    fontSize: 22,
    fontWeight: 700,
    marginRight: 5,
    cursor: 'pointer'
  };
  return (

       onXClick(e, hideTest)}>X

            <SyntaxHighlighter language="javascript">
              {getTest()}
            </SyntaxHighlighter>

  );
}

export default DisplayTest;<commit_msg>add zINdex to test display<commit_after>import React from 'react';
import SyntaxHighlighter from 'react-syntax-highlighter';
// hacky for now until we run tests in browser
if (process.env.NODE_ENV !== 'test') {
  require('highlight.js/styles/docco.css');
}

const onXClick = (e, close) => {
  e.preventDefault();
  close();
};

const DisplayTest = ({ getTest, shouldShowTest, onKeyPress, hideTest }) => {
  if (!shouldShowTest()) {
    return ;
  }
  const style = {
    position: 'absolute',
    width: 500,
    height: 600,
    right: 25,
    bottom: 80,
    backgroundColor: 'gainsboro',
    color: 'black',
    boxShadow: '2px 2px 5px #888888',
    overflowY: 'auto',
    zIndex: 99
  };
  const xStyle = {
    float: 'right',
    fontSize: 22,
    fontWeight: 700,
    marginRight: 5,
    cursor: 'pointer'
  };
  return (

       onXClick(e, hideTest)}>X

            <SyntaxHighlighter language="javascript">
              {getTest()}
            </SyntaxHighlighter>

  );
}

export default DisplayTest;<|endoftext|>


<commit_before>var fs = require('fs'),
  http = require('http'),
  points = {};

function addFile(filename) {
  try {
    points[filename] = JSON.parse(fs.readFileSync('points/'+filename));
  } catch(e) {
    console.log(e, filename);
  }
}

function savePoint(filename) {
  fs.writeFileSync('points/'+filename, JSON.stringify(points[filename]));
}

function displayPoint(res, filename, reason, data) {
  res.write('
'+filename+' '+reason+JSON.stringify(data)+'
');
  console.log(filename);
}

function displayPoints(res) {
	var before;
  files = fs.readdirSync('points/');
	for(var i=0; i<files.length; i++) {
		if(files[i]!='README.md') {
			addFile(files[i]);
			if(!points[files[i]].id) {
				displayPoint(res, files[i], 'no id', points[files[i]]);
			}
			if(!points[files[i]].title) {
				displayPoint(res, files[i], 'no title', points[files[i]]);
			}
			if(!points[files[i]].irrelevant && !points[files[i]].service) {
				displayPoint(res, files[i], 'no service', points[files[i]]);
			}
		}
	}
	//console.log(points);
}

//...
var server = http.createServer(function(req, res) {
  res.writeHead(200, {});
  res.write('
');
  displayPoints(res);
  res.end('
');
});
server.listen(21337);
console.log('see http://localhost:21337/');
<commit_msg>process post<commit_after>var fs = require('fs'),
  http = require('http'),
  points = {};

function addFile(filename) {
  try {
    points[filename] = JSON.parse(fs.readFileSync('points/'+filename));
  } catch(e) {
    console.log(e, filename);
  }
}

function savePoint(filename) {
  fs.writeFileSync('points/'+filename, JSON.stringify(points[filename]));
}

function displayPoint(res, filename, reason, data) {
  res.write('
'+filename+' '+reason+JSON.stringify(data)+'
');
  console.log(filename);
}

function displayField(res, point, field) {
  if(typeof(point[field])=='string') {
    point[field]=point[field].split('"').join('"');
  }
  res.write(field+': <input value="'+point[field]+'" name="'+field+'"/>
');
}
function displayForm(res, filename) {
  var point = points[filename];
  res.write('<form method="POST">');
  displayField(res, point, 'id');
  displayField(res, point, 'title');
  displayField(res, point, 'service');
  displayField(res, point, 'irrelevant');
  displayField(res, {filename: filename}, 'filename');
  res.write('<input type="submit"></form>');
  res.write('JSON: <textarea>'+fs.readFileSync('points/'+filename)+'</textarea>');
}

function displayPoints(res) {
  for(var i in points) {
    if(!points[i].id) {
      displayPoint(res, i, 'no id', points[i]);
    }
    if(!points[i].title) {
      displayPoint(res, i, 'no title', points[i]);
    }
    if(!points[i].irrelevant && !points[i].service) {
      displayPoint(res, i, 'no service', points[i]);
    }
  }
	//console.log(points);
}
function processPost(req) {
  var str='';
  req.on('data', function(chunk) {
    str += chunk;
  });
  req.on('end', function() {
    var pairs = str.split('&');
    var incoming = {};
    for(var i=0; i<pairs.length; i++) {
      var parts = pairs[i].split('=');
      incoming[parts[0]]=parts[1];
    }
    for(var i in incoming) {
      if(i!='filename') {
        points[incoming.filename][i]=incoming[i];
      }
    }
    savePoint(incoming.filename);
  });
}
//...
files = fs.readdirSync('points/');
for(var i=0; i<files.length; i++) {
	if(files[i]!='README.md') {
		addFile(files[i]);
  }
}
var server = http.createServer(function(req, res) {
  res.writeHead(200, {});
  res.write('
');
  var point = req.url.substring(2);
  if(point.length) {
    processPost(req);
    displayForm(res, point);
  } else {
    displayPoints(res);
  }
  res.end('
');
});
server.listen(21337);
console.log('see http://localhost:21337/');
<|endoftext|>