<commit_before>/*!
 * base-runner <https://github.com/jonschlinkert/base-runner>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var utils = require('./utils');

/**
 * Create a customized `Runner` constructor with the given `config`.
 *
 * ```js
 * var runner = require('base-runner');
 * var Generate = require('generate');
 *
 * // register `runner` as a mixin
 * Generate.mixin(runner('generate', 'generator'));
 *
 * // get the `base` instance
 * var base = Generate.getConfig('generator.js')
 *   .resolve('generator.js', {
 *     cwd: __dirname
 *   });
 * ```
 *
 * @param {String} `moduleName` The name of the "parent" module, ex: `generate`
 * @param {String} `appName` The name of the "child" apps, ex: `generator`
 * @return {Function}
 */

function runner(moduleName, appName) {
  if (typeof moduleName !== 'string') {
    throw new TypeError('expected "moduleName" to be a string');
  }
  if (typeof appName !== 'string') {
    throw new TypeError('expected "appName" to be a string');
  }

  var toSingular = utils.inflection.singularize;
  var toPlural = utils.inflection.pluralize;

  appName = toSingular(appName);

  // create property and method names
  var parent = utils.pascal(appName);
  var plural = toPlural(appName);
  var isName = 'is' + utils.pascal(moduleName);
  var method = function(prop) {
    return prop + parent;
  };

  return function plugin(proto) {
    var Ctor = proto.constructor;
    if (proto instanceof Ctor) {
      throw new Error('base-runner must be used as a mixin, not as an instance plugin.');
    }

    /**
     * Static method for getting the very first instance to be used
     * as the `base` instance. The first instance will either be defined
     * by the user, like in local `node_modules`, or a globally installed
     * module that serves as a default/fallback.
     *
     * ```js
     * var base = Base.getConfig('generator.js');
     * ```
     * @name .getConfig
     * @param {String} `filename` Then name of the config file to lookup.
     * @return {Object} Returns the "base" instance.
     * @api public
     */

    Ctor.getConfig = function(filename, fallback) {
      var base = getConfig(filename, moduleName, {
        Ctor: Ctor,
        fallback: fallback,
        isModule: function(app) {
          return app[isName];
        }
      });

      base.initRunner(base);
      return base;
    };

    /**
     * Private method for initializing runner defaults and listening for config
     * objects to be emitted.
     *
     * @return {Object}
     */

    proto.initRunner = function() {
      var name = this.name = this.options.name || 'base';
      this.env = this.env || {};

      this[plural] = this[plural] || {};
      this[isName] = true;

      this
        .use(utils.cli())
        .use(utils.argv({prop: plural}))
        .use(utils.resolver(moduleName))
        .use(utils.runtimes({
          displayName: function(key) {
            return name + ':' + key;
          }
        }));

      initListeners(this);
      proxyArgv(this);
      return this;
    };

    /**
     * Ensure argv is parsed for the `base-cli` and
     * `base-argv` plugins at the same time.
     */

    function proxyArgv(app) {
      var processFn = app.cli.process;
      var argvFn = app.processArgv;

      app.cli.process = function(argv) {
        var args = argvFn.call(app, argv);
        processFn.call(app.cli, args);
        app.set('env.argv', args);
        return args;
      };
    }

    /**
     * Add a `config` listener to `app`, and register
     * a `fn` each time a config is emitted
     */

    function initListeners(app) {
      app.on('config', function(name, env) {
        env.module.path = env.module.path || app.path;
        var config = env.config;
        var alias = config.alias;
        var fn = config.fn;

        if (alias === moduleName) {
          alias = 'base';
        }
        app.register(alias, fn, app, env);
      });
    }

    /**
     * Get task `name` from the `runner.tasks` object.
     *
     * ```js
     * runner.getTask('abc');
     *
     * // get a task from app `foo`
     * runner.getTask('foo:abc');
     *
     * // get a task from sub-app `foo.bar`
     * runner.getTask('foo.bar:abc');
     * ```
     * @name .getTask
     * @param {String} `name`
     * @return {Object}
     * @api public
     */

    proto.getTask = function(name) {
      var segments = name.split(':');
      if (segments.length === 1) {
        return this.tasks[name];
      }
      var app = this[method('get')](segments[0]);
      return app.getTask(segments[1]);
    };

    /**
     * Register `app` with the given `name`.
     *
     * ```js
     * runner.register('foo', function(app, base, env) {
     *   app.task('foo-a', function() {});
     *   app.task('foo-b', function() {});
     *   app.task('foo-c', function() {});
     *
     *   // sub-app
     *   app.register('bar', function(sub) {
     *     sub.task('bar-a', function() {});
     *     sub.task('bar-b', function() {});
     *     sub.task('bar-c', function() {});
     *   });
     * });
     *  ```
     * @name .register
     * @param {String} `name` The app's name.
     * @param {Object|Function} `app` Generator can be an instance of runner or a function. Generator functions are invoked with a new instance of `Runner`, a `base` instance that is used for storing all apps, and `env`, an object with user environment details, such as `cwd`.
     * @return {String}
     */

    proto.register = function(name, app, base, env) {
      if (typeof this[plural] === 'undefined') {
        var ctor = this.constructor.name;
        throw new Error('object "' + plural + '" is not defined on ' + ctor);
      }
      if (typeof app === 'undefined') {
        throw new Error('expected ' + appName + ' to be a function or object');
      }

      app = this.invoke(name, app, base, env);
      this.emit('register', name, app);
      this[plural][name] = app;
      return this;
    };

    /**
     * Alias for `register`. Adds an `app` with the given `name`
     * to the `runner.apps` object.
     *
     * @name .addApp
     * @param {String} `name` The name of the config object to register
     * @param {Object|Function} `config` The config object or function
     * @api public
     */

    proto[method('add')] = function(name, config) {
      return this.register.apply(this, arguments);
    };

    /**
     * Return true if app `name` is registered. Dot-notation
     * may be used to check for [sub-apps](#sub-apps).
     *
     * ```js
     * base.hasApp('foo.bar.baz');
     * ```
     * @name .hasApp
     * @param {String} `name`
     * @return {Boolean}
     * @api public
     */

    proto[method('has')] = function(name) {
      if (this[plural].hasOwnProperty(name)) {
        return true;
      }
      name = name.split('.').join('.' + plural + '.');
      return this.has([plural, name]);
    };

    /**
     * Return app `name` is registered. Dot-notation
     * may be used to get [sub-apps](#sub-apps).
     *
     * ```js
     * base.getApp('foo');
     * // or
     * base.getApp('foo.bar.baz');
     * ```
     * @name .getApp
     * @param {String} `name`
     * @return {Boolean}
     * @api public
     */

    proto[method('get')] = function(name) {
      if (name === 'base') return this;
      if (this[plural].hasOwnProperty(name)) {
        return this[plural][name];
      }
      name = name.split('.').join('.' + plural + '.');
      return this.get([plural, name]);
    };

    /**
     * Extend an app.
     *
     * ```js
     * var foo = base.getApp('foo');
     * foo.extendApp(app);
     * ```
     * @name .extendApp
     * @param {Object} `app`
     * @return {Object} Returns the instance for chaining.
     * @api public
     */

    proto[method('extend')] = function(app) {
      if (typeof this.fn !== 'function') {
        throw new Error('base-runner expected `fn` to be a function');
      }
      this.fn.call(app, app, this.base, app.env || this.env);
      return this;
    };

    /**
     * Run one or more apps and the specified tasks for each.
     *
     * ```js
     * // run the default tasks for apps `foo` and `bar`
     * foo.runApps(['foo', 'bar'], function(err) {
     *   if (err) return console.log(err);
     *   console.log('done!');
     * });
     *
     * // run the specified tasks for apps `foo` and `bar`
     * var apps = {
     *   foo: ['a', 'b', 'c'],
     *   bar: ['x', 'y', 'z']
     * };
     *
     * foo.runApps(apps, function(err) {
     *   if (err) return console.log(err);
     *   console.log('done!');
     * });
     * ```
     * @param {Object} `apps`
     * @param {Function} `done`
     * @api public
     */

    proto[toPlural(method('run'))] = function(apps, done) {
      if (!Array.isArray(apps) || !utils.isObject(apps[0])) {
        apps = this.argv(apps)[plural];
      }
      utils.async.each(apps, function(app, cb) {
        utils.async.eachOf(app, function(tasks, name, next) {
          var instance = this[plural][name] || this;
          if (!instance) {
            return cb(new Error('cannot find ' + appName + ' "' + name + '"'));
          }
          return instance.build(tasks, cb);
        }.bind(this), cb);
      }.bind(this), done);
    };

    /**
     * Invoke app `fn` with the given `base` instance.
     *
     * ```js
     * runner.invoke(app.fn, app);
     * ```
     * @name .invoke
     * @param {Function} `fn` The app function.
     * @param {Object} `app` The "base" instance to use with the app.
     * @return {Object}
     * @api public
     */

    proto.invoke = function(name, app, base, env) {
      if (typeof app === 'function') {
        var fn = app;
        app = new this.constructor();
        app.name = name;
        app.env = env || this.env;
        app.fn = fn;
        fn.call(app, app, base || app.base, app.env);
      } else {
        // `parent` is used to get the base instance
        app.name = name;
        app.env = env || app.env || this.env;
      }

      app.define('parent', this);
      return app;
    };

    /**
     * Get the `base` instance
     */

    Object.defineProperty(proto, 'base', {
      configurable: true,
      get: function() {
        return this.parent ? this.parent.base : this;
      }
    });

  };
}

/**
 * Expose `runner`
 */

module.exports = runner;

/**
 * If necessary, this static method will resolve the _first instance_
 * to be used as the `base` instance for caching any additional resolved configs.
 *
 * ```js
 * var Generate = require('generate');
 * var resolver = require('base-resolver');
 *
 * var generate = resolver.first('generator.js', 'generate', {
 *   Ctor: Generate,
 *   isModule: function(app) {
 *     return app.isGenerate;
 *   }
 * });
 * ```
 * @param {String} `configfile` The name of the config file, ex: `assemblefile.js`
 * @param {String} `moduleName` The name of the module to lookup, ex: `assemble`
 * @param {Object} `options`
 *   @option {Function} `options.isModule` Optionally pass a function that will be used to verify that the correct instance was created.
 * @return {Object}
 * @api public
 */

function getConfig(configfile, moduleName, options) {
  var opts = utils.extend({ cwd: process.cwd() }, options);
  var fp = path.resolve(opts.cwd, configfile);
  var Ctor = opts.Ctor;

  var Resolver = utils.resolver.Resolver;
  var fallback = opts.fallback;

  if (!utils.isAbsolute(fallback)) {
    fallback = utils.resolveModule(opts.fallback);
  }

  if (typeof Ctor !== 'function') {
    throw new TypeError('expected options.Ctor to be a function');
  }

  var validate = function() {
    return false;
  };

  if (typeof opts.isModule === 'function') {
    validate = opts.isModule;
  }

  // if a "configfile.js" is in the user's cwd, we'll try to
  // require it in and use it to get (or create) the instance
  if (fs.existsSync(fp)) {
    var env = new Resolver.Config(fp, opts);
    var mod = new Resolver.Mod(moduleName, env);

    env.module = mod;
    Ctor = mod.fn;

    // `fn` is whatever the "configfile" returns
    var fn = env.fn;

    // if the "configfile" returns a function, we need to
    // call the function, and pass an instance of our
    // application to it
    if (typeof fn === 'function') {
      var app = new Ctor();
      app.fn = fn;
      app.env = env;

      fn.call(app, app, app.base, env);

      // set the `app` function on the instance, so it
      // can be used to utils.extend other generators if needed
      return app;
    } else if (validate(fn)) {
      // if the "configfile" returns an instance of our application
      // we'll use that as our `base`
      return fn;
    }
  }

  // if we haven't resolved a user-specified config file by now,
  // try the fallback dir, if passed on the options
  if (fallback && fallback !== opts.cwd) {
    opts.cwd = fallback;
    var base = getConfig(configfile, moduleName, opts);
    return base;
  }

  // create a new, bare instance as a last resort
  return new Ctor();
};

/**
 * Expose `getConfig`
 */

module.exports.getConfig = getConfig;
<commit_msg>use `createEnv` in `getConfig`<commit_after>/*!
 * base-runner <https://github.com/jonschlinkert/base-runner>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var utils = require('./utils');

/**
 * Create a customized `Runner` constructor with the given `config`.
 *
 * ```js
 * var runner = require('base-runner');
 * var Generate = require('generate');
 *
 * // register `runner` as a mixin
 * Generate.mixin(runner('generate', 'generator'));
 *
 * // get the `base` instance
 * var base = Generate.getConfig('generator.js')
 *   .resolve('generator.js', {
 *     cwd: __dirname
 *   });
 * ```
 *
 * @param {String} `moduleName` The name of the "parent" module, ex: `generate`
 * @param {String} `appName` The name of the "child" apps, ex: `generator`
 * @return {Function}
 */

function runner(moduleName, appName) {
  if (typeof moduleName !== 'string') {
    throw new TypeError('expected "moduleName" to be a string');
  }
  if (typeof appName !== 'string') {
    throw new TypeError('expected "appName" to be a string');
  }

  var toSingular = utils.inflection.singularize;
  var toPlural = utils.inflection.pluralize;

  appName = toSingular(appName);

  // create property and method names
  var parent = utils.pascal(appName);
  var plural = toPlural(appName);
  var isName = 'is' + utils.pascal(moduleName);
  var method = function(prop) {
    return prop + parent;
  };

  return function plugin(proto) {
    var Ctor = proto.constructor;
    if (proto instanceof Ctor) {
      throw new Error('base-runner must be used as a mixin, not as an instance plugin.');
    }

    /**
     * Static method for getting the very first instance to be used
     * as the `base` instance. The first instance will either be defined
     * by the user, like in local `node_modules`, or a globally installed
     * module that serves as a default/fallback.
     *
     * ```js
     * var base = Base.getConfig('generator.js');
     * ```
     * @name .getConfig
     * @param {String} `filename` Then name of the config file to lookup.
     * @return {Object} Returns the "base" instance.
     * @api public
     */

    Ctor.getConfig = function(filename, fallback) {
      var base = getConfig(filename, moduleName, {
        Ctor: Ctor,
        fallback: fallback,
        isModule: function(app) {
          return app[isName];
        }
      });

      base.initRunner(base);
      return base;
    };

    /**
     * Private method for initializing runner defaults and listening for config
     * objects to be emitted.
     *
     * @return {Object}
     */

    proto.initRunner = function() {
      var name = this.name = this.options.name || 'base';
      this.env = this.env || {};

      this[plural] = this[plural] || {};
      this[isName] = true;

      this
        .use(utils.cli())
        .use(utils.argv({prop: plural}))
        .use(utils.resolver(moduleName))
        .use(utils.runtimes({
          displayName: function(key) {
            return name + ':' + key;
          }
        }));

      initListeners(this);
      proxyArgv(this);
      return this;
    };

    /**
     * Ensure argv is parsed for the `base-cli` and
     * `base-argv` plugins at the same time.
     */

    function proxyArgv(app) {
      var processFn = app.cli.process;
      var argvFn = app.processArgv;

      app.cli.process = function(argv) {
        var args = argvFn.call(app, argv);
        processFn.call(app.cli, args);
        app.set('env.argv', args);
        return args;
      };
    }

    /**
     * Add a `config` listener to `app`, and register
     * a `fn` each time a config is emitted
     */

    function initListeners(app) {
      app.on('config', function(name, env) {
        env.module.path = env.module.path || app.path;
        var config = env.config;
        var alias = config.alias;
        var fn = config.fn;

        if (alias === moduleName) {
          alias = 'base';
        }
        app.register(alias, fn, app, env);
      });
    }

    /**
     * Get task `name` from the `runner.tasks` object.
     *
     * ```js
     * runner.getTask('abc');
     *
     * // get a task from app `foo`
     * runner.getTask('foo:abc');
     *
     * // get a task from sub-app `foo.bar`
     * runner.getTask('foo.bar:abc');
     * ```
     * @name .getTask
     * @param {String} `name`
     * @return {Object}
     * @api public
     */

    proto.getTask = function(name) {
      var segments = name.split(':');
      if (segments.length === 1) {
        return this.tasks[name];
      }
      var app = this[method('get')](segments[0]);
      return app.getTask(segments[1]);
    };

    /**
     * Register `app` with the given `name`.
     *
     * ```js
     * runner.register('foo', function(app, base, env) {
     *   app.task('foo-a', function() {});
     *   app.task('foo-b', function() {});
     *   app.task('foo-c', function() {});
     *
     *   // sub-app
     *   app.register('bar', function(sub) {
     *     sub.task('bar-a', function() {});
     *     sub.task('bar-b', function() {});
     *     sub.task('bar-c', function() {});
     *   });
     * });
     *  ```
     * @name .register
     * @param {String} `name` The app's name.
     * @param {Object|Function} `app` Generator can be an instance of runner or a function. Generator functions are invoked with a new instance of `Runner`, a `base` instance that is used for storing all apps, and `env`, an object with user environment details, such as `cwd`.
     * @return {String}
     */

    proto.register = function(name, app, base, env) {
      if (typeof this[plural] === 'undefined') {
        var ctor = this.constructor.name;
        throw new Error('object "' + plural + '" is not defined on ' + ctor);
      }
      if (typeof app === 'undefined') {
        throw new Error('expected ' + appName + ' to be a function or object');
      }

      app = this.invoke(name, app, base, env);
      this.emit('register', name, app);
      this[plural][name] = app;
      return this;
    };

    /**
     * Alias for `register`. Adds an `app` with the given `name`
     * to the `runner.apps` object.
     *
     * @name .addApp
     * @param {String} `name` The name of the config object to register
     * @param {Object|Function} `config` The config object or function
     * @api public
     */

    proto[method('add')] = function(name, config) {
      return this.register.apply(this, arguments);
    };

    /**
     * Return true if app `name` is registered. Dot-notation
     * may be used to check for [sub-apps](#sub-apps).
     *
     * ```js
     * base.hasApp('foo.bar.baz');
     * ```
     * @name .hasApp
     * @param {String} `name`
     * @return {Boolean}
     * @api public
     */

    proto[method('has')] = function(name) {
      if (this[plural].hasOwnProperty(name)) {
        return true;
      }
      name = name.split('.').join('.' + plural + '.');
      return this.has([plural, name]);
    };

    /**
     * Return app `name` is registered. Dot-notation
     * may be used to get [sub-apps](#sub-apps).
     *
     * ```js
     * base.getApp('foo');
     * // or
     * base.getApp('foo.bar.baz');
     * ```
     * @name .getApp
     * @param {String} `name`
     * @return {Boolean}
     * @api public
     */

    proto[method('get')] = function(name) {
      if (name === 'base') return this;
      if (this[plural].hasOwnProperty(name)) {
        return this[plural][name];
      }
      name = name.split('.').join('.' + plural + '.');
      return this.get([plural, name]);
    };

    /**
     * Extend an app.
     *
     * ```js
     * var foo = base.getApp('foo');
     * foo.extendApp(app);
     * ```
     * @name .extendApp
     * @param {Object} `app`
     * @return {Object} Returns the instance for chaining.
     * @api public
     */

    proto[method('extend')] = function(app) {
      if (typeof this.fn !== 'function') {
        throw new Error('base-runner expected `fn` to be a function');
      }
      this.fn.call(app, app, this.base, app.env || this.env);
      return this;
    };

    /**
     * Run one or more apps and the specified tasks for each.
     *
     * ```js
     * // run the default tasks for apps `foo` and `bar`
     * foo.runApps(['foo', 'bar'], function(err) {
     *   if (err) return console.log(err);
     *   console.log('done!');
     * });
     *
     * // run the specified tasks for apps `foo` and `bar`
     * var apps = {
     *   foo: ['a', 'b', 'c'],
     *   bar: ['x', 'y', 'z']
     * };
     *
     * foo.runApps(apps, function(err) {
     *   if (err) return console.log(err);
     *   console.log('done!');
     * });
     * ```
     * @param {Object} `apps`
     * @param {Function} `done`
     * @api public
     */

    proto[toPlural(method('run'))] = function(apps, done) {
      if (!Array.isArray(apps) || !utils.isObject(apps[0])) {
        apps = this.argv(apps)[plural];
      }
      utils.async.each(apps, function(app, cb) {
        utils.async.eachOf(app, function(tasks, name, next) {
          var instance = this[plural][name] || this;
          if (!instance) {
            return cb(new Error('cannot find ' + appName + ' "' + name + '"'));
          }
          return instance.build(tasks, cb);
        }.bind(this), cb);
      }.bind(this), done);
    };

    /**
     * Invoke app `fn` with the given `base` instance.
     *
     * ```js
     * runner.invoke(app.fn, app);
     * ```
     * @name .invoke
     * @param {Function} `fn` The app function.
     * @param {Object} `app` The "base" instance to use with the app.
     * @return {Object}
     * @api public
     */

    proto.invoke = function(name, app, base, env) {
      if (typeof app === 'function') {
        var fn = app;
        app = new this.constructor();
        app.name = name;
        app.env = env || this.env;
        app.fn = fn;
        fn.call(app, app, base || app.base, app.env);
      } else {
        // `parent` is used to get the base instance
        app.name = name;
        app.env = env || app.env || this.env;
      }

      app.define('parent', this);
      return app;
    };

    /**
     * Get the `base` instance
     */

    Object.defineProperty(proto, 'base', {
      configurable: true,
      get: function() {
        return this.parent ? this.parent.base : this;
      }
    });

  };
}

/**
 * Expose `runner`
 */

module.exports = runner;

/**
 * If necessary, this static method will resolve the _first instance_
 * to be used as the `base` instance for caching any additional resolved configs.
 *
 * ```js
 * var Generate = require('generate');
 * var resolver = require('base-resolver');
 *
 * var generate = resolver.first('generator.js', 'generate', {
 *   Ctor: Generate,
 *   isModule: function(app) {
 *     return app.isGenerate;
 *   }
 * });
 * ```
 * @param {String} `configfile` The name of the config file, ex: `assemblefile.js`
 * @param {String} `moduleName` The name of the module to lookup, ex: `assemble`
 * @param {Object} `options`
 *   @option {Function} `options.isModule` Optionally pass a function that will be used to verify that the correct instance was created.
 * @return {Object}
 * @api public
 */

function getConfig(configfile, moduleName, options) {
  var opts = utils.extend({ cwd: process.cwd() }, options);
  var fp = path.resolve(opts.cwd, configfile);

  var createEnv = utils.resolver.Resolver.createEnv;
  var fallback = opts.fallback;
  var Ctor = opts.Ctor;

  if (!utils.isAbsolute(fallback)) {
    fallback = utils.resolveModule(opts.fallback);
  }

  if (typeof Ctor !== 'function') {
    throw new TypeError('expected options.Ctor to be a function');
  }

  var validate = function() {
    return false;
  };

  if (typeof opts.isModule === 'function') {
    validate = opts.isModule;
  }

  // if a "configfile.js" is in the user's cwd, we'll try to
  // require it in and use it to get (or create) the instance
  if (fs.existsSync(fp)) {
    opts.module = moduleName;
    var env = createEnv(fp, opts.cwd, opts);
    Ctor = env.module.fn;

    // `fn` is whatever the "configfile" returns
    var fn = env.config.fn;

    // if the "configfile" returns a function, we need to
    // call the function, and pass an instance of our
    // application to it
    if (typeof fn === 'function') {
      var app = new Ctor();
      return app.invoke('base', fn, app, env);
    }

    // Otherwise, if the "configfile" returns an instance
    // of our application we'll use that as our `base`
    if (validate(fn)) {
      return fn;
    }
  }

  // if we haven't resolved a user-specified config file by now,
  // try the fallback dir, if passed on the options
  if (fallback && fallback !== opts.cwd) {
    opts.cwd = fallback;
    var base = getConfig(configfile, moduleName, opts);
    return base;
  }

  // create a new, bare instance as a last resort
  return new Ctor();
};

/**
 * Expose `getConfig`
 */

module.exports.getConfig = getConfig;
<|endoftext|>


<commit_before>const cheerio = require('cheerio');
const request = require('request');

// The module returns a client object
const boxrecClient = {

    getBoxerById: id => {

        // Parameter validation
        if (typeof id !== 'string') {
            return false;
        }

        request('http://boxrec.com/en/boxer/' + id, function (error, response, body) {
            //console.log('error:', error);
            //console.log('statusCode:', response && response.statusCode);
            //console.log('body:', body);

            // Load the page HTML into Cheerio
            var $ = cheerio.load(body);

            var boxer = {
                alias: '',
                bouts: '',
            };

            $('.profileTable .rowTable .rowLabel b').filter(function() {
                if($(this).text().indexOf('alias') > -1) {
                    boxer.alias = $(this).parent().next().text().trim();
                }
                if($(this).text().indexOf('bouts') > -1) {
                    boxer.bouts = parseInt($(this).parent().next().text().trim());
                }
                if($(this).text().indexOf('debut') > -1) {
                    boxer.debut = $(this).parent().next().text().trim();
                }
                if($(this).text().indexOf('nationality') > -1) {
                    boxer.nationality = $(this).parent().next().text().trim();
                }
                if($(this).text().indexOf('KOs') > -1) {
                    boxer.knockoutPercentage = parseInt($(this).parent().next().text());
                }
                if($(this).text().indexOf('rounds') > -1) {
                    boxer.rounds = parseInt($(this).parent().next().text());
                }
                if($(this).text().indexOf('stance') > -1) {
                    boxer.stance = $(this).parent().next().text().trim();
                }
                if($(this).text().indexOf('division') > -1) {
                    boxer.weightDivision = $(this).parent().next().text().trim();
                }
            });

            // Extract the data we need
            boxer.dob = $('span[itemprop="birthDate"]').text(),
            boxer.name = $('h1').text();
            boxer.wins = parseInt($('.profileWLD .bgW').text()),
            boxer.winsKO = parseInt($('.profileWLD .textWon').text()),
            boxer.draws = parseInt($('.profileWLD .bgD').text()),
            boxer.losses = parseInt($('.profileWLD .bgL').text()),
            boxer.lossesKO = parseInt($('.profileWLD .textLost').text()),

            console.log(boxer);
            return boxer;
        });
    }
}

boxrecClient.getBoxerById('474');

module.exports = boxrecClient;
<commit_msg>Converted async call into Promise speak<commit_after>const cheerio = require('cheerio');
const request = require('request');

// The module returns a client object
const boxrecClient = {

    getBoxerById: id => {

        // Define the boxer fetch function, returning a promise
        const getBoxer = id => {

            // Return a new promise
            return new Promise(function(resolve, reject) {

                // If the ID is not a string, reject the promise
                if (typeof id !== 'string') {
                    reject('Invalid id parameter. It must be a string');
                }

                request('http://boxrec.com/en/boxer/' + id, (error, response, body) => {

                    // If the request failed, reject the promise
                    if (error) {
                        reject(error);
                    }

                    // Load the page HTML into Cheerio
                    var $ = cheerio.load(body);

                    var boxer = {
                        alias: '',
                        bouts: '',
                    };

                    $('.profileTable .rowTable .rowLabel b').filter(function() {
                        if($(this).text().indexOf('alias') > -1) {
                            boxer.alias = $(this).parent().next().text().trim();
                        }
                        if($(this).text().indexOf('bouts') > -1) {
                            boxer.bouts = parseInt($(this).parent().next().text().trim());
                        }
                        if($(this).text().indexOf('debut') > -1) {
                            boxer.debut = $(this).parent().next().text().trim();
                        }
                        if($(this).text().indexOf('nationality') > -1) {
                            boxer.nationality = $(this).parent().next().text().trim();
                        }
                        if($(this).text().indexOf('KOs') > -1) {
                            boxer.knockoutPercentage = parseInt($(this).parent().next().text());
                        }
                        if($(this).text().indexOf('rounds') > -1) {
                            boxer.rounds = parseInt($(this).parent().next().text());
                        }
                        if($(this).text().indexOf('stance') > -1) {
                            boxer.stance = $(this).parent().next().text().trim();
                        }
                        if($(this).text().indexOf('division') > -1) {
                            boxer.weightDivision = $(this).parent().next().text().trim();
                        }
                    });

                    // Extract the data we need
                    boxer.dob = $('span[itemprop="birthDate"]').text(),
                    boxer.name = $('h1').text();
                    boxer.wins = parseInt($('.profileWLD .bgW').text()),
                    boxer.winsKO = parseInt($('.profileWLD .textWon').text()),
                    boxer.draws = parseInt($('.profileWLD .bgD').text()),
                    boxer.losses = parseInt($('.profileWLD .bgL').text()),
                    boxer.lossesKO = parseInt($('.profileWLD .textLost').text()),

                    resolve(boxer);
                });
            });
        };

        // Call our get boxer function, which returns a promise
        getBoxer(id).then(function(response) {
            // We got the boxer details, return them
            console.log(response);
            return response;
        }).catch (function (error) {
            // Something went wrong, error out
            console.error('getBoxerById function failed: ', error);
        });
    }
}

// Uncomment this to test the function
// boxrecClient.getBoxerById('474');

module.exports = boxrecClient;
<|endoftext|>


<commit_before>// @flow

import Icon from '@conveyal/woonerf/components/icon'
import React, {Component} from 'react'
import { Row, Col } from 'react-bootstrap'

type Props = {
  style: any
}

export default class Loading extends Component<Props> {
  render () {
    return (
      <Row>
        <Col xs={12}>

            <Icon style={this.props.style} className='fa-5x fa-spin' type='refresh' />

        </Col>
      </Row>
    )
  }
}
<commit_msg>test(flow): fix flow type for Loading component props<commit_after>// @flow

import Icon from '@conveyal/woonerf/components/icon'
import React, {Component} from 'react'
import { Row, Col } from 'react-bootstrap'

type Props = {
  style?: {[string]: string | number}
}

export default class Loading extends Component<Props> {
  render () {
    const {style} = this.props
    return (
      <Row>
        <Col xs={12}>

            <Icon style={style} className='fa-5x fa-spin' type='refresh' />

        </Col>
      </Row>
    )
  }
}
<|endoftext|>


<commit_before>// LICENSE : MIT
"use strict";
var React = require("react");
var ReactCodeMirror = require("react-code-mirror");
require("codemirror/addon/mode/overlay.js");
require("codemirror/mode/xml/xml.js");
require("codemirror/mode/markdown/markdown.js");
require("codemirror/mode/gfm/gfm.js");
require("codemirror/mode/javascript/javascript.js");
require("codemirror/mode/css/css.js");
require("codemirror/mode/htmlmixed/htmlmixed.js");
require("codemirror/mode/clike/clike.js");
require("codemirror/mode/meta.js");
require("codemirror/addon/edit/continuelist.js");

function scrollToBottom(cm) {
    var line = cm.lineCount();
    cm.setCursor({line: line, ch: 0});
    var myHeight = cm.getScrollInfo().clientHeight;
    var coords = cm.charCoords({line: line, ch: 0}, "local");
    cm.scrollTo(null, (coords.top + coords.bottom - myHeight) / 2);
}
export default class MarkdownEditor extends React.Component {
    constructor(props) {
        super(props);
        this.editorStore = this.props.context.editorStore;
        var editorAction = this.props.context.editorAction;
        this.editorStore.on("quote", (quoteText)=> {
            scrollToBottom(this.editor);
        });
        this.extraKeys = {
            "Cmd-S": ()=> {
                var filePath = this.editorStore.getFilePath();
                editorAction.saveAsFile(filePath);
                return false;
            },
            "Cmd-N": ()=> {
                editorAction.createNewFile();
                return false;
            },
            "Cmd-O": ()=> {
                editorAction.openFile();
                return false;
            },
            "Enter": "newlineAndIndentContinueMarkdownList"
        };

    }

    componentDidMount() {
        var nodes = React.findDOMNode(this);
        this.editor = nodes.querySelector(".CodeMirror").CodeMirror;
    }

    _onChange() {
        if (this.editor.getValue() != this.props.source) {
            this.editor.setValue(this.props.source);
        }
    }

    _codeMirrorOnChange(cm, change) {
        var text = this.editor.getValue();
        if (this.props.source === text) {
            return;
        }
        var action = this.props.context.editorAction;
        action.save(text);
    }

    render() {
        return

            <ReactCodeMirror value={this.props.source}
                             mode="gfm"
                             lineWrapping="true"
                             lineNumbers="true"
                             extraKeys={this.extraKeys}
                             onChange={this._codeMirrorOnChange.bind(this)}/>

    }
}<commit_msg>fix(editor): lazy call `scrollBottom`<commit_after>// LICENSE : MIT
"use strict";
var React = require("react");
var ReactCodeMirror = require("react-code-mirror");
require("codemirror/addon/mode/overlay.js");
require("codemirror/mode/xml/xml.js");
require("codemirror/mode/markdown/markdown.js");
require("codemirror/mode/gfm/gfm.js");
require("codemirror/mode/javascript/javascript.js");
require("codemirror/mode/css/css.js");
require("codemirror/mode/htmlmixed/htmlmixed.js");
require("codemirror/mode/clike/clike.js");
require("codemirror/mode/meta.js");
require("codemirror/addon/edit/continuelist.js");

function scrollToBottom(cm) {
    var line = cm.lineCount();
    cm.setCursor({line: line, ch: 0});
    var myHeight = cm.getScrollInfo().clientHeight;
    var coords = cm.charCoords({line: line, ch: 0}, "local");
    cm.scrollTo(null, (coords.top + coords.bottom - myHeight) / 2);
}
export default class MarkdownEditor extends React.Component {
    constructor(props) {
        super(props);
        this.editorStore = this.props.context.editorStore;
        var editorAction = this.props.context.editorAction;
        this.editorStore.on("quote", (quoteText)=> {
            setTimeout(()=> {
                scrollToBottom(this.editor);
            }, 64);
        });
        this.extraKeys = {
            "Cmd-S": ()=> {
                var filePath = this.editorStore.getFilePath();
                editorAction.saveAsFile(filePath);
                return false;
            },
            "Cmd-N": ()=> {
                editorAction.createNewFile();
                return false;
            },
            "Cmd-O": ()=> {
                editorAction.openFile();
                return false;
            },
            "Enter": "newlineAndIndentContinueMarkdownList"
        };

    }

    componentDidMount() {
        var nodes = React.findDOMNode(this);
        this.editor = nodes.querySelector(".CodeMirror").CodeMirror;
    }

    _codeMirrorOnChange(cm, change) {
        var text = this.editor.getValue();
        if (this.props.source === text) {
            return;
        }
        var action = this.props.context.editorAction;
        action.save(text);
    }

    render() {
        return

            <ReactCodeMirror value={this.props.source}
                             mode="gfm"
                             lineWrapping="true"
                             lineNumbers="true"
                             extraKeys={this.extraKeys}
                             onChange={this._codeMirrorOnChange.bind(this)}/>

    }
}<|endoftext|>


<commit_before>var bitwise = require('./bitwise.js')

// Use Hilbert curve point generation to map n-dimensional data to 1D space and vice-versa.

function Point(x, y, z) { // :: Int -> Int -> Int -> Point
    this.rotations = {
        x: 0,
        y: 0,
        z: 0
    }

    this.init = function (x, y, z) {
        this.x = Math.round(x) || 0
        this.y = Math.round(y) || 0
        if (z != null) {
            this.z = Math.round(z) || 0
            this.d = 3
            this.n = 4 * this.z + 2 * this.y  + this.x
        } else {
            this.z = null
            this.d = 2
        }
    }
    if (x instanceof Array) {
        this.init(x[0], x[1], x[2])
    } else {
        this.init(x, y, z)
    }
}

Point.prototype.rotate2d = function (n, xbit, ybit) { // : Int -> Int -> Int -> Point
    return new Point(rotate2d(n, this.x, this.y, xbit, ybit))
}

Point.prototype.rotate3d = function (level) { // :: Int -> Point
    return new Point(rotate3d(level, this.x, this.y, this.z))
}

Point.prototype.toArray = function () { // :: -> [Int, Int]
        if (this.d == 3) { return [this.x, this.y, this.z] }
        return [this.x, this.y]
}

// Accepts the height or width of a square/graph, and the coordinates to
// convert.
function convert2dPointToDistance (p, height) { // :: Int -> Int -> Int -> Int
    var xbit, ybit, level, d = 0
    var forHeight = p.x > p.y ? p.x : p.y

    // needs some tests to make sure height is compatible
    // What keeps the user from putting 54 down as the height
    while (forHeight >= height) {
            height *=2
    }
    // For each Hilbert level, we want to add an amount to
    // `d` based on which region we are in
    for (level = height / 2; level > 0; level = Math.floor(level / 2)) {
        // Determine what region we're in
        xbit = (p.x & level) > 0
        ybit = (p.y & level) > 0
        // increase distance based on region
        d += level * level * ((3 * xbit) ^ ybit)
        // rotate so that we'll be in sync with the next
        // region.
        p = p.rotate2d(level, xbit, ybit)
    }

    return d
}

// Accepts height or width of a square/graph and distance
function convertDistanceTo2dPoint (distance, height) { // :: Int -> Int -> [Int, Int]
    distance = Math.floor(distance)
    var xbit, ybit, level, p = new Point(0, 0)

    if (height <= Math.sqrt(distance))  {
        height = 2
        while (height <= Math.sqrt(distance)) {
            height *=2
        }
    }

    for (level = 1; level < height; level *= 2) {
        xbit = 1 & (distance / 2)
        ybit = 1 & (distance ^ xbit)

        p = p.rotate2d(level, xbit, ybit)
        p.x += level * xbit
        p.y += level * ybit
        distance = Math.floor(distance / 4)
    }

    return p.toArray()
}

// Rotate the coordinate plane and (x,y)
function rotate2d (n, x, y, xbit, ybit) { // :: Int -> Int -> Int -> Int -> Int -> [Int, Int]
    if (ybit == 0  ) {
        if (xbit == 1) {
            x = n - 1 - x
            y = n - 1 - y
        }

        var temp = x
        x = y
        y = temp
    }

    return [x, y]
}

function grayCode (sequence) { // :: Int -> Int
    return sequence ^ (sequence >> 1)
}

// returns a non-negative int 'inverse' such that graycode(inverse) = g
function grayInverse (g) { // : Int -> Int
    var m = precision(g), inverse = g, j = 1
    while (j < m) {
        inverse = inverse ^ (g >> j)
        j++
    }
    return inverse
}

// Returns the number of bits required to store an integer
function precision (n) { // :: Int > Int
    var ret = 0
    while (n > 0) {
        ret++
        n = n >> 1
    }
    return ret
}

function grayTransform (entry, direction, x, dim) { // :: Int -> Int -> Int -> Int
    return bitwise.rotateRight((x ^ entry), dim, 0, direction + 1)
}

function grayInverseTransform (entry, direction, x, dim) { // :: Int -> Int -> Int -> Int
    return grayTransform(bitwise.rotateRight(entry, dim, 0, direction + 1), dim - direction - 1, x, dim)
}

function entrySequence (i) { // :: Int -> Int
    if (i) {
        return grayCode(2 * Math.floor((i-1) / 2))
    }
    return 0
}

function directionSequence(i, dim) { // :: Int -> Int -> Int
    if (i == 0) return 0
    if (i % 2 == 0) return trailingSetBits(i - 1) % dim
    return trailingSetBits(i) % dim
}

function trailingSetBits (i) { // :: Int -> Int
    var ones = ~i & (i + 1)
    return Math.log(ones) / Math.log(2)
}

function hilbertIndex(point, options) { // :: [Int, Int, ..] -> {} -> Int
    options = options || {}
    var index = 0, code,
        entry = options.entry || 0,
        direction = options.direction || 0,
        i = options.precision || precision(Math.max.apply(null, point)) - 1,
        dim = point.length

    while (i >= 0) {

        var bits = 0
        var mask = 1 << dim - 1

        for (var k = 0; k < point.length; k++) {
            if (point[dim - (k+1)] & (1 << i)) {
                bits |= mask
            }
            mask >>>= 1
        }

        bits = grayTransform(entry, direction, bits, dim)
        code = grayInverse(bits)

        entry = entry ^ bitwise.rotateLeft(entrySequence(code), dim, 0, direction + 1)
        direction = (direction + directionSequence(code, dim) + 1) % dim
        index = (index << dim) | code

        i--
    }

    return index
}

function precise(index, dim) {
    var n = Math.pow(2, dim)
    var bits = 32

    while(bits % dim != 0) --bits

    for (var i=1; i < bits; i++) {
        if (index < Math.pow(n, i)) return i+1
    }
}

function hilbertIndexInverse(dim, index, options) { // :: Int -> Int -> [Int, Int, ..]
    options = options || {}
    var entry = options.entry || 0,
        direction = options.direction || 0,
        m = precise(index, dim),
        p = Array.apply(null, new Array(dim)).map(Number.prototype.valueOf, 0)

    for (var i = m - 1; i >= 0; i--) {
        var mask = 1 << (i * dim), bits = 0, code

        for (var k = dim - 1; k >= 0; k--) {
            if (index & (mask << k)) {
                bits |= (1 << k)
            }
        }

        code = grayInverseTransform(entry, direction, grayCode(bits), dim)
        for (var k = 0; k < dim; k++) {
            if (code & (1 << k)) {
                p[k] |= (1 << i)
            }
        }

        entry = entry ^ bitwise.rotateLeft(entrySequence(bits), dim, 0, direction + 1)
        direction = (direction + directionSequence(bits, dim) + 1) % dim
    }
    return p
}

function nthRoot(num, nArg, precArg) { // : Int -> Int -> Int -> Int
  var n = nArg || 2;
  var prec = precArg || 12;

  var x = 1; // Initial guess.
  for (var i=0; i<prec; i++) {
    x = 1/n * ((n-1)*x + (num / Math.pow(x, n-1)));
  }

  return x;
}

exports.xy2d = function (x, y, height) {
    height = height || 2
    return convert2dPointToDistance(new Point(x, y), height)
}

exports.xyz2d = function(x, y, z, height) {
    height = height || 2
    return convert3dPointToDistance(new Point(x, y, z), height)
}
exports.hilbert = hilbertIndex
exports.hilbertInverse = hilbertIndexInverse
<commit_msg>Reorganizing.<commit_after>var bitwise = require('./bitwise.js')

// Use Hilbert curve point generation to map n-dimensional data to 1D space and vice-versa.

function Point(x, y, z) { // :: Int -> Int -> Int -> Point
    this.rotations = {
        x: 0,
        y: 0,
        z: 0
    }

    this.init = function (x, y, z) {
        this.x = Math.round(x) || 0
        this.y = Math.round(y) || 0
        if (z != null) {
            this.z = Math.round(z) || 0
            this.d = 3
            this.n = 4 * this.z + 2 * this.y  + this.x
        } else {
            this.z = null
            this.d = 2
        }
    }
    if (x instanceof Array) {
        this.init(x[0], x[1], x[2])
    } else {
        this.init(x, y, z)
    }
}

Point.prototype.rotate2d = function (n, xbit, ybit) { // : Int -> Int -> Int -> Point
    return new Point(rotate2d(n, this.x, this.y, xbit, ybit))
}

Point.prototype.rotate3d = function (level) { // :: Int -> Point
    return new Point(rotate3d(level, this.x, this.y, this.z))
}

Point.prototype.toArray = function () { // :: -> [Int, Int]
        if (this.d == 3) { return [this.x, this.y, this.z] }
        return [this.x, this.y]
}

// Accepts the height or width of a square/graph, and the coordinates to
// convert.
function convert2dPointToDistance (p, height) { // :: Int -> Int -> Int -> Int
    var xbit, ybit, level, d = 0
    var forHeight = p.x > p.y ? p.x : p.y

    // needs some tests to make sure height is compatible
    // What keeps the user from putting 54 down as the height
    while (forHeight >= height) {
            height *=2
    }
    // For each Hilbert level, we want to add an amount to
    // `d` based on which region we are in
    for (level = height / 2; level > 0; level = Math.floor(level / 2)) {
        // Determine what region we're in
        xbit = (p.x & level) > 0
        ybit = (p.y & level) > 0
        // increase distance based on region
        d += level * level * ((3 * xbit) ^ ybit)
        // rotate so that we'll be in sync with the next
        // region.
        p = p.rotate2d(level, xbit, ybit)
    }

    return d
}

// Accepts height or width of a square/graph and distance
function convertDistanceTo2dPoint (distance, height) { // :: Int -> Int -> [Int, Int]
    distance = Math.floor(distance)
    var xbit, ybit, level, p = new Point(0, 0)

    if (height <= Math.sqrt(distance))  {
        height = 2
        while (height <= Math.sqrt(distance)) {
            height *=2
        }
    }

    for (level = 1; level < height; level *= 2) {
        xbit = 1 & (distance / 2)
        ybit = 1 & (distance ^ xbit)

        p = p.rotate2d(level, xbit, ybit)
        p.x += level * xbit
        p.y += level * ybit
        distance = Math.floor(distance / 4)
    }

    return p.toArray()
}

// Rotate the coordinate plane and (x,y)
function rotate2d (n, x, y, xbit, ybit) { // :: Int -> Int -> Int -> Int -> Int -> [Int, Int]
    if (ybit == 0  ) {
        if (xbit == 1) {
            x = n - 1 - x
            y = n - 1 - y
        }

        var temp = x
        x = y
        y = temp
    }

    return [x, y]
}

function grayCode (sequence) { // :: Int -> Int
    return sequence ^ (sequence >> 1)
}

// returns a non-negative int 'inverse' such that graycode(inverse) = g
function grayInverse (g) { // : Int -> Int
    var m = precision(g), inverse = g, j = 1
    while (j < m) {
        inverse = inverse ^ (g >> j)
        j++
    }
    return inverse
}

function grayTransform (entry, direction, x, dim) { // :: Int -> Int -> Int -> Int
    return bitwise.rotateRight((x ^ entry), dim, 0, direction + 1)
}

function grayInverseTransform (entry, direction, x, dim) { // :: Int -> Int -> Int -> Int
    return grayTransform(bitwise.rotateRight(entry, dim, 0, direction + 1), dim - direction - 1, x, dim)
}

// Returns the number of bits required to store an integer
function precision (n) { // :: Int > Int
    var ret = 0
    while (n > 0) {
        ret++
        n = n >> 1
    }
    return ret
}

function entrySequence (i) { // :: Int -> Int
    if (i) {
        return grayCode(2 * Math.floor((i-1) / 2))
    }
    return 0
}

function directionSequence(i, dim) { // :: Int -> Int -> Int
    if (i == 0) return 0
    if (i % 2 == 0) return trailingSetBits(i - 1) % dim
    return trailingSetBits(i) % dim
}

function trailingSetBits (i) { // :: Int -> Int
    var ones = ~i & (i + 1)
    return Math.log(ones) / Math.log(2)
}

function precise(index, dim) {
    var n = Math.pow(2, dim)
    var bits = 32

    while(bits % dim != 0) --bits

    for (var i=1; i < bits; i++) {
        if (index < Math.pow(n, i)) return i+1
    }
}

function nthRoot(num, nArg, precArg) { // : Int -> Int -> Int -> Int
  var n = nArg || 2;
  var prec = precArg || 12;

  var x = 1; // Initial guess.
  for (var i=0; i<prec; i++) {
    x = 1/n * ((n-1)*x + (num / Math.pow(x, n-1)));
  }

  return x;
}

function hilbertIndex(point, options) { // :: [Int, Int, ..] -> {} -> Int
    options = options || {}
    var index = 0, code,
        entry = options.entry || 0,
        direction = options.direction || 0,
        i = options.precision || precision(Math.max.apply(null, point)) - 1,
        dim = point.length

    while (i >= 0) {

        var bits = 0
        var mask = 1 << dim - 1

        for (var k = 0; k < point.length; k++) {
            if (point[dim - (k+1)] & (1 << i)) {
                bits |= mask
            }
            mask >>>= 1
        }

        bits = grayTransform(entry, direction, bits, dim)
        code = grayInverse(bits)

        entry = entry ^ bitwise.rotateLeft(entrySequence(code), dim, 0, direction + 1)
        direction = (direction + directionSequence(code, dim) + 1) % dim
        index = (index << dim) | code

        i--
    }

    return index
}

function hilbertIndexInverse(dim, index, options) { // :: Int -> Int -> [Int, Int, ..]
    options = options || {}
    var entry = options.entry || 0,
        direction = options.direction || 0,
        m = precise(index, dim),
        p = Array.apply(null, new Array(dim)).map(Number.prototype.valueOf, 0)

    for (var i = m - 1; i >= 0; i--) {
        var mask = 1 << (i * dim), bits = 0, code

        for (var k = dim - 1; k >= 0; k--) {
            if (index & (mask << k)) {
                bits |= (1 << k)
            }
        }

        code = grayInverseTransform(entry, direction, grayCode(bits), dim)
        for (var k = 0; k < dim; k++) {
            if (code & (1 << k)) {
                p[k] |= (1 << i)
            }
        }

        entry = entry ^ bitwise.rotateLeft(entrySequence(bits), dim, 0, direction + 1)
        direction = (direction + directionSequence(bits, dim) + 1) % dim
    }
    return p
}

exports.xy2d = function (x, y, height) {
    height = height || 2
    return convert2dPointToDistance(new Point(x, y), height)
}

exports.xyz2d = function(x, y, z, height) {
    height = height || 2
    return convert3dPointToDistance(new Point(x, y, z), height)
}
exports.hilbert = hilbertIndex
exports.hilbertInverse = hilbertIndexInverse
<|endoftext|>


<commit_before>var Q = require('q');

module.exports = exports = function why(opts) {
  if(arguments.length === 0) {
    return exports.resume.apply(this, arguments);
  }
  return exports.create(opts);
}

exports.done = function done() {
  if(!exports.runningState || !exports.runningState.wrappedPromise) {
    throw error.INVALID_STATE_FOR_DONE();
  }
  var wrapped = exports.runningState.wrappedPromise;
  delete exports.runningState.wrappedPromise;
  return wrapped;
}

exports.create = function create(factory) {
  var wrapper = function wrapper() {
    var iterator = factory.apply(this, arguments);
    var promise = exports.run(iterator);

    var result = function result(cb) {
      promise
        .fail(function(err) { cb(err); })
        .then(function(v) { cb(null, v); });
    }
    result.__proto__ = promise;
    return result;
  }
  wrapper.toString = function() {
    return 'why(' + factory.toString() + ')';
  }
  return wrapper;
};

exports.resume = function resume(throws) {
  var state = exports.runningState;
  var wrap = Q.defer(), old = state.wrappedPromise;
  if(!old) { state.wrappedPromise = wrap.promise; }
  else {
    var list = state.wrappedPromise.list || [state.wrappedPromise];
    list.push(wrap.promise);
    state.wrappedPromise = Q.all(list);
    state.wrappedPromise.list = list;
  }
  return function(err, result) {
    if(throws === false) { result = err; err = null; }
    if(err) return wrap.reject(err);
    if(arguments.length === 2) return wrap.resolve(result);
    var args = Array.prototype.slice.call(arguments, 1);
    wrap.resolve(args);
  };
}

exports.run = function run(iterator) {
  var def      = Q.defer()
    , state    = { wrappedPromise: undefined }
    , callback = next.bind(next, 'next')
    , errback  = next.bind(next, 'throw');

  next('send');
  return def.promise;
  function next(verb, value) {
    function verify() {
      if(state.wrappedPromise !== undefined) {
        throw error.UNUSED_CALLBACK();
      }
    }

    try {
      var promise, response, oldState = exports.runningState;
      verify();
      exports.runningState = state;
      try {
        response = iterator[verb](value);
      } finally {
        exports.runningState = oldState;
      }
      if(response.done) {
        verify();
        return def.resolve(response.value);
      }
      var promised = exports.toPromise(response.value, false);
      if(state.wrappedPromise !== undefined && promised === undefined) {
        promised = state.wrappedPromise;
        state.wrappedPromise = undefined;
      }
      verify();
      promised.then(callback).fail(errback);
    } catch(ex) {
      def.reject(ex);
    }
  }
}

exports.toPromise = function toPromise(value, raiseError) {
  if(value) {
    if(isPromise(value)) { return value; }
    if(isGenerator(value)) { return exports.run(value); }
    if(isGeneratorFunction(value)) { return exports.create(value)(); }
    if(Array.isArray(value)) { return Q.all(value.map(exports.toPromise)); }
  }
  if(raiseError === false) return;
  throw error.TOPROMISE_FAILED();
}

function isPromise(v) { return v && v.then && v.then.call; }
function isGenerator(v) { return v && Object.prototype.toString.call(v) === '[object Generator]'; }
function isGeneratorFunction(v) { return v && v.constructor && v.constructor.name === 'GeneratorFunction'; }

error('INVALID_STATE_FOR_DONE', 'Y.done can only be used right after wrapping a node-style callback!');
error('UNUSED_CALLBACK', 'expected node-style callback did not occur!');
error('TOPROMISE_FAILED', 'yield value must be a generator, promise or an array of generators or promises.');
function error(code, msg) {
  error[code] = function() {
    var err = new Error(msg + ' (WHY_' + code + ')');
    err.code = 'WHY_' + code;
    return err;
  }
}

<commit_msg>used wrong function<commit_after>var Q = require('q');

module.exports = exports = function why(opts) {
  if(arguments.length === 0) {
    return exports.resume.apply(this, arguments);
  }
  return exports.create(opts);
}

exports.done = function done() {
  if(!exports.runningState || !exports.runningState.wrappedPromise) {
    throw error.INVALID_STATE_FOR_DONE();
  }
  var wrapped = exports.runningState.wrappedPromise;
  delete exports.runningState.wrappedPromise;
  return wrapped;
}

exports.create = function create(factory) {
  var wrapper = function wrapper() {
    var iterator = factory.apply(this, arguments);
    var promise = exports.run(iterator);

    var result = function result(cb) {
      promise
        .fail(function(err) { cb(err); })
        .then(function(v) { cb(null, v); });
    }
    result.__proto__ = promise;
    return result;
  }
  wrapper.toString = function() {
    return 'why(' + factory.toString() + ')';
  }
  return wrapper;
};

exports.resume = function resume(throws) {
  var state = exports.runningState;
  var wrap = Q.defer(), old = state.wrappedPromise;
  if(!old) { state.wrappedPromise = wrap.promise; }
  else {
    var list = state.wrappedPromise.list || [state.wrappedPromise];
    list.push(wrap.promise);
    state.wrappedPromise = Q.all(list);
    state.wrappedPromise.list = list;
  }
  return function(err, result) {
    if(throws === false) { result = err; err = null; }
    if(err) return wrap.reject(err);
    if(arguments.length === 2) return wrap.resolve(result);
    var args = Array.prototype.slice.call(arguments, 1);
    wrap.resolve(args);
  };
}

exports.run = function run(iterator) {
  var def      = Q.defer()
    , state    = { wrappedPromise: undefined }
    , callback = next.bind(next, 'next')
    , errback  = next.bind(next, 'throw');

  next('next');
  return def.promise;
  function next(verb, value) {
    function verify() {
      if(state.wrappedPromise !== undefined) {
        throw error.UNUSED_CALLBACK();
      }
    }

    try {
      var promise, response, oldState = exports.runningState;
      verify();
      exports.runningState = state;
      try {
        response = iterator[verb](value);
      } finally {
        exports.runningState = oldState;
      }
      if(response.done) {
        verify();
        return def.resolve(response.value);
      }
      var promised = exports.toPromise(response.value, false);
      if(state.wrappedPromise !== undefined && promised === undefined) {
        promised = state.wrappedPromise;
        state.wrappedPromise = undefined;
      }
      verify();
      promised.then(callback).fail(errback);
    } catch(ex) {
      def.reject(ex);
    }
  }
}

exports.toPromise = function toPromise(value, raiseError) {
  if(value) {
    if(isPromise(value)) { return value; }
    if(isGenerator(value)) { return exports.run(value); }
    if(isGeneratorFunction(value)) { return exports.create(value)(); }
    if(Array.isArray(value)) { return Q.all(value.map(exports.toPromise)); }
  }
  if(raiseError === false) return;
  throw error.TOPROMISE_FAILED();
}

function isPromise(v) { return v && v.then && v.then.call; }
function isGenerator(v) { return v && Object.prototype.toString.call(v) === '[object Generator]'; }
function isGeneratorFunction(v) { return v && v.constructor && v.constructor.name === 'GeneratorFunction'; }

error('INVALID_STATE_FOR_DONE', 'Y.done can only be used right after wrapping a node-style callback!');
error('UNUSED_CALLBACK', 'expected node-style callback did not occur!');
error('TOPROMISE_FAILED', 'yield value must be a generator, promise or an array of generators or promises.');
function error(code, msg) {
  error[code] = function() {
    var err = new Error(msg + ' (WHY_' + code + ')');
    err.code = 'WHY_' + code;
    return err;
  }
}

<|endoftext|>


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

/**
 * @fileoverview Controllers for the editor's state graph.
 *
 * @author sll@google.com (Sean Lip)
 */

function EditorGraph($scope, $filter, explorationData) {
  $scope.updateViz = function() {
    explorationData.getData().then(function(data) {
      $scope.graphData = $scope.reformatResponse(
          data.states, data.init_state_id);
    });
  };

  // At the start, update the graph.
  $scope.updateViz();

  // Also update the graph when an update event is broadcast.
  $scope.$on('updateViz', $scope.updateViz);

  // Reformat the model into a response that is processable by d3.js.
  $scope.reformatResponse = function(states, initStateId) {
    var SENTINEL_DEPTH = 3000;
    var VERT_OFFSET = 20;
    var HORIZ_SPACING = 150;
    var VERT_SPACING = 100;
    var HORIZ_OFFSET = 100;
    var nodes = {};
    nodes[END_DEST] = {name: END_DEST, depth: SENTINEL_DEPTH, reachable: false};
    for (var state in states) {
      nodes[state] = {name: states[state].name, depth: SENTINEL_DEPTH, reachable: false};
    }
    nodes[initStateId].depth = 0;

    var maxDepth = 0;
    var seenNodes = [initStateId];
    var queue = [initStateId];
    var maxXDistPerLevel = {0: HORIZ_OFFSET};
    nodes[initStateId].y0 = VERT_OFFSET;
    nodes[initStateId].x0 = HORIZ_OFFSET;

    while (queue.length > 0) {
      var currNode = queue[0];
      queue.shift();
      nodes[currNode].reachable = true;
      if (currNode in states) {
        for (var i = 0; i < states[currNode].widget.rules.submit.length; i++) {
          // Assign levels to nodes only when they are first encountered.
          if (seenNodes.indexOf(states[currNode].widget.rules.submit[i].dest) == -1) {
            seenNodes.push(states[currNode].widget.rules.submit[i].dest);
            nodes[states[currNode].widget.rules.submit[i].dest].depth = nodes[currNode].depth + 1;
            nodes[states[currNode].widget.rules.submit[i].dest].y0 = (nodes[currNode].depth + 1) * VERT_SPACING + VERT_OFFSET;
            if (nodes[currNode].depth + 1 in maxXDistPerLevel) {
              nodes[states[currNode].widget.rules.submit[i].dest].x0 = maxXDistPerLevel[nodes[currNode].depth + 1] + HORIZ_SPACING;
              maxXDistPerLevel[nodes[currNode].depth + 1] += HORIZ_SPACING;
            } else {
              nodes[states[currNode].widget.rules.submit[i].dest].x0 = HORIZ_OFFSET;
              maxXDistPerLevel[nodes[currNode].depth + 1] = HORIZ_OFFSET;
            }
            maxDepth = Math.max(maxDepth, nodes[currNode].depth + 1);
            queue.push(states[currNode].widget.rules.submit[i].dest);
          }
        }
      }
    }

    var horizPositionForLastRow = HORIZ_OFFSET;
    for (var node in nodes) {
      if (nodes[node].depth == SENTINEL_DEPTH) {
        nodes[node].depth = maxDepth + 1;
        nodes[node].y0 = VERT_OFFSET + nodes[node].depth * VERT_SPACING;
        nodes[node].x0 = horizPositionForLastRow;
        horizPositionForLastRow += HORIZ_SPACING;
      }
    }

    // Assign unique IDs to each node.
    var idCount = 0;
    var nodeList = [];
    for (var node in nodes) {
      var nodeMap = nodes[node];
      nodeMap['hashId'] = node;
      nodeMap['id'] = idCount;
      nodes[node]['id'] = idCount;
      idCount++;
      nodeList.push(nodeMap);
    }

    var links = [];
    for (var state in states) {
      for (var i = 0; i < states[state].widget.rules.submit.length; i++) {
        links.push({
            source: nodeList[nodes[state].id],
            target: nodeList[nodes[states[state].widget.rules.submit[i].dest].id],
            name: $filter('parameterizeRule')({
                rule: states[state].widget.rules.submit[i].rule,
                inputs: states[state].widget.rules.submit[i].inputs
            })
        });
      }
    }

    return {nodes: nodeList, links: links, initStateId: initStateId};
  };
}

oppia.directive('stateGraphViz', function(explorationData) {
  // constants
  var w = 960,
      h = 4000,
      i = 0;
  var DEFAULT_CIRCLE_RADIUS = 30;
  // The following variable must be at least 3.
  var MAX_CATEGORY_LENGTH = 20;

  var getEllipseWidth = function(text) {
    return 20 + Math.min(MAX_CATEGORY_LENGTH, text.length) * 3;
  };

  return {
    restrict: 'E',
    scope: {
      val: '=',
      grouped: '='
    },
    link: function(scope, element, attrs) {
      scope.truncate = function(text) {
        if (text.length > MAX_CATEGORY_LENGTH) {
          return text.substring(0, MAX_CATEGORY_LENGTH - 3) + '...';
        } else {
          return text;
        }
      };

      var vis = d3.select(element[0]).append('svg:svg')
          .attr('width', w)
          .attr('height', h)
          .attr('class', 'oppia-graph-viz')
        .append('svg:g')
          .attr('transform', 'translate(20,30)');

      scope.$watch('val', function (newVal, oldVal) {
        // clear the elements inside of the directive
        vis.selectAll('*').remove();

        // if 'val' is undefined, exit
        if (!newVal) {
          return;
        }

        var source = newVal;
        var nodes = source.nodes;
        var links = source.links;
        var initStateId = source.initStateId;

        // Update the links
        var link = vis.selectAll('path.link')
            .data(links);

        vis.append('svg:defs').selectAll('marker')
            .data(['arrowhead'])
          .enter().append('svg:marker')
            .attr('id', String)
            .attr('viewBox', '0 -5 10 10')
            .attr('refX', 25)
            .attr('refY', -1.5)
            .attr('markerWidth', 6)
            .attr('markerHeight', 6)
            .attr('orient', 'auto')
          .append('svg:path')
            .attr('d', 'M0,-5L10,0L0,5')
            .attr('fill', 'red');

        var linkEnter = link.enter().append('svg:g')
            .attr('class', 'link');

        linkEnter.insert('svg:path', 'g')
            .style('stroke-width', 3)
            .style('stroke', 'red')
            .attr('class', 'link')
            .attr('d', function(d) {
              // Draw elliptical arcs.
              var dx = d.target.x0 - d.source.x0,
                  dy = d.target.y0 - d.source.y0,
                  dr = Math.sqrt(dx * dx + dy * dy);
              return 'M' + d.source.x0 + ',' + d.source.y0 + 'A' + dr + ',' + dr + ' 0 0,1 ' + d.target.x0 + ',' + d.target.y0;
            })
            .attr('marker-end', function(d) {
              if (d.source.x0 == d.target.x0 && d.source.y0 == d.target.y0) {
                return '';
              } else {
                return 'url(#arrowhead)';
              }
            });

        linkEnter.append('svg:text')
            .attr('dy', function(d) { return d.source.y0*0.5 + d.target.y0*0.5; })
            .attr('dx', function(d) {
              return d.source.x0*0.5 + d.target.x0*0.5 - DEFAULT_CIRCLE_RADIUS;
            })
            .attr('color', 'black')
            .text(function(d) {
              if (d.source.x0 == d.target.x0 && d.source.y0 == d.target.y0) {
                return '';
              }
              return '';
              // TODO(sll): display link text (return d.name) when we can do so
              // without all the text overlapping.
            });

        // Update the nodes
        // TODO(sll): Put a blue border around the current node.
        var node = vis.selectAll('g.node')
            .data(nodes, function(d) { return d.id; });

        var nodeEnter = node.enter().append('svg:g')
            .attr('class', 'node');

        // Add nodes to the canvas.
        nodeEnter.append('svg:ellipse')
            .attr('cy', function(d) { return d.y0; })
            .attr('cx', function(d) { return d.x0; })
            .attr('rx', function(d) {
              if (d.hashId == initStateId) {
                return 40;
              } else {
                return getEllipseWidth(d.name);
              }
            })
            .attr('ry', function(d) {
              if (d.hashId == initStateId) {
                return 40;
              } else {
                return 30;
              }
            })
            .attr('class', function(d) {
              if (d.hashId != END_DEST) {
                return 'clickable';
              }
            })
            .style('fill', function(d) {
              if (d.hashId == END_DEST) {
                return 'olive';
              } else if (d.reachable === false) {
                return 'pink';
              } else {
                return 'beige';
              }
            })
            .on('click', function (d) {
              if (d.hashId == END_DEST) {
                return;
              }
              explorationData.getStateData(d.hashId);
              scope.$parent.$parent.stateId = d.hashId;
              $('#editorViewTab a[href="#stateEditor"]').tab('show');
            })
            .append('svg:title')
            .text(function(d) { return d.name; });

        nodeEnter.append('svg:text')
            .attr('dx', function(d) { return d.x0 - getEllipseWidth(d.name) + 5; })
            .attr('dy', function(d) { return d.y0; })
            .text(function(d) { return scope.truncate(d.name); });

        // Add a 'delete node' handler.
        nodeEnter.append('svg:rect')
            .attr('y', function(d) { return d.y0; })
            .attr('x', function(d) { return d.x0; })
            .attr('height', 20)
            .attr('width', 20)
            .attr('opacity', 0)
            .attr('transform', function(d) {
              return 'translate(' + (getEllipseWidth(d.name) - 20) + ',' + (-30) + ')'; }
            )
            .attr('stroke-width', '0')
            .on('click', function (d) {
              if (d.hashId == initStateId || d.hashId == END_DEST) {
                return;
              }
              scope.$parent.$parent.openDeleteStateModal(d.hashId);
            });

        nodeEnter.append('svg:text')
            .attr('dx', function(d) { return d.x0 + getEllipseWidth(d.name) - 20; })
            .attr('dy', function(d) { return d.y0 - 20; })
            .text(function(d) {
              if (d.hashId == initStateId || d.hashId == END_DEST) {
                return;
              }
              return 'x';
            });
      });
    }
  };
});

/**
 * Injects dependencies in a way that is preserved by minification.
 */
EditorGraph.$inject = ['$scope', '$filter', 'explorationData'];
<commit_msg>editor graph rendering tweaks<commit_after>// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Controllers for the editor's state graph.
 *
 * @author sll@google.com (Sean Lip)
 */

function EditorGraph($scope, $filter, explorationData) {
  $scope.updateViz = function() {
    explorationData.getData().then(function(data) {
      $scope.graphData = $scope.reformatResponse(
          data.states, data.init_state_id);
    });
  };

  // At the start, update the graph.
  $scope.updateViz();

  // Also update the graph when an update event is broadcast.
  $scope.$on('updateViz', $scope.updateViz);

  // Reformat the model into a response that is processable by d3.js.
  $scope.reformatResponse = function(states, initStateId) {
    var SENTINEL_DEPTH = 3000;
    var VERT_OFFSET = 20;
    var HORIZ_SPACING = 150;
    var VERT_SPACING = 100;
    var HORIZ_OFFSET = 100;
    var nodes = {};
    nodes[END_DEST] = {name: END_DEST, depth: SENTINEL_DEPTH, reachable: false};
    for (var state in states) {
      nodes[state] = {name: states[state].name, depth: SENTINEL_DEPTH, reachable: false};
    }
    nodes[initStateId].depth = 0;

    var maxDepth = 0;
    var seenNodes = [initStateId];
    var queue = [initStateId];
    var maxXDistPerLevel = {0: HORIZ_OFFSET};
    nodes[initStateId].y0 = VERT_OFFSET;
    nodes[initStateId].x0 = HORIZ_OFFSET;

    while (queue.length > 0) {
      var currNode = queue[0];
      queue.shift();
      nodes[currNode].reachable = true;
      if (currNode in states) {
        for (var i = 0; i < states[currNode].widget.rules.submit.length; i++) {
          // Assign levels to nodes only when they are first encountered.
          if (seenNodes.indexOf(states[currNode].widget.rules.submit[i].dest) == -1) {
            seenNodes.push(states[currNode].widget.rules.submit[i].dest);
            nodes[states[currNode].widget.rules.submit[i].dest].depth = nodes[currNode].depth + 1;
            nodes[states[currNode].widget.rules.submit[i].dest].y0 = (nodes[currNode].depth + 1) * VERT_SPACING + VERT_OFFSET;
            if (nodes[currNode].depth + 1 in maxXDistPerLevel) {
              nodes[states[currNode].widget.rules.submit[i].dest].x0 = maxXDistPerLevel[nodes[currNode].depth + 1] + HORIZ_SPACING;
              maxXDistPerLevel[nodes[currNode].depth + 1] += HORIZ_SPACING;
            } else {
              nodes[states[currNode].widget.rules.submit[i].dest].x0 = HORIZ_OFFSET;
              maxXDistPerLevel[nodes[currNode].depth + 1] = HORIZ_OFFSET;
            }
            maxDepth = Math.max(maxDepth, nodes[currNode].depth + 1);
            queue.push(states[currNode].widget.rules.submit[i].dest);
          }
        }
      }
    }

    var horizPositionForLastRow = HORIZ_OFFSET;
    for (var node in nodes) {
      if (nodes[node].depth == SENTINEL_DEPTH) {
        nodes[node].depth = maxDepth + 1;
        nodes[node].y0 = VERT_OFFSET + nodes[node].depth * VERT_SPACING;
        nodes[node].x0 = horizPositionForLastRow;
        horizPositionForLastRow += HORIZ_SPACING;
      }
    }

    // Assign unique IDs to each node.
    var idCount = 0;
    var nodeList = [];
    for (var node in nodes) {
      var nodeMap = nodes[node];
      nodeMap['hashId'] = node;
      nodeMap['id'] = idCount;
      nodes[node]['id'] = idCount;
      idCount++;
      nodeList.push(nodeMap);
    }

    var links = [];
    for (var state in states) {
      for (var i = 0; i < states[state].widget.rules.submit.length; i++) {
        links.push({
            source: nodeList[nodes[state].id],
            target: nodeList[nodes[states[state].widget.rules.submit[i].dest].id],
            name: $filter('parameterizeRule')({
                rule: states[state].widget.rules.submit[i].rule,
                inputs: states[state].widget.rules.submit[i].inputs
            })
        });
      }
    }

    return {nodes: nodeList, links: links, initStateId: initStateId};
  };
}

oppia.directive('stateGraphViz', function(explorationData) {
  // constants
  var w = 960,
      h = 4000,
      i = 0;
  var DEFAULT_CIRCLE_RADIUS = 30;
  // The following variable must be at least 3.
  var MAX_CATEGORY_LENGTH = 20;

  var getTextWidth = function(text) {
    return 40 + Math.min(MAX_CATEGORY_LENGTH, text.length) * 10;
  };

  return {
    restrict: 'E',
    scope: {
      val: '=',
      grouped: '='
    },
    link: function(scope, element, attrs) {
      scope.truncate = function(text) {
        if (text.length > MAX_CATEGORY_LENGTH) {
          return text.substring(0, MAX_CATEGORY_LENGTH - 3) + '...';
        } else {
          return text;
        }
      };

      var vis = d3.select(element[0]).append('svg:svg')
          .attr('width', w)
          .attr('height', h)
          .attr('class', 'oppia-graph-viz')
        .append('svg:g')
          .attr('transform', 'translate(20,30)');

      scope.$watch('val', function (newVal, oldVal) {
        // clear the elements inside of the directive
        vis.selectAll('*').remove();

        // if 'val' is undefined, exit
        if (!newVal) {
          return;
        }

        var source = newVal;
        var nodes = source.nodes;
        var links = source.links;
        var initStateId = source.initStateId;

        // Update the links
        var link = vis.selectAll('path.link')
            .data(links);

        vis.append('svg:defs').selectAll('marker')
            .data(['arrowhead'])
          .enter().append('svg:marker')
            .attr('id', String)
            .attr('viewBox', '0 -5 10 10')
            .attr('refX', 25)
            .attr('refY', -1.5)
            .attr('markerWidth', 6)
            .attr('markerHeight', 6)
            .attr('orient', 'auto')
          .append('svg:path')
            .attr('d', 'M0,-5L10,0L0,5')
            .attr('fill', 'red');

        var linkEnter = link.enter().append('svg:g')
            .attr('class', 'link');

        linkEnter.insert('svg:path', 'g')
            .style('stroke-width', 3)
            .style('stroke', 'red')
            .attr('opacity', .3)
            .attr('class', 'link')
            .attr('d', function(d) {
              // Draw elliptical arcs.
              var dx = d.target.x0 - d.source.x0,
                  dy = d.target.y0 - d.source.y0,
                  dr = Math.sqrt(dx * dx + dy * dy);
              return 'M' + d.source.x0 + ',' + d.source.y0 + 'A' + dr + ',' + dr + ' 0 0,1 ' + d.target.x0 + ',' + d.target.y0;
            })
            .attr('marker-end', function(d) {
              if (d.source.x0 == d.target.x0 && d.source.y0 == d.target.y0) {
                return '';
              } else {
                return 'url(#arrowhead)';
              }
            });

        linkEnter.append('svg:text')
            .attr('dy', function(d) { return d.source.y0*0.5 + d.target.y0*0.5; })
            .attr('dx', function(d) {
              return d.source.x0*0.5 + d.target.x0*0.5 - DEFAULT_CIRCLE_RADIUS;
            })
            .attr('color', 'black')
            .text(function(d) {
              if (d.source.x0 == d.target.x0 && d.source.y0 == d.target.y0) {
                return '';
              }
              return '';
              // TODO(sll): display link text (return d.name) when we can do so
              // without all the text overlapping.
            });

        // Update the nodes
        // TODO(sll): Put a blue border around the current node.
        var node = vis.selectAll('g.node')
            .data(nodes, function(d) { return d.id; });

        var nodeEnter = node.enter().append('svg:g')
            .attr('class', 'node');

        // Add nodes to the canvas.
        nodeEnter.append('svg:rect')
            .attr('x', function(d) { return d.x0; })
            .attr('y', function(d) { return d.y0; })
            .attr('ry', function(d) { return 4; })
            .attr('rx', function(d) { return 4; })
            .attr('width', function(d) { return getTextWidth(d.name); })
            .attr('height', function(d) { return 40; })
            .attr('class', function(d) {
              if (d.hashId != END_DEST) {
                return 'clickable';
              }
            })
            .style('stroke', 'black')
            .style('stroke-width', function(d) {
              if (d.hashId == initStateId || d.hashId == END_DEST) {
                return '3';
              }
              return '2'; })
            .style('fill', function(d) {
              if (d.hashId == initStateId) {
                return 'olive';
              } else if (d.hashId == END_DEST) {
                return 'green';
              } else if (d.reachable === false) {
                return 'pink';
              } else {
                return 'beige';
              }
            })
            .on('click', function (d) {
              if (d.hashId == END_DEST) {
                return;
              }
              explorationData.getStateData(d.hashId);
              scope.$parent.$parent.stateId = d.hashId;
              $('#editorViewTab a[href="#stateEditor"]').tab('show');
            })
            .append('svg:title')
            .text(function(d) { return d.name; });

        nodeEnter.append('svg:text')
            .attr('text-anchor', 'middle')
            .attr('dx', function(d) { return d.x0 + (getTextWidth(d.name) / 2); })
            .attr('dy', function(d) { return d.y0 + 25; })
            .text(function(d) { return scope.truncate(d.name); });

        // Add a 'delete node' handler.
        nodeEnter.append('svg:rect')
            .attr('y', function(d) { return d.y0; })
            .attr('x', function(d) { return d.x0; })
            .attr('height', 20)
            .attr('width', 20)
            .attr('opacity', 0) // comment out this line to see the delete target
            .attr('transform', function(d) {
              return 'translate(' + (getTextWidth(d.name) - 15) + ',' + (+0) + ')'; }
            )
            .attr('stroke-width', '0')
            .style('fill', 'pink')
            .on('click', function (d) {
              if (d.hashId == initStateId || d.hashId == END_DEST) {
                return;
              }
              scope.$parent.$parent.openDeleteStateModal(d.hashId);
            });

        nodeEnter.append('svg:text')
            .attr('text-anchor', 'right')
            .attr('dx', function(d) { return d.x0 + getTextWidth(d.name) -10; })
            .attr('dy', function(d) { return d.y0 + 10; })
            .text(function(d) {
              if (d.hashId == initStateId || d.hashId == END_DEST) {
                return;
              }
              return 'x';
            });
      });
    }
  };
});

/**
 * Injects dependencies in a way that is preserved by minification.
 */
EditorGraph.$inject = ['$scope', '$filter', 'explorationData'];
<|endoftext|>


<commit_before>var express = require("express");
var app = express();
var server = require("http").createServer(app);
var io = require("socket.io")(server);
var serveStatic = require("serve-static");
var request = require("request");
var progress = require("request-progress");
var fs = require("fs");
var uuid = require("node-uuid");
var winston = require("winston");

var logger = new (winston.Logger)({
	transports: [
		new (winston.transports.Console)()
	],
	levels: {
		"info": 0,
		"notable": 1,
		"warning": 2,
		"error": 3
	}
});

var downloading = {};				// The list of downloads
var downloadDir = "./download/";	// The directorie to download files to

// Make sure the download directorie exists
if(!fs.existsSync(downloadDir))
	fs.mkdirSync(downloadDir);

// Triggered when a client connects
io.on("connection", function(socket) {
	// Inform connecting clients about all downloads in the system
	for (var i in downloading) {
		socket.emit("in progress", {
			"name": downloading[i].name,
			"title": downloading[i].title,
			"progress": (downloading[i].status == "finished") ? 100 : downloading[i].state.percent, // If the download has finished just sent 100
			"status": downloading[i].status
		});
	}

	// Trigged when a client request that a download is initialized
	socket.on("download", function(data) {
		if (data == null || data.title == null || typeof data.title !== "string" || data.title.length <= 0 || data.url == null || typeof data.url !== "string" || data.url.length <= 0) {
			logger.log("warning", "invalid data was send with download request", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"data": data
			});
			return;
		}

		// Start the download
		var p = progress(request(data.url));

		p.name = uuid.v4();		// Reference name
		p.title = data.title;	// Filename
		p.status = "working";	// Initial status
		p.theUrl = data.url		// Url
		downloading[p.name] = p;// List the download for further reference

		// Sends out progress status when we get them
		p.on("progress", function (state) {
			io.emit("download progress", {
				"name": p.name,
				"progress": state.percent
			});
		});

		// Open a write stream for writing the downloaded file to disk
		var f = fs.createWriteStream(downloadDir + data.title);

		// Triggerd when when the stream is closed
		f.on("close", function (err) {
			if (p.status !== "aborted") {
				p.status = "finished";
				socket.emit("download status", {
					"name": p.name,
					"status": p.status
				});
			}
		});

		// Write downloaded data to the stream
		p.pipe(f);

		// Incase the download fails
		p.on("error", function (err) {
			p.status = "failed";
			socket.emit("download status", {
				"name": p.name,
				"status": p.status
			});
			logger.log("error", "download failed", {
				"filename": p.title,
				"url": p.theUrl,
				"startedBy": socket.handshake.address,
				"error": err
			});
		});

		// Info all clients that there is a new download
		io.emit("in progress", {
			"name": p.name,
			"title": p.title,
			"progress": 0,
			"status": p.status
		});

		logger.log("notable", "download started", {
			"connectionMethod": "socket.io",
			"clientIp": socket.handshake.address,
			"receivedData": data
		});
	});

	// Triggered when download is aborted
	socket.on("download abort", function(name) {
		var d = downloading[name];
		if (d === null || d == undefined) {
			logger.log("warning", "invalid name was send with abort request", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"undefined": name === undefined,
				"null": name === null
			});
			return;
		}
		if (d.status == "working") {
			d.abort();
			d.status = "aborted";
			io.emit("download status", {
				"name": name,
				"status": d.status
			});
			logger.log("notable", "download aborted", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.title
			});
		} else {
			logger.log("warning", "attempted to abort non-working download", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.title,
				"status": d.status
			});
		}
	});

	// Send from client to check if a file exists
	socket.on("exists", function(name) {
		fs.exists(downloadDir + name, function(exists) { //.replace("../", "")
			socket.emit("exists", {
				"exists": exists,
				"name": name
			});
		});
	});

	// Triggered when a client has request a download removed from the list of files
	socket.on("download remove", function(name) {
		var d = downloading[name];
		if (d === null || d == undefined) {
			logger.log("warning", "invalid name was send with remove request", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"undefined": name === undefined,
				"null": name === null
			});
			return;
		}
		if (d.status != "working") {
			delete downloading[name];
			io.emit("remove", name);
			logger.log("info", "download removed", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.title
			});
		} else {
			logger.log("warning", "attempted to remove working download", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.title,
				"status": d.status
			});
		}
	});

	logger.log("info", "socket client connected", {
		"clientIp": socket.handshake.address
	});
});

// Serves static files that a system specific
app.use("/", serveStatic(__dirname + "/public", {
	extension: ["html"],
	lastModified: true,
	dotfiles: "ignore"
}));

// Serves bower components
app.use("/bower_components", serveStatic(__dirname + "/bower_components", {
	extension: ["html"],
	lastModified: true,
	dotfiles: "ignore"
}));

//Start the server
server.listen(8080);
<commit_msg>Internal server refactoring<commit_after>var express = require("express");
var app = express();
var server = require("http").createServer(app);
var io = require("socket.io")(server);
var serveStatic = require("serve-static");
var request = require("request");
var progress = require("request-progress");
var fs = require("fs");
var uuid = require("node-uuid");
var winston = require("winston");

var logger = new (winston.Logger)({
	transports: [
		new (winston.transports.Console)()
	],
	levels: {
		"info": 0,
		"notable": 1,
		"warning": 2,
		"error": 3
	}
});

var downloading = {};				// The list of downloads
var downloadDir = "./download/";	// The directorie to download files to

// Make sure the download directorie exists
if(!fs.existsSync(downloadDir))
	fs.mkdirSync(downloadDir);

// Triggered when a client connects
io.on("connection", function(socket) {
	// Inform connecting clients about all downloads in the system
	for (var i in downloading) {
		socket.emit("in progress", {
			"name": downloading[i].id,
			"title": downloading[i].filename,
			"progress": (downloading[i].status == "finished") ? 100 : downloading[i].progress, // If the download has finished just sent 100
			"status": downloading[i].status
		});
	}

	// Trigged when a client request that a download is initialized
	socket.on("download", function(data) {
		if (data == null || data.title == null || typeof data.title !== "string" || data.title.length <= 0 || data.url == null || typeof data.url !== "string" || data.url.length <= 0) {
			logger.log("warning", "invalid data was send with download request", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"data": data
			});
			return;
		}

		// Start the download
		var d = {
			request: progress(request(data.url)),	// The Request object
			id: uuid.v4(),							// ID
			filename: data.title,					// Filename
			url: data.url,							// Url downloaded from
			status: "working",						// Initial status
			progress: 0,							// Percent downloaded
			startedBy: socket.handshake.address		// The ip who initiated the download
		}

		downloading[data.id] = d;// List the download for further reference

		// Sends out progress status when we get them
		d.request.on("progress", function (state) {
			d.progress = state.percent;
			io.emit("download progress", {
				"name": d.id,
				"progress": d.progress
			});
		});

		// Open a write stream for writing the downloaded file to disk
		var f = fs.createWriteStream(downloadDir + data.filename);

		// Triggerd when when the stream is closed
		f.on("close", function (err) {
			if (d.status !== "aborted") {
				d.status = "finished";
				socket.emit("download status", {
					"name": d.id,
					"status": d.status
				});
			}
		});

		// Write downloaded data to the stream
		d.request.pipe(f);

		// Incase the download fails
		d.request.on("error", function (err) {
			d.status = "failed";
			socket.emit("download status", {
				"name": d.id,
				"status": d.status
			});
			logger.log("error", "download failed", {
				"filename": d.filename,
				"url": d.url,
				"startedBy": d.startedBy,
				"error": err
			});
		});

		// Info all clients that there is a new download
		io.emit("in progress", {
			"name": d.id,
			"title": d.filename,
			"progress": d.progress,
			"status": d.status
		});

		logger.log("notable", "download started", {
			"connectionMethod": "socket.io",
			"clientIp": socket.handshake.address,
			"receivedData": data
		});
	});

	// Triggered when download is aborted
	socket.on("download abort", function(id) {
		var d = downloading[id];
		if (d === null || d == undefined) {
			logger.log("warning", "invalid name was send with abort request", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"undefined": id === undefined,
				"null": id === null
			});
			return;
		}
		if (d.status == "working") {
			d.request.abort();
			d.status = "aborted";
			io.emit("download status", {
				"name": id,
				"status": d.status
			});
			logger.log("notable", "download aborted", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.filename
			});
		} else {
			logger.log("warning", "attempted to abort non-working download", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.filename,
				"status": d.status
			});
		}
	});

	// Send from client to check if a file exists
	socket.on("exists", function(filename) {
		fs.exists(downloadDir + filename, function(exists) { //.replace("../", "")
			socket.emit("exists", {
				"exists": exists,
				"name": filename
			});
		});
	});

	// Triggered when a client has requested a download removed from the list of files
	socket.on("download remove", function(id) {
		var d = downloading[id];
		if (d === null || d == undefined) {
			logger.log("warning", "invalid name was send with remove request", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"undefined": name === undefined,
				"null": name === null
			});
			return;
		}
		if (d.status != "working") {
			delete downloading[id];
			io.emit("remove", id);
			logger.log("info", "download removed", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.filename
			});
		} else {
			logger.log("warning", "attempted to remove working download", {
				"connectionMethod": "socket.io",
				"clientIp": socket.handshake.address,
				"filename": d.filename,
				"status": d.status
			});
		}
	});

	logger.log("info", "socket client connected", {
		"clientIp": socket.handshake.address
	});
});

// Serves static files that a system specific
app.use("/", serveStatic(__dirname + "/public", {
	extension: ["html"],
	lastModified: true,
	dotfiles: "ignore"
}));

// Serves bower components
app.use("/bower_components", serveStatic(__dirname + "/bower_components", {
	extension: ["html"],
	lastModified: true,
	dotfiles: "ignore"
}));

//Start the server
server.listen(8080);
<|endoftext|>


<commit_before>const URL = require('url');
const QS = require('querystring');
const Config = require('../config');

const INIT = Symbol('INIT');

const writableProperties = ['enabled', 'disabled', 'weight'];

class Provider {
  constructor(optionsString) {
    this.enabled = true;
    this.disabled = false;

    this.weight = Config.getDubboConfig().weight;

    this[INIT](optionsString);
  }

  [INIT](optionsString) {
    let optionUrl = URL.parse(optionsString);
    let query = QS.parse(optionUrl.query);

    this.host = optionUrl.host;
    this.hostname = optionUrl.hostname;
    this.port = optionUrl.port;
    this.protocol = optionUrl.protocol.replace(/:/, '');

    this.methods = new Set(query.methods.split(','));
    this.dubbo = Object.assign({}, query);
  }

  override(options) {
    Object.keys(options).forEach((key) => {
      if (writableProperties.includes(key)) {
        this[key] = options[key];
      }
    });
  }

  hasMethod(method) {
    return this.methods && this.methods.has(method);
  }

  resume() {
    this.enabled = true;
    this.disabled = false;
  }

  canUse() {
    return this.enabled && !this.disabled;
  }

  toString() {
    return this.host;
  }
}

module.exports = Provider;
<commit_msg>provider配置覆盖的时候对配置数据的数据类型进行转换.<commit_after>const URL = require('url');
const QS = require('querystring');
const Config = require('../config');

const INIT = Symbol('INIT');

const writableProperties = {
  enabled: (value) => value === 'true',
  disabled: (value) => value === 'true',
  weight: (value) => parseInt(value),
};

class Provider {
  constructor(optionsString) {
    this.enabled = true;
    this.disabled = false;

    this.weight = Config.getDubboConfig().weight;

    this[INIT](optionsString);
  }

  [INIT](optionsString) {
    let optionUrl = URL.parse(optionsString);
    let query = QS.parse(optionUrl.query);

    this.host = optionUrl.host;
    this.hostname = optionUrl.hostname;
    this.port = optionUrl.port;
    this.protocol = optionUrl.protocol.replace(/:/, '');

    this.methods = new Set(query.methods.split(','));
    this.dubbo = Object.assign({}, query);
  }

  override(options) {
    Object.keys(options).forEach((key) => {
      const typeConverter = writableProperties[key];
      if (typeConverter) {
        this[key] = typeConverter(options[key]);
      }
    });
  }

  hasMethod(method) {
    return this.methods && this.methods.has(method);
  }

  resume() {
    this.enabled = true;
    this.disabled = false;
  }

  canUse() {
    return this.enabled && !this.disabled;
  }

  toString() {
    return this.host;
  }
}

module.exports = Provider;
<|endoftext|>