<commit_before>"use strict";

const co = require('co');
const path = require('path');
const util = require('util');
const stream = require('stream');
const _ = require('underscore');
const Server = require('./server');
const directory = require('./app/lib/system/directory');
const constants = require('./app/lib/constants');
const wizard = require('./app/lib/wizard');
const logger = require('./app/lib/logger')('duniter');

const configDependency    = require('./app/modules/config');
const wizardDependency    = require('./app/modules/wizard');
const resetDependency     = require('./app/modules/reset');
const checkConfDependency = require('./app/modules/check-config');
const exportBcDependency  = require('./app/modules/export-bc');
const reapplyDependency   = require('./app/modules/reapply');
const revertDependency    = require('./app/modules/revert');
const daemonDependency    = require('./app/modules/daemon');
const pSignalDependency   = require('./app/modules/peersignal');
const routerDependency    = require('./app/modules/router');
const pluginDependency    = require('./app/modules/plugin');

const MINIMAL_DEPENDENCIES = [
  { name: 'duniter-config',    required: configDependency }
];

const DEFAULT_DEPENDENCIES = MINIMAL_DEPENDENCIES.concat([
  { name: 'duniter-wizard',    required: wizardDependency },
  { name: 'duniter-reset',     required: resetDependency },
  { name: 'duniter-chkconf',   required: checkConfDependency },
  { name: 'duniter-exportbc',  required: exportBcDependency },
  { name: 'duniter-reapply',   required: reapplyDependency },
  { name: 'duniter-revert',    required: revertDependency },
  { name: 'duniter-daemon',    required: daemonDependency },
  { name: 'duniter-psignal',   required: pSignalDependency },
  { name: 'duniter-router',    required: routerDependency },
  { name: 'duniter-plugin',    required: pluginDependency }
]);

const PRODUCTION_DEPENDENCIES = DEFAULT_DEPENDENCIES.concat([
]);

module.exports = function (home, memory, overConf) {
  return new Server(home, memory, overConf);
};

module.exports.statics = {

  logger: logger,

  /**
   * Creates a new stack with minimal registrations only.
   */
  minimalStack: () => new Stack(MINIMAL_DEPENDENCIES),

  /**
   * Creates a new stack with core registrations only.
   */
  simpleStack: () => new Stack(DEFAULT_DEPENDENCIES),

  /**
   * Creates a new stack pre-registered with compliant modules found in package.json
   */
  autoStack: (priorityModules) => {
    const duniterModules = [];
    let duniterDeps = []
    try {
      const pjson = require(path.resolve('./package.json'))
      // Look for compliant packages
      const prodDeps = Object.keys(pjson.dependencies || {});
      const devDeps = Object.keys(pjson.devDependencies || {});
      duniterDeps = prodDeps.concat(devDeps)
    } catch (e) { /* duniter as a dependency might not be run from an NPM project */ }
    for(const dep of duniterDeps) {
      try {
        const required = require(dep);
        if (required.duniter) {
          duniterModules.push({
            name: dep,
            required
          });
        }
      } catch (e) { /* Silent errors for packages that fail to load */ }
    }

    // The final stack
    return new Stack((priorityModules || []).concat(PRODUCTION_DEPENDENCIES).concat(duniterModules));
  },

  quickRun: function() {
    const deps = Array.from(arguments).map((f, index) => {
      const canonicalPath = path.resolve(f)
      return {
        name: 'duniter-quick-module-' + index,
        required: require(canonicalPath)
      }
    })
    const that = this
    const stack = this.autoStack(deps)
    return co(function*() {
      let res
      try {
        res = yield stack.executeStack(that.quickRunGetArgs())
      } catch(e) {
        console.error(e)
      }
      that.onRunDone()
      return res
    })
  },

  quickRunGetArgs: () => process.argv.slice(),
  onRunDone: () => process.exit()
};

function Stack(dependencies) {

  const that = this;
  const cli = require('./app/cli')();
  const configLoadingCallbacks = [];
  const configBeforeSaveCallbacks = [];
  const resetDataHooks = [];
  const resetConfigHooks = [];
  const INPUT = new InputStream();
  const PROCESS = new ProcessStream();
  const loaded = {};
  const wizardTasks = {};

  const definitions = [];
  const streams = {
    input: [],
    process: [],
    output: [],
    neutral: []
  };

  // Part of modules API
  this.getModule = (name) => loaded[name]

  this.registerDependency = (requiredObject, name) => {
    if (name && loaded[name]) {
      // Do not try to load it twice
      return;
    }
    loaded[name] = requiredObject;
    const def = requiredObject.duniter;
    definitions.push(def);
    for (const opt of (def.cliOptions || [])) {
      cli.addOption(opt.value, opt.desc, opt.parser);
    }
    for (const command of (def.cli || [])) {
      cli.addCommand({
        name: command.name,
        desc: command.desc
      }, (...args) => that.processCommand.apply(null, [command].concat(args)));
    }

    /**
     * Configuration injection
     * -----------------------
     */
    if (def.config) {
      if (def.config.onLoading) {
        configLoadingCallbacks.push(def.config.onLoading);
      }
      // Before the configuration is saved, the module can make some injection/cleaning
      if (def.config.beforeSave) {
        configBeforeSaveCallbacks.push(def.config.beforeSave);
      }
    }

    /**
     * Reset data/config injection
     * -----------------------
     */
    if (def.onReset) {
      if (def.onReset.data) {
        resetDataHooks.push(def.onReset.data);
      }
      // Before the configuration is saved, the module can make some injection/cleaning
      if (def.onReset.config) {
        resetConfigHooks.push(def.onReset.config);
      }
    }

    /**
     * Wizard injection
     * -----------------------
     */
    if (def.wizard) {
      const tasks = Object.keys(def.wizard);
      for (const name of tasks) {
        wizardTasks[name] = def.wizard[name];
      }
    }
  };

  this.processCommand = (...args) => co(function*() {
    const command = args[0];
    const program = args[1];
    const params  = args.slice(2);
    params.pop(); // Don't need the command argument

    const dbName = program.mdb;
    const dbHome = program.home;
    const home = directory.getHome(dbName, dbHome);

    if (command.logs === false) {
      logger.mute();
    }

    // Add log files for this instance
    logger.addHomeLogs(home, program.loglevel);

    const server = new Server(home, program.memory === true, commandLineConf(program));

    // If ever the process gets interrupted
    let isSaving = false;
    process.on('SIGINT', () => {
      co(function*() {
        if (!isSaving) {
          isSaving = true;
          // Save DB
          try {
            yield server.disconnect();
            process.exit();
          } catch (e) {
            logger.error(e);
            process.exit(3);
          }
        }
      });
    });

    // Config or Data reset hooks
    server.resetDataHook = () => co(function*() {
      for (const callback of resetDataHooks) {
        yield callback(server.conf, program, logger, server.dal.confDAL);
      }
    })
    server.resetConfigHook = () => co(function*() {
      for (const callback of resetConfigHooks) {
        yield callback(server.conf, program, logger, server.dal.confDAL);
      }
    })

    // Initialize server (db connection, ...)
    try {
      server.onPluggedFSHook = () => co(function*() {

        // Register the configuration hook for loading phase (overrides the loaded data)
        server.dal.loadConfHook = (conf) => co(function*() {
          // Loading injection
          for (const callback of configLoadingCallbacks) {
            yield callback(conf, program, logger, server.dal.confDAL);
          }
        });

        // Register the configuration hook for saving phase (overrides the saved data)
        server.dal.saveConfHook = (conf) => co(function*() {
          const clonedConf = _.clone(conf);
          for (const callback of configBeforeSaveCallbacks) {
            yield callback(clonedConf, program, logger, server.dal.confDAL);
          }
          return clonedConf;
        });
      })
      yield server.plugFileSystem();

      const conf = yield server.loadConf();

      // Eventually change the log level
      logger.addHomeLogs(home, conf.loglevel);

      // Auto-configuration default
      yield configure(program, server, server.conf || {});
      // Autosave conf
      try {
        yield server.dal.saveConf(conf);
        logger.debug("Configuration saved.");
      } catch (e) {
        logger.error("Configuration could not be saved: " + e);
        throw Error(e);
      }

      const daemon = server.getDaemon()
      if (command.preventIfRunning && daemon.status()) {
        throw 'Your node is currently running. Please stop it and relaunch your command.'
      }

      // First possible class of commands: post-config
      if (command.onConfiguredExecute) {
        return yield command.onConfiguredExecute(server, conf, program, params, wizardTasks, that);
      }
      // Second possible class of commands: post-service
      yield server.initDAL(conf);

      /**
       * Service injection
       * -----------------
       */
      for (const def of definitions) {
        if (def.service) {
          // To feed data coming from some I/O (network, disk, other module, ...)
          if (def.service.input) {
            streams.input.push(def.service.input(server, conf, logger));
          }
          // To handle data that has been submitted by INPUT stream
          if (def.service.process) {
            streams.process.push(def.service.process(server, conf, logger));
          }
          // To handle data that has been validated by PROCESS stream
          if (def.service.output) {
            streams.output.push(def.service.output(server, conf, logger));
          }
          // Special service which does not stream anything particular (ex.: piloting the `server` object)
          if (def.service.neutral) {
            streams.neutral.push(def.service.neutral(server, conf, logger));
          }
        }
      }
      // All inputs write to global INPUT stream
      for (const module of streams.input) module.pipe(INPUT);
      // All processes read from global INPUT stream
      for (const module of streams.process) INPUT.pipe(module);
      // All processes write to global PROCESS stream
      for (const module of streams.process) module.pipe(PROCESS);
      // All ouputs read from global PROCESS stream
      for (const module of streams.output) PROCESS.pipe(module);

      return yield command.onDatabaseExecute(server, conf, program, params,

        // Start services and streaming between them
        () => co(function*() {
          // Any streaming module must implement a `startService` method
          for (const m of streams.input) {
            yield m.startService();
          }
          const modules = [].concat(streams.process).concat(streams.output).concat(streams.neutral);
          yield modules.map(module => module.startService());
        }),

        // Stop services and streaming between them
        () => co(function*() {
          const modules = streams.input.concat(streams.process).concat(streams.output);
          // Any streaming module must implement a `stopService` method
          yield modules.map(module => module.stopService());
          // // Stop reading inputs
          // for (const module of streams.input) module.unpipe();
          // Stop reading from global INPUT
          // INPUT.unpipe();
          // for (const module of streams.process) module.unpipe();
          // // Stop reading from global PROCESS
          // PROCESS.unpipe();
        }), that);
    } catch (e) {
      server.disconnect();
      throw e;
    }
  });

  this.executeStack = (argv) => {

    // Trace these errors
    process.on('unhandledRejection', (reason) => {
      logger.error('Unhandled rejection: ' + reason);
      logger.error(reason);
    });

    // Executes the command
    return cli.execute(argv);
  };

  // We register the initial dependencies right now. Others can be added thereafter.
  for (const dep of dependencies) {
    that.registerDependency(dep.required, dep.name);
  }
}

function commandLineConf(program, conf) {

  conf = conf || {};
  conf.sync = conf.sync || {};
  const cli = {
    currency: program.currency,
    cpu: program.cpu,
    server: {
      port: program.port,
    },
    db: {
      mport: program.mport,
      mdb: program.mdb,
      home: program.home
    },
    logs: {
      http: program.httplogs,
      nohttp: program.nohttplogs
    },
    endpoints: [],
    rmEndpoints: [],
    isolate: program.isolate,
    forksize: program.forksize,
    nofork: program.nofork,
    timeout: program.timeout
  };

  // Update conf
  if (cli.currency)                         conf.currency = cli.currency;
  if (cli.server.port)                      conf.port = cli.server.port;
  if (cli.cpu)                              conf.cpu = Math.max(0.01, Math.min(1.0, cli.cpu));
  if (cli.logs.http)                        conf.httplogs = true;
  if (cli.logs.nohttp)                      conf.httplogs = false;
  if (cli.db.mport)                         conf.mport = cli.db.mport;
  if (cli.db.home)                          conf.home = cli.db.home;
  if (cli.db.mdb)                           conf.mdb = cli.db.mdb;
  if (cli.isolate)                          conf.isolate = cli.isolate;
  if (cli.timeout)                          conf.timeout = cli.timeout;
  if (cli.forksize != null)                 conf.forksize = cli.forksize;

  return conf;
}

function configure(program, server, conf) {
  return co(function *() {
    if (typeof server == "string" || typeof conf == "string") {
      throw constants.ERRORS.CLI_CALLERR_CONFIG;
    }
    // Try to add an endpoint if provided
    if (program.addep) {
      if (conf.endpoints.indexOf(program.addep) === -1) {
        conf.endpoints.push(program.addep);
      }
      // Remove it from "to be removed" list
      const indexInRemove = conf.rmEndpoints.indexOf(program.addep);
      if (indexInRemove !== -1) {
        conf.rmEndpoints.splice(indexInRemove, 1);
      }
    }
    // Try to remove an endpoint if provided
    if (program.remep) {
      if (conf.rmEndpoints.indexOf(program.remep) === -1) {
        conf.rmEndpoints.push(program.remep);
      }
      // Remove it from "to be added" list
      const indexInToAdd = conf.endpoints.indexOf(program.remep);
      if (indexInToAdd !== -1) {
        conf.endpoints.splice(indexInToAdd, 1);
      }
    }
  });
}

/**
 * InputStream is a special stream that filters what passes in.
 * Only DUP-like documents should be treated by the processing tools, to avoid JSON injection and save CPU cycles.
 * @constructor
 */
function InputStream() {

  const that = this;

  stream.Transform.call(this, { objectMode: true });

  this._write = function (str, enc, done) {
    if (typeof str === 'string') {
      // Keep only strings
      const matches = str.match(/Type: (.*)\n/);
      if (matches && matches[1].match(/(Block|Membership|Identity|Certification|Transaction|Peer)/)) {
        const type = matches[1].toLowerCase();
        that.push({ type, doc: str });
      }
    }
    done && done();
  };
}

function ProcessStream() {

  const that = this;

  stream.Transform.call(this, { objectMode: true });

  this._write = function (obj, enc, done) {
    // Never close the stream
    if (obj !== undefined && obj !== null) {
      that.push(obj);
    }
    done && done();
  };
}

util.inherits(InputStream, stream.Transform);
util.inherits(ProcessStream, stream.Transform);
<commit_msg>[fix] `prover` module was not plugged in<commit_after>"use strict";

const co = require('co');
const path = require('path');
const util = require('util');
const stream = require('stream');
const _ = require('underscore');
const Server = require('./server');
const directory = require('./app/lib/system/directory');
const constants = require('./app/lib/constants');
const wizard = require('./app/lib/wizard');
const logger = require('./app/lib/logger')('duniter');

const configDependency    = require('./app/modules/config');
const wizardDependency    = require('./app/modules/wizard');
const resetDependency     = require('./app/modules/reset');
const checkConfDependency = require('./app/modules/check-config');
const exportBcDependency  = require('./app/modules/export-bc');
const reapplyDependency   = require('./app/modules/reapply');
const revertDependency    = require('./app/modules/revert');
const daemonDependency    = require('./app/modules/daemon');
const pSignalDependency   = require('./app/modules/peersignal');
const routerDependency    = require('./app/modules/router');
const pluginDependency    = require('./app/modules/plugin');
const proverDependency    = require('./app/modules/prover');

const MINIMAL_DEPENDENCIES = [
  { name: 'duniter-config',    required: configDependency }
];

const DEFAULT_DEPENDENCIES = MINIMAL_DEPENDENCIES.concat([
  { name: 'duniter-wizard',    required: wizardDependency },
  { name: 'duniter-reset',     required: resetDependency },
  { name: 'duniter-chkconf',   required: checkConfDependency },
  { name: 'duniter-exportbc',  required: exportBcDependency },
  { name: 'duniter-reapply',   required: reapplyDependency },
  { name: 'duniter-revert',    required: revertDependency },
  { name: 'duniter-daemon',    required: daemonDependency },
  { name: 'duniter-psignal',   required: pSignalDependency },
  { name: 'duniter-router',    required: routerDependency },
  { name: 'duniter-plugin',    required: pluginDependency },
  { name: 'duniter-prover',    required: proverDependency }
]);

const PRODUCTION_DEPENDENCIES = DEFAULT_DEPENDENCIES.concat([
]);

module.exports = function (home, memory, overConf) {
  return new Server(home, memory, overConf);
};

module.exports.statics = {

  logger: logger,

  /**
   * Creates a new stack with minimal registrations only.
   */
  minimalStack: () => new Stack(MINIMAL_DEPENDENCIES),

  /**
   * Creates a new stack with core registrations only.
   */
  simpleStack: () => new Stack(DEFAULT_DEPENDENCIES),

  /**
   * Creates a new stack pre-registered with compliant modules found in package.json
   */
  autoStack: (priorityModules) => {
    const duniterModules = [];
    let duniterDeps = []
    try {
      const pjson = require(path.resolve('./package.json'))
      // Look for compliant packages
      const prodDeps = Object.keys(pjson.dependencies || {});
      const devDeps = Object.keys(pjson.devDependencies || {});
      duniterDeps = prodDeps.concat(devDeps)
    } catch (e) { /* duniter as a dependency might not be run from an NPM project */ }
    for(const dep of duniterDeps) {
      try {
        const required = require(dep);
        if (required.duniter) {
          duniterModules.push({
            name: dep,
            required
          });
        }
      } catch (e) { /* Silent errors for packages that fail to load */ }
    }

    // The final stack
    return new Stack((priorityModules || []).concat(PRODUCTION_DEPENDENCIES).concat(duniterModules));
  },

  quickRun: function() {
    const deps = Array.from(arguments).map((f, index) => {
      const canonicalPath = path.resolve(f)
      return {
        name: 'duniter-quick-module-' + index,
        required: require(canonicalPath)
      }
    })
    const that = this
    const stack = this.autoStack(deps)
    return co(function*() {
      let res
      try {
        res = yield stack.executeStack(that.quickRunGetArgs())
      } catch(e) {
        console.error(e)
      }
      that.onRunDone()
      return res
    })
  },

  quickRunGetArgs: () => process.argv.slice(),
  onRunDone: () => process.exit()
};

function Stack(dependencies) {

  const that = this;
  const cli = require('./app/cli')();
  const configLoadingCallbacks = [];
  const configBeforeSaveCallbacks = [];
  const resetDataHooks = [];
  const resetConfigHooks = [];
  const INPUT = new InputStream();
  const PROCESS = new ProcessStream();
  const loaded = {};
  const wizardTasks = {};

  const definitions = [];
  const streams = {
    input: [],
    process: [],
    output: [],
    neutral: []
  };

  // Part of modules API
  this.getModule = (name) => loaded[name]

  this.registerDependency = (requiredObject, name) => {
    if (name && loaded[name]) {
      // Do not try to load it twice
      return;
    }
    loaded[name] = requiredObject;
    const def = requiredObject.duniter;
    definitions.push(def);
    for (const opt of (def.cliOptions || [])) {
      cli.addOption(opt.value, opt.desc, opt.parser);
    }
    for (const command of (def.cli || [])) {
      cli.addCommand({
        name: command.name,
        desc: command.desc
      }, (...args) => that.processCommand.apply(null, [command].concat(args)));
    }

    /**
     * Configuration injection
     * -----------------------
     */
    if (def.config) {
      if (def.config.onLoading) {
        configLoadingCallbacks.push(def.config.onLoading);
      }
      // Before the configuration is saved, the module can make some injection/cleaning
      if (def.config.beforeSave) {
        configBeforeSaveCallbacks.push(def.config.beforeSave);
      }
    }

    /**
     * Reset data/config injection
     * -----------------------
     */
    if (def.onReset) {
      if (def.onReset.data) {
        resetDataHooks.push(def.onReset.data);
      }
      // Before the configuration is saved, the module can make some injection/cleaning
      if (def.onReset.config) {
        resetConfigHooks.push(def.onReset.config);
      }
    }

    /**
     * Wizard injection
     * -----------------------
     */
    if (def.wizard) {
      const tasks = Object.keys(def.wizard);
      for (const name of tasks) {
        wizardTasks[name] = def.wizard[name];
      }
    }
  };

  this.processCommand = (...args) => co(function*() {
    const command = args[0];
    const program = args[1];
    const params  = args.slice(2);
    params.pop(); // Don't need the command argument

    const dbName = program.mdb;
    const dbHome = program.home;
    const home = directory.getHome(dbName, dbHome);

    if (command.logs === false) {
      logger.mute();
    }

    // Add log files for this instance
    logger.addHomeLogs(home, program.loglevel);

    const server = new Server(home, program.memory === true, commandLineConf(program));

    // If ever the process gets interrupted
    let isSaving = false;
    process.on('SIGINT', () => {
      co(function*() {
        if (!isSaving) {
          isSaving = true;
          // Save DB
          try {
            yield server.disconnect();
            process.exit();
          } catch (e) {
            logger.error(e);
            process.exit(3);
          }
        }
      });
    });

    // Config or Data reset hooks
    server.resetDataHook = () => co(function*() {
      for (const callback of resetDataHooks) {
        yield callback(server.conf, program, logger, server.dal.confDAL);
      }
    })
    server.resetConfigHook = () => co(function*() {
      for (const callback of resetConfigHooks) {
        yield callback(server.conf, program, logger, server.dal.confDAL);
      }
    })

    // Initialize server (db connection, ...)
    try {
      server.onPluggedFSHook = () => co(function*() {

        // Register the configuration hook for loading phase (overrides the loaded data)
        server.dal.loadConfHook = (conf) => co(function*() {
          // Loading injection
          for (const callback of configLoadingCallbacks) {
            yield callback(conf, program, logger, server.dal.confDAL);
          }
        });

        // Register the configuration hook for saving phase (overrides the saved data)
        server.dal.saveConfHook = (conf) => co(function*() {
          const clonedConf = _.clone(conf);
          for (const callback of configBeforeSaveCallbacks) {
            yield callback(clonedConf, program, logger, server.dal.confDAL);
          }
          return clonedConf;
        });
      })
      yield server.plugFileSystem();

      const conf = yield server.loadConf();

      // Eventually change the log level
      logger.addHomeLogs(home, conf.loglevel);

      // Auto-configuration default
      yield configure(program, server, server.conf || {});
      // Autosave conf
      try {
        yield server.dal.saveConf(conf);
        logger.debug("Configuration saved.");
      } catch (e) {
        logger.error("Configuration could not be saved: " + e);
        throw Error(e);
      }

      const daemon = server.getDaemon()
      if (command.preventIfRunning && daemon.status()) {
        throw 'Your node is currently running. Please stop it and relaunch your command.'
      }

      // First possible class of commands: post-config
      if (command.onConfiguredExecute) {
        return yield command.onConfiguredExecute(server, conf, program, params, wizardTasks, that);
      }
      // Second possible class of commands: post-service
      yield server.initDAL(conf);

      /**
       * Service injection
       * -----------------
       */
      for (const def of definitions) {
        if (def.service) {
          // To feed data coming from some I/O (network, disk, other module, ...)
          if (def.service.input) {
            streams.input.push(def.service.input(server, conf, logger));
          }
          // To handle data that has been submitted by INPUT stream
          if (def.service.process) {
            streams.process.push(def.service.process(server, conf, logger));
          }
          // To handle data that has been validated by PROCESS stream
          if (def.service.output) {
            streams.output.push(def.service.output(server, conf, logger));
          }
          // Special service which does not stream anything particular (ex.: piloting the `server` object)
          if (def.service.neutral) {
            streams.neutral.push(def.service.neutral(server, conf, logger));
          }
        }
      }
      // All inputs write to global INPUT stream
      for (const module of streams.input) module.pipe(INPUT);
      // All processes read from global INPUT stream
      for (const module of streams.process) INPUT.pipe(module);
      // All processes write to global PROCESS stream
      for (const module of streams.process) module.pipe(PROCESS);
      // All ouputs read from global PROCESS stream
      for (const module of streams.output) PROCESS.pipe(module);

      return yield command.onDatabaseExecute(server, conf, program, params,

        // Start services and streaming between them
        () => co(function*() {
          // Any streaming module must implement a `startService` method
          for (const m of streams.input) {
            yield m.startService();
          }
          const modules = [].concat(streams.process).concat(streams.output).concat(streams.neutral);
          yield modules.map(module => module.startService());
        }),

        // Stop services and streaming between them
        () => co(function*() {
          const modules = streams.input.concat(streams.process).concat(streams.output);
          // Any streaming module must implement a `stopService` method
          yield modules.map(module => module.stopService());
          // // Stop reading inputs
          // for (const module of streams.input) module.unpipe();
          // Stop reading from global INPUT
          // INPUT.unpipe();
          // for (const module of streams.process) module.unpipe();
          // // Stop reading from global PROCESS
          // PROCESS.unpipe();
        }), that);
    } catch (e) {
      server.disconnect();
      throw e;
    }
  });

  this.executeStack = (argv) => {

    // Trace these errors
    process.on('unhandledRejection', (reason) => {
      logger.error('Unhandled rejection: ' + reason);
      logger.error(reason);
    });

    // Executes the command
    return cli.execute(argv);
  };

  // We register the initial dependencies right now. Others can be added thereafter.
  for (const dep of dependencies) {
    that.registerDependency(dep.required, dep.name);
  }
}

function commandLineConf(program, conf) {

  conf = conf || {};
  conf.sync = conf.sync || {};
  const cli = {
    currency: program.currency,
    cpu: program.cpu,
    server: {
      port: program.port,
    },
    db: {
      mport: program.mport,
      mdb: program.mdb,
      home: program.home
    },
    logs: {
      http: program.httplogs,
      nohttp: program.nohttplogs
    },
    endpoints: [],
    rmEndpoints: [],
    isolate: program.isolate,
    forksize: program.forksize,
    nofork: program.nofork,
    timeout: program.timeout
  };

  // Update conf
  if (cli.currency)                         conf.currency = cli.currency;
  if (cli.server.port)                      conf.port = cli.server.port;
  if (cli.cpu)                              conf.cpu = Math.max(0.01, Math.min(1.0, cli.cpu));
  if (cli.logs.http)                        conf.httplogs = true;
  if (cli.logs.nohttp)                      conf.httplogs = false;
  if (cli.db.mport)                         conf.mport = cli.db.mport;
  if (cli.db.home)                          conf.home = cli.db.home;
  if (cli.db.mdb)                           conf.mdb = cli.db.mdb;
  if (cli.isolate)                          conf.isolate = cli.isolate;
  if (cli.timeout)                          conf.timeout = cli.timeout;
  if (cli.forksize != null)                 conf.forksize = cli.forksize;

  return conf;
}

function configure(program, server, conf) {
  return co(function *() {
    if (typeof server == "string" || typeof conf == "string") {
      throw constants.ERRORS.CLI_CALLERR_CONFIG;
    }
    // Try to add an endpoint if provided
    if (program.addep) {
      if (conf.endpoints.indexOf(program.addep) === -1) {
        conf.endpoints.push(program.addep);
      }
      // Remove it from "to be removed" list
      const indexInRemove = conf.rmEndpoints.indexOf(program.addep);
      if (indexInRemove !== -1) {
        conf.rmEndpoints.splice(indexInRemove, 1);
      }
    }
    // Try to remove an endpoint if provided
    if (program.remep) {
      if (conf.rmEndpoints.indexOf(program.remep) === -1) {
        conf.rmEndpoints.push(program.remep);
      }
      // Remove it from "to be added" list
      const indexInToAdd = conf.endpoints.indexOf(program.remep);
      if (indexInToAdd !== -1) {
        conf.endpoints.splice(indexInToAdd, 1);
      }
    }
  });
}

/**
 * InputStream is a special stream that filters what passes in.
 * Only DUP-like documents should be treated by the processing tools, to avoid JSON injection and save CPU cycles.
 * @constructor
 */
function InputStream() {

  const that = this;

  stream.Transform.call(this, { objectMode: true });

  this._write = function (str, enc, done) {
    if (typeof str === 'string') {
      // Keep only strings
      const matches = str.match(/Type: (.*)\n/);
      if (matches && matches[1].match(/(Block|Membership|Identity|Certification|Transaction|Peer)/)) {
        const type = matches[1].toLowerCase();
        that.push({ type, doc: str });
      }
    }
    done && done();
  };
}

function ProcessStream() {

  const that = this;

  stream.Transform.call(this, { objectMode: true });

  this._write = function (obj, enc, done) {
    // Never close the stream
    if (obj !== undefined && obj !== null) {
      that.push(obj);
    }
    done && done();
  };
}

util.inherits(InputStream, stream.Transform);
util.inherits(ProcessStream, stream.Transform);
<|endoftext|>


<commit_before>/*

 Elysium

 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eu quam tellus. Ut scelerisque justo eget nunc congue tristique. Fusce blandit arcu neque. Donec rutrum, dui eget condimentum elementum, eros enim dapibus leo, at lobortis nisi ante vel est. Curabitur faucibus rhoncus enim eget malesuada. Aenean libero felis, rhoncus a purus a, laoreet pellentesque arcu.

*/

function cardAdd(cardData) //object=parsed JSON
{
	var cardString
	cardString="
"
	if (cardData.url != "")
	{
		cardString =cardString+ ""
	}
	cardString=cardString+"
"
	cardString=cardString+ "
"
	cardString=cardString+ "
 " + cardData.title + "
"
	if (cardData.url != "")
	{
		cardString=cardString+ ""
	}
	cardString=cardString+ "
Relevancy Score: " + cardData.score + "
"
	if (cardData.postcode != "" && cardData.postcode != null)
	{
		cardString=cardString+ "
Postcode: " + cardData.postcode + "
"
	}
	switch(cardData.type)
	{

		case TYPE_CINEMA:
			if (cardData.showings != undefined)
			{
				cardString=cardString+ "
Showings:
"
				$.each(cardData.showings,function(index,movie)
				{
					cardString=cardString+ "
"+movie.title+"
"
					if (movie.time!=null)
					{
						$.each(movie.time,function(_,movietime)
						{
							cardString=cardString+"
-"+movietime+"
"
						})
					}
				})
			}

			break

		default:

	}
	cardString=cardString+"

"
	var newCard=$(cardString)
	$("#cardcontainer").append(newCard)
}
<commit_msg>removed relevancy score by request<commit_after>/*

 Elysium

 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eu quam tellus. Ut scelerisque justo eget nunc congue tristique. Fusce blandit arcu neque. Donec rutrum, dui eget condimentum elementum, eros enim dapibus leo, at lobortis nisi ante vel est. Curabitur faucibus rhoncus enim eget malesuada. Aenean libero felis, rhoncus a purus a, laoreet pellentesque arcu.

*/

function cardAdd(cardData) //object=parsed JSON
{
	var cardString
	cardString="
"
	if (cardData.url != "")
	{
		cardString =cardString+ ""
	}
	cardString=cardString+"
"
	cardString=cardString+ "
"
	cardString=cardString+ "
 " + cardData.title + "
"
	if (cardData.url != "")
	{
		cardString=cardString+ ""
	}
	//cardString=cardString+ "
Relevancy Score: " + cardData.score + "
"
	if (cardData.postcode != "" && cardData.postcode != null)
	{
		cardString=cardString+ "
Postcode: " + cardData.postcode + "
"
	}
	switch(cardData.type)
	{

		case TYPE_CINEMA:
			if (cardData.showings != undefined)
			{
				cardString=cardString+ "
Showings:
"
				$.each(cardData.showings,function(index,movie)
				{
					cardString=cardString+ "
"+movie.title+"
"
					if (movie.time!=null)
					{
						$.each(movie.time,function(_,movietime)
						{
							cardString=cardString+"
-"+movietime+"
"
						})
					}
				})
			}

			break

		default:

	}
	cardString=cardString+"

"
	var newCard=$(cardString)
	$("#cardcontainer").append(newCard)
}
<|endoftext|>


<commit_before>var yaml = require('yamljs');
var request = require('request');
var fs = require('fs');
var validUrl = require('valid-url');
var async = require('async');
var _ = require('lodash');
var path = require('path');

exports.parse = parse;
exports.merge = function(pathtoyml, cb) {
	parse(pathtoyml, function() {

	});
}

function toFullname(ymlobj, prop, namespace) {
	if (ymlobj[prop] == undefined) {
		return;
	}
	var newprop = [];
	for (var i in ymlobj[prop]) {
		var propitem = ymlobj[prop][i];
		if (propitem == undefined) continue;

		var newpropitem = '';
		var propitems = propitem.split(':');
		if (propitems.length === 2) {
			newpropitem = `${namespace}.${propitems[0]}:${propitems[1]}`;
		} else {
			newpropitem = `${namespace}.${propitems[0]}:${propitems[0]}`;
		}

		newprop.push(newpropitem);
	}
	ymlobj[prop] = newprop;

}

function parse(pathtoyml, cb, currentPath) {
	if (validUrl.isUri(pathtoyml)) {
		request(pathtoyml, function(err, response, body) {
			parseYml(body);
		});
	}
	else {
		var absolutePath = !currentPath ? path.resolve(pathtoyml) : path.resolve(currentPath, pathtoyml);

		fs.readFile(absolutePath, 'utf8', function(err, data) {
			if (err) throw err;
			currentPath = path.dirname(absolutePath);
			parseYml(data);
		});
	}

	function parseYml(content) {
		var ymlobj = yaml.parse(content);
		var namespaceMap = ymlobj.includes;

		if (ymlobj.includes == undefined) {
			cb(ymlobj);
			return;
		}

		async.filter(Object.keys(ymlobj.includes), function(namespace, callback) {
			parse(ymlobj.includes[namespace], function(childymlobj) {
				var childServices = childymlobj.services;
				var services = {};
				_.map(Object.keys(ymlobj.services), function(servicename) {
					services[servicename] = ymlobj.services[servicename];
					//			toFullname(services[servicename], 'links', namespace);
				});

				if (childServices == undefined) {
					callback(services);
					return;
				}

				_.map(Object.keys(childServices), function(servicename) {
					if (services[`${namespace}.${servicename}`] != undefined) {
						toFullname(childServices[servicename], 'links', namespace);

						merge(childServices[servicename], services[`${namespace}.${servicename}`]);
					}

					services[`${namespace}.${servicename}`] = childServices[servicename];

				});
				callback(services);
			}, currentPath);
		}, function(servicesArr) {
			delete ymlobj.includes;
			ymlobj.services = servicesArr;
			cb(ymlobj);
		});
	}
}

// merge links and depends_on
function merge(dst, src) {
	_.map(['external_links', 'links', 'depends_on'], function(fieldname) {
		var dstmap = {};
		_.map(dst[fieldname], function(item) {
			var	itemsplit = item.split(':');
			dstmap[itemsplit[1]] = itemsplit[0];
		});

		_.map(src[fieldname], function(item) {
			var itemsplit =  item.split(':');
			var name = !itemsplit[1] ? itemsplit[0] : itemsplit[1];
			var ref = itemsplit[0];
			dstmap[name] = ref;
		});

		var newfield = [];
		_.map(Object.keys(dstmap), function(itemname) {
			newfield.push(`${dstmap[itemname]}:${itemname}`);
		});

		dst[fieldname] = newfield;

	});
}

function mergePort(dst, src) {
	var fieldname = 'ports';
	var dstmap = {};
	_.map(dst[fieldname], function(item) {
		var	itemsplit = item.split(':');
		dstmap[itemsplit[0]] = !itemsplit[1] ? itemsplit[0] : itemsplit[1];
	});

	_.map(src[fieldname], function(item) {
		var itemsplit =  item.split(':')[1];
		var name = !itemsplit[1] ? itemsplit[0] : itemsplit[1];
		var serviceref = itemsplit[0];

		dstmap[itemsplit[0]] = !itemsplit[1] ? itemsplit[0] : itemsplit[1];
	});

	var newfield = [];
	_.map(Object.keys(dstmap), function(itemname) {
		newfield.push(`${itemname}:${dstmap[itemname]}`);
	});

	dst[fieldname] = newfield;
}

function arrayUnique(array) {
  var a = array.concat();
  for(var i=0; i<a.length; ++i) {
    for(var j=i+1; j<a.length; ++j) {
      if(a[i] === a[j])
        a.splice(j--, 1);
    }
  }
  return a;
}

function mergeArray(dst, src) {
	_.map(['args', 'command', 'environment', 'expose', 'labels', 'networks', 'aliases', 'env_file'], function(fieldname) {
		if (dst[fieldname].constructor === Array) {
			if (src[fieldname] != undefined) {
				// convert src to array if itsn't
				var newsrc = [];
				if (src[fieldname].constructor !== Array) {
					_.map(Object.keys(src[fieldname]), function(key) {
						newsrc.push([key]);
					});
				}
				else {
					newsrc = src;
				}
				dst[fieldname] = arrayUnique(dst[fieldname].concat(newsrc));
			}
			return;
		}
		var dstmap = {};
		_.map(Object.keys(dst[fieldname]), function(key) {
			dstmap[key] = dst[fieldname][key];
		});

		_.map(src[fieldname], function(key) {
			dstmap[key] = src[fieldname][key];
		});

		dst[fieldname] = dstmap;
	});
}

function override(dst, src) {
	//container_name, entrypoint, image
	_.map(['build', 'context', 'dockerfile', 'container_name', 'entrypoint', 'image', 'cpu_shares', 'cpu_quota', 'cpuset', 'domainname', 'hostname', 'ipc', 'mac_address', 'mem_limit', 'memswap_limit', 'oom_score_adj', 'privileged', 'read_only', 'restart', 'shm_size', 'stdin_open', 'tty', 'user', 'working_dir'], function(fieldname) {
		if (src[fieldname] !== undefined) dst[fieldname] = src[fieldname];
	});
}

function toRelativePath(filepath, value) {

}

<commit_msg>fix merge port<commit_after>var yaml = require('yamljs');
var request = require('request');
var fs = require('fs');
var validUrl = require('valid-url');
var async = require('async');
var _ = require('lodash');
var path = require('path');

exports.parse = parse;
exports.merge = function(pathtoyml, cb) {
	parse(pathtoyml, function() {

	});
}

function toFullname(ymlobj, prop, namespace) {
	if (ymlobj[prop] == undefined) {
		return;
	}
	var newprop = [];
	for (var i in ymlobj[prop]) {
		var propitem = ymlobj[prop][i];
		if (propitem == undefined) continue;

		var newpropitem = '';
		var propitems = propitem.split(':');
		if (propitems.length === 2) {
			newpropitem = `${namespace}.${propitems[0]}:${propitems[1]}`;
		} else {
			newpropitem = `${namespace}.${propitems[0]}:${propitems[0]}`;
		}

		newprop.push(newpropitem);
	}
	ymlobj[prop] = newprop;

}

function parse(pathtoyml, cb, currentPath) {
	if (validUrl.isUri(pathtoyml)) {
		request(pathtoyml, function(err, response, body) {
			parseYml(body);
		});
	}
	else {
		var absolutePath = !currentPath ? path.resolve(pathtoyml) : path.resolve(currentPath, pathtoyml);

		fs.readFile(absolutePath, 'utf8', function(err, data) {
			if (err) throw err;
			currentPath = path.dirname(absolutePath);
			parseYml(data);
		});
	}

	function parseYml(content) {
		var ymlobj = yaml.parse(content);
		var namespaceMap = ymlobj.includes;

		if (ymlobj.includes == undefined) {
			cb(ymlobj);
			return;
		}

		async.filter(Object.keys(ymlobj.includes), function(namespace, callback) {
			parse(ymlobj.includes[namespace], function(childymlobj) {
				var childServices = childymlobj.services;
				var services = {};
				_.map(Object.keys(ymlobj.services), function(servicename) {
					services[servicename] = ymlobj.services[servicename];
					//			toFullname(services[servicename], 'links', namespace);
				});

				if (childServices == undefined) {
					callback(services);
					return;
				}

				_.map(Object.keys(childServices), function(servicename) {
					if (services[`${namespace}.${servicename}`] != undefined) {
						toFullname(childServices[servicename], 'links', namespace);

						merge(childServices[servicename], services[`${namespace}.${servicename}`]);
						mergePort(childServices[servicename], services[`${namespace}.${servicename}`]);
					}

					services[`${namespace}.${servicename}`] = childServices[servicename];

				});
				callback(services);
			}, currentPath);
		}, function(servicesArr) {
			delete ymlobj.includes;
			ymlobj.services = servicesArr;
			cb(ymlobj);
		});
	}
}

// merge links and depends_on
function merge(dst, src) {
	_.map(['external_links', 'links', 'depends_on'], function(fieldname) {
		var dstmap = {};
		_.map(dst[fieldname], function(item) {
			var	itemsplit = item.split(':');
			dstmap[itemsplit[1]] = itemsplit[0];
		});

		_.map(src[fieldname], function(item) {
			var itemsplit =  item.split(':');
			var name = !itemsplit[1] ? itemsplit[0] : itemsplit[1];
			var ref = itemsplit[0];
			dstmap[name] = ref;
		});

		var newfield = [];
		_.map(Object.keys(dstmap), function(itemname) {
			newfield.push(`${dstmap[itemname]}:${itemname}`);
		});

		dst[fieldname] = newfield;

	});
}

function mergePort(dst, src) {
	var fieldname = 'ports';
	var dstmap = {};
	_.map(dst[fieldname], function(item) {
		var	itemsplit = item.split(':');
		dstmap[itemsplit[0]] = !itemsplit[1] ? itemsplit[0] : itemsplit[1];
	});

	_.map(src[fieldname], function(item) {
		var itemsplit =  item.split(':');
		var name = !itemsplit[1] ? itemsplit[0] : itemsplit[1];
		var ref = itemsplit[0];
		dstmap[ref] = name;
	});

	var newfield = [];
	_.map(Object.keys(dstmap), function(itemname) {
		newfield.push(`${itemname}:${dstmap[itemname]}`);
	});

	dst[fieldname] = newfield;
}

function arrayUnique(array) {
  var a = array.concat();
  for(var i=0; i<a.length; ++i) {
    for(var j=i+1; j<a.length; ++j) {
      if(a[i] === a[j])
        a.splice(j--, 1);
    }
  }
  return a;
}

function mergeArray(dst, src) {
	_.map(['args', 'command', 'environment', 'expose', 'labels', 'networks', 'aliases', 'env_file'], function(fieldname) {
		if (dst[fieldname].constructor === Array) {
			if (src[fieldname] != undefined) {
				// convert src to array if itsn't
				var newsrc = [];
				if (src[fieldname].constructor !== Array) {
					_.map(Object.keys(src[fieldname]), function(key) {
						newsrc.push([key]);
					});
				}
				else {
					newsrc = src;
				}
				dst[fieldname] = arrayUnique(dst[fieldname].concat(newsrc));
			}
			return;
		}
		var dstmap = {};
		_.map(Object.keys(dst[fieldname]), function(key) {
			dstmap[key] = dst[fieldname][key];
		});

		_.map(src[fieldname], function(key) {
			dstmap[key] = src[fieldname][key];
		});

		dst[fieldname] = dstmap;
	});
}

function override(dst, src) {
	//container_name, entrypoint, image
	_.map(['build', 'context', 'dockerfile', 'container_name', 'entrypoint', 'image', 'cpu_shares', 'cpu_quota', 'cpuset', 'domainname', 'hostname', 'ipc', 'mac_address', 'mem_limit', 'memswap_limit', 'oom_score_adj', 'privileged', 'read_only', 'restart', 'shm_size', 'stdin_open', 'tty', 'user', 'working_dir'], function(fieldname) {
		if (src[fieldname] !== undefined) dst[fieldname] = src[fieldname];
	});
}

function toRelativePath(filepath, value) {

}

<|endoftext|>


<commit_before>/*
---
name: Company

description: Mediated Component System for MooTools

version: 1.0.X

license: MIT-style

authors:
- Mark Joseph "Keeto" Obcena

requires:
- core/1.3: [Type, Events]

provides: [Unit]

...
*/

(function(){

// Utility Functions

var removeOnRegexp = /^on([A-Z])/,
	removeOnFn = function(_, ch){
		return ch.toLowerCase();
	};

var wrap = function(fn){
	return function(){
		return fn.apply(this, arguments);
	};
};

var mix = function(){
	var len = arguments.length;
	while(len--){
		var Current = arguments[len];
		switch (typeOf(Current)){
			case 'type':
			case 'class':
				Current.$prototyping = true;
				Object.append(this, new Current);
				delete Current.$prototyping;
			break;

			case 'unit':
				for (var i in Current){
					if (!Current.hasOwnProperty(i)) continue;
					var value = Current[i];
					this[i] = (typeof value == 'function' && !value.exec) ? wrap(value) : value;
				}
			break;

			default:
				Object.append(this, Current);
			break;
		}
	}
	return this;
};

// Dispatcher

var callback = function(){
	var current = callback.current;
	current.apply(current.$ownerObj, callback.args);
};

var Dispatcher = new Events;

unwrapClassMethods: for (var prop in Dispatcher){
	var item = Dispatcher[prop];
	if (typeof item != 'function' || item.exec || !item.$origin) continue;
	Dispatcher[prop] = item.$origin;
}

Object.append(Dispatcher, {

	$dispatched: {},
	$finished: {},
	$mediator: (this.document) ? this.document.createElement('script') : null,

	setup: function(){
		var mediator = this.$mediator;

		if (!mediator || (!mediator.attachEvent && !mediator.addEventListener)) return this;

		if (mediator.addEventListener){
			mediator.addEventListener('publishDispatch', callback, false);
			this.dispatch = function(fn, args){
				var e = document.createEvent('UIEvents');
				e.initEvent('publishDispatch', false, false);
				callback.args = args;
				callback.current = fn;
				mediator.dispatchEvent(e);
			};
		} else if (mediator.attachEvent && !mediator.addEventListener){
			$(document.head).appendChild(mediator);
			mediator.publishDispatch = 0;
			mediator.attachEvent('onpropertychange', callback);
			this.dispatch = function(fn, args){
				callback.args = args;
				callback.current = fn;
				mediator.publishDispatch++;
			};
			var cleanUp = function(){
				mediator.detachEvent('onpropertychange', callback);
				mediator.parentNode.removeChild(mediator);
				this.detachEvent('onunload', cleanUp);
			};
			window.attachEvent('onunload', cleanUp);
		}
		return this;
	},

	getFinished: function(key){
		return this.$finished[key] || null;
	},

	getDispatched: function(key){
		return this.$dispatched[key] || [];
	},

	dispatch: function(fn, args){
		callback.args = args;
		callback.current = fn;
		callback.call(null);
	},

	replay: function(type, fn){
		if (!this.$dispatched || !this.$dispatched[type]) return false;
		this.dispatch(fn, this.$dispatched[type]);
		return true;
	},

	redispatch: function(type, fn){
		if (!this.$finished || !this.$finished[type]) return false;
		this.dispatch(fn, this.$finished[type]);
		return true;
	},

	fireEvent: function(type, args, finish){
		var self = this,
			dispatched = this.$dispatched,
			finished = this.$finished,
			events = this.$events,
			handlers = null;
		type = type.replace(removeOnRegexp, removeOnFn);
		args = Array.from(args);
		dispatched[type] = args;
		if (finish) finished[type] = args;
		if (!events || !(handlers = events[type])) return this;
		for (var i = 0, l = handlers.length; i < l; i++){
			this.dispatch(handlers[i], args);
		}
		return this;
	},

	removeEvents: function(events){
		var type;
		if (typeOf(events) == 'object'){
			for (type in events){
				if (!events.hasOwnProperty(type)) continue;
				this.removeEvent(type, events[type]);
			}
			return this;
		}
		if (events) events = events.replace(removeOnRegexp, removeOnFn);
		for (type in this.$events){
			if (events && events != type) continue;
			var fns = this.$events[type];
			for (var i = fns.length; i--;){
				if (i in fns) this.removeEvent(type, fns[i]);
			}
		}
		return this;
	},

	removeFinished: function(){
		var finished = this.$finished;
		for (var i in finished){
			if (!finished.hasOwnProperty(i)
				|| i == 'window.domready'
				|| i == 'window.load') continue;
			delete finished[i];
		}
		return this;
	},

	removeDispatched: function(){
		var dispatched = this.$dispatched;
		for (var i in dispatched){
			if (!dispatched.hasOwnProperty(i)
				|| i == 'window.domready'
				|| i == 'window.load') continue;
			delete dispatched[i];
		}
		return this;
	},

	flush: function(){
		this.removeEvents();
		delete Dispatcher.$events;
		Dispatcher.$events = {};
		this.removeFinished();
		this.removeDispatched();
		return this;
	}

}).setup();

// Load and DOMReady

window.addEvents({
	'domready': function(){
		Dispatcher.fireEvent('window.domready', [], true);
	},
	'load': function(){
		Dispatcher.fireEvent('window.load', [], true);
	}
});

// Unit Constructor

function Unit(desc){
	if (!(this instanceof Unit)) return new Unit(desc);

	this.$unitAttached = true;
	this.$unitHandlers = {};
	this.$unitPrefix = '';
	if (Unit.$prototyping) return this;
	if (desc){
		this.extendUnit(desc);
		this.setupUnit();
	}
	return this;
}

var decorateFireEvent = function(origin, rep){
	var fn = function(){
		rep.apply(this, arguments);
		return origin.apply(this, arguments);
	};
	fn.$unwrapped = origin;
	return fn;
};

var decorateFn = function(value, unit){
	var fn = function(){
		return value.apply(unit, arguments);
	};
	fn.$origin = value;
	return fn;
};

this.Unit = new Type('Unit', Unit).extend({

	isUnit: function(obj){
		if (typeOf(obj) === 'unit'){
			return true;
		} else {
			return obj.$unitInstance ? obj.$unitInstance instanceof Unit : false;
		}
	},

	decorate: function(obj, nowrap){
		if (obj.$unitInstance) return obj;
		var unit = obj.$unitInstance = new Unit;
		unit.extendUnit = function(ext){
			mix.call(obj, ext);
			return this;
		};
		for (var i in unit){
			var value = unit[i];
			if (obj[i] || i == '$family' || (typeof value !== 'function' || value.exec)) continue;
			obj[i] = decorateFn(value, unit);
		}
		obj.setupUnit();
		return (!nowrap) ? this.wrapEvents(obj) : obj;
	},

	undecorate: function(obj){
		var unit = obj.$unitInstance;
		if (!unit) return obj;
		for (var key in unit){
			var value = obj[key];
			if (!value || value.$origin == value) continue;
			delete obj[key];
		}
		this.unwrapEvents(obj);
		delete obj.$unitInstance;
		return obj;
	},

	wrapEvents: function(unit){
		var fireEvent = unit.fireEvent;
		if (!fireEvent || fireEvent.$unwrapped) return unit;
		unit.fireEvent = decorateFireEvent(fireEvent, function(type, args){
			unit.publish(type, args);
		});
		return unit;
	},

	unwrapEvents: function(unit){
		var fireEvent = unit.fireEvent;
		if (fireEvent && fireEvent.$unwrapped) unit.fireEvent = fireEvent.$unwrapped;
		return unit;
	}

}).implement({

	setupUnit: function(){
		var self = this;
		if (this.Uses){
			Array.from(this.Uses).each(this.extendUnit.bind(this));
			delete this.Uses;
		}
		if (this.Prefix){
			this.setPrefix(this.Prefix);
			delete this.Prefix;
		}

		if (this.initSetup) Dispatcher.dispatch(function(){ self.initSetup.apply(self); });
		if (this.readySetup) this.subscribe('window.domready', function(){ self.readySetup(); });
		if (this.loadSetup) this.subscribe('window.load', function(){ self.loadSetup(); });
		return this;
	},

	extendUnit: function(obj){
		mix.call(this, obj);
		return this;
	},

	getPrefix: function(){
		return this.$unitPrefix;
	},

	setPrefix: function(str){
		this.$unitPrefix = (str || '').toString();
		return this;
	},

	isAttached: function(){
		return !!this.$unitAttached;
	},

	detachUnit: function(){
		var attached = this.$unitHandlers;
		if (!this.$unitAttached) return this;
		for (var key in attached){
			var len = attached[key].length;
			while (len--){
				Dispatcher.removeEvent(key, attached[key][len]);
			}
		}
		this.$unitAttached= false;
		return this;
	},

	attachUnit: function(){
		var attached = this.$unitHandlers;
		if (this.$unitAttached) return this;
		for (var key in attached){
			var len = attached[key].length;
			while (len--){
				Dispatcher.addEvent(key, attached[key][len]);
			}
		}
		this.$unitAttached= true;
		return this;
	},

	destroyUnit: function(){
		this.detachUnit();
		this.$unitHandlers = {};
		return this;
	},

	subscribe: function(key, fn, replay){
		if (typeof key == 'object'){
			for (var i in key) this.subscribe(i, key[i], fn);
		} else {
			if (key.charAt(0) == '!'){
				replay = true;
				key = key.substring(1);
			}
			fn.$ownerObj = this;
			if (!Dispatcher.redispatch(key, fn)){
				Events.prototype.addEvent.call({$events: this.$unitHandlers}, key, fn);
				if (this.$unitAttached){
					Dispatcher.addEvent(key, fn);
					if (replay) Dispatcher.replay(key, fn);
				}
			}
		}
		return this;
	},

	unsubscribe: function(key, fn){
		if (typeof key !== 'string'){
			for (var i in key) this.unsubscribe(i, key[i]);
		} else {
			Dispatcher.removeEvent(key, fn);
			Events.prototype.removeEvent.call({$events: this.$unitHandlers}, key, fn);
		}
		return this;
	},

	publish: function(type, args, finish){
		if (type.charAt(0) == '!') type = type.substring(1);
		else if (this.$unitPrefix) type = this.$unitPrefix + '.' + type;
		if (this.$unitAttached) Dispatcher.fireEvent.call(Dispatcher, type, args, finish);
		return this;
	}

});

// Dispatcher Inspection

var wrapDispatcherFn = function(origin){
	var fn = function(){
		fn.$spy.apply(null, arguments);
		fn.$unwrapped.apply(Dispatcher, arguments);
	};
	return Object.append(fn, {$unwrapped: origin});
};

Unit.Dispatcher = {

	flush: function(){
		Dispatcher.flush();
		return this;
	},

	getFinished: function(){
		return Object.clone(Dispatcher.$finished);
	},

	removeFinished: function(){
		Dispatcher.removeFinished();
		return this;
	},

	getDispatched: function(key){
		return key ? (Dispatcher.$dispatched[key] || []).clone() : Object.clone(Dispatcher.$dispatched);
	},

	removeDispatched: function(){
		Dispatcher.removeDispatched();
		return this;
	},

	getSubscribers: function(key){
		return key ? (Dispatcher.$events[key] || []).clone() : Object.clone(Dispatcher.$events);
	},

	spySubscribe: function(spy){
		var fnAddEvent = Dispatcher.addEvent;
		if (!fnAddEvent.$unwrapped) Dispatcher.addEvent = wrapDispatcherFn(fnAddEvent);
		Dispatcher.addEvent.$spy = spy;
		return this;
	},

	unspySubscribe: function(){
		var fnAddEvent = Dispatcher.addEvent;
		if (fnAddEvent.$unwrapped){
			Dispatcher.addEvent = fnAddEvent.$unwrapped;
		}
		return this;
	},

	spyUnsubscribe: function(spy){
		var fnRemoveEvent = Dispatcher.removeEvent;
		if (!fnRemoveEvent.$unwrapped) Dispatcher.removeEvent = wrapDispatcherFn(fnRemoveEvent);
		Dispatcher.removeEvent.$spy = spy;
		return this;
	},

	unspyUnsubscribe: function(){
		var fnRemoveEvent = Dispatcher.removeEvent;
		if (fnRemoveEvent.$unwrapped){
			Dispatcher.removeEvent = fnRemoveEvent.$unwrapped;
		}
		return this;
	},

	spyPublish: function(spy){
		var fnFireEvent = Dispatcher.fireEvent;
		if (!fnFireEvent.$unwrapped) Dispatcher.fireEvent = wrapDispatcherFn(fnFireEvent);
		Dispatcher.fireEvent.$spy = spy;
		return this;
	},

	unspyPublish: function(){
		var fnFireEvent = Dispatcher.fireEvent;
		if (fnFireEvent.$unwrapped){
			Dispatcher.fireEvent = fnFireEvent.$unwrapped;
		}
		return this;
	}

};

}).call(this);

<commit_msg>* Replay and redispatch cleanup.<commit_after>/*
---
name: Company

description: Mediated Component System for MooTools

version: 1.0.X

license: MIT-style

authors:
- Mark Joseph "Keeto" Obcena

requires:
- core/1.3: [Type, Events]

provides: [Unit]

...
*/

(function(){

// Utility Functions

var removeOnRegexp = /^on([A-Z])/,
	removeOnFn = function(_, ch){
		return ch.toLowerCase();
	};

var wrap = function(fn){
	return function(){
		return fn.apply(this, arguments);
	};
};

var mix = function(){
	var len = arguments.length;
	while(len--){
		var Current = arguments[len];
		switch (typeOf(Current)){
			case 'type':
			case 'class':
				Current.$prototyping = true;
				Object.append(this, new Current);
				delete Current.$prototyping;
			break;

			case 'unit':
				for (var i in Current){
					if (!Current.hasOwnProperty(i)) continue;
					var value = Current[i];
					this[i] = (typeof value == 'function' && !value.exec) ? wrap(value) : value;
				}
			break;

			default:
				Object.append(this, Current);
			break;
		}
	}
	return this;
};

// Dispatcher

var callback = function(){
	var current = callback.current;
	current.apply(current.$ownerObj, callback.args);
};

var Dispatcher = new Events;

unwrapClassMethods: for (var prop in Dispatcher){
	var item = Dispatcher[prop];
	if (typeof item != 'function' || item.exec || !item.$origin) continue;
	Dispatcher[prop] = item.$origin;
}

Object.append(Dispatcher, {

	$dispatched: {},
	$finished: {},
	$mediator: (this.document) ? this.document.createElement('script') : null,

	setup: function(){
		var mediator = this.$mediator;

		if (!mediator || (!mediator.attachEvent && !mediator.addEventListener)) return this;

		if (mediator.addEventListener){
			mediator.addEventListener('publishDispatch', callback, false);
			this.dispatch = function(fn, args){
				var e = document.createEvent('UIEvents');
				e.initEvent('publishDispatch', false, false);
				callback.args = args;
				callback.current = fn;
				mediator.dispatchEvent(e);
			};
		} else if (mediator.attachEvent && !mediator.addEventListener){
			$(document.head).appendChild(mediator);
			mediator.publishDispatch = 0;
			mediator.attachEvent('onpropertychange', callback);
			this.dispatch = function(fn, args){
				callback.args = args;
				callback.current = fn;
				mediator.publishDispatch++;
			};
			var cleanUp = function(){
				mediator.detachEvent('onpropertychange', callback);
				mediator.parentNode.removeChild(mediator);
				this.detachEvent('onunload', cleanUp);
			};
			window.attachEvent('onunload', cleanUp);
		}
		return this;
	},

	getFinished: function(key){
		return this.$finished[key] || null;
	},

	getDispatched: function(key){
		return this.$dispatched[key] || [];
	},

	dispatch: function(fn, args){
		callback.args = args;
		callback.current = fn;
		callback.call(null);
	},

	replay: function(type, fn){
		var dispatched = this.$dispatched,
			args = null;
		if (!dispatched || !(args = dispatched[type])) return false;
		this.dispatch(fn, args);
		return true;
	},

	redispatch: function(type, fn){
		var finished = this.$finished,
			args = null;
		if (!finished || !(args = finished[type])) return false;
		this.dispatch(fn, args);
		return true;
	},

	fireEvent: function(type, args, finish){
		var self = this,
			dispatched = this.$dispatched,
			finished = this.$finished,
			events = this.$events,
			handlers = null;
		type = type.replace(removeOnRegexp, removeOnFn);
		args = Array.from(args);
		dispatched[type] = args;
		if (finish) finished[type] = args;
		if (!events || !(handlers = events[type])) return this;
		for (var i = 0, l = handlers.length; i < l; i++){
			this.dispatch(handlers[i], args);
		}
		return this;
	},

	removeEvents: function(events){
		var type;
		if (typeOf(events) == 'object'){
			for (type in events){
				if (!events.hasOwnProperty(type)) continue;
				this.removeEvent(type, events[type]);
			}
			return this;
		}
		if (events) events = events.replace(removeOnRegexp, removeOnFn);
		for (type in this.$events){
			if (events && events != type) continue;
			var fns = this.$events[type];
			for (var i = fns.length; i--;){
				if (i in fns) this.removeEvent(type, fns[i]);
			}
		}
		return this;
	},

	removeFinished: function(){
		var finished = this.$finished;
		for (var i in finished){
			if (!finished.hasOwnProperty(i)
				|| i == 'window.domready'
				|| i == 'window.load') continue;
			delete finished[i];
		}
		return this;
	},

	removeDispatched: function(){
		var dispatched = this.$dispatched;
		for (var i in dispatched){
			if (!dispatched.hasOwnProperty(i)
				|| i == 'window.domready'
				|| i == 'window.load') continue;
			delete dispatched[i];
		}
		return this;
	},

	flush: function(){
		this.removeEvents();
		delete Dispatcher.$events;
		Dispatcher.$events = {};
		this.removeFinished();
		this.removeDispatched();
		return this;
	}

}).setup();

// Load and DOMReady

window.addEvents({
	'domready': function(){
		Dispatcher.fireEvent('window.domready', [], true);
	},
	'load': function(){
		Dispatcher.fireEvent('window.load', [], true);
	}
});

// Unit Constructor

function Unit(desc){
	if (!(this instanceof Unit)) return new Unit(desc);

	this.$unitAttached = true;
	this.$unitHandlers = {};
	this.$unitPrefix = '';
	if (Unit.$prototyping) return this;
	if (desc){
		this.extendUnit(desc);
		this.setupUnit();
	}
	return this;
}

var decorateFireEvent = function(origin, rep){
	var fn = function(){
		rep.apply(this, arguments);
		return origin.apply(this, arguments);
	};
	fn.$unwrapped = origin;
	return fn;
};

var decorateFn = function(value, unit){
	var fn = function(){
		return value.apply(unit, arguments);
	};
	fn.$origin = value;
	return fn;
};

this.Unit = new Type('Unit', Unit).extend({

	isUnit: function(obj){
		if (typeOf(obj) === 'unit'){
			return true;
		} else {
			return obj.$unitInstance ? obj.$unitInstance instanceof Unit : false;
		}
	},

	decorate: function(obj, nowrap){
		if (obj.$unitInstance) return obj;
		var unit = obj.$unitInstance = new Unit;
		unit.extendUnit = function(ext){
			mix.call(obj, ext);
			return this;
		};
		for (var i in unit){
			var value = unit[i];
			if (obj[i] || i == '$family' || (typeof value !== 'function' || value.exec)) continue;
			obj[i] = decorateFn(value, unit);
		}
		obj.setupUnit();
		return (!nowrap) ? this.wrapEvents(obj) : obj;
	},

	undecorate: function(obj){
		var unit = obj.$unitInstance;
		if (!unit) return obj;
		for (var key in unit){
			var value = obj[key];
			if (!value || value.$origin == value) continue;
			delete obj[key];
		}
		this.unwrapEvents(obj);
		delete obj.$unitInstance;
		return obj;
	},

	wrapEvents: function(unit){
		var fireEvent = unit.fireEvent;
		if (!fireEvent || fireEvent.$unwrapped) return unit;
		unit.fireEvent = decorateFireEvent(fireEvent, function(type, args){
			unit.publish(type, args);
		});
		return unit;
	},

	unwrapEvents: function(unit){
		var fireEvent = unit.fireEvent;
		if (fireEvent && fireEvent.$unwrapped) unit.fireEvent = fireEvent.$unwrapped;
		return unit;
	}

}).implement({

	setupUnit: function(){
		var self = this;
		if (this.Uses){
			Array.from(this.Uses).each(this.extendUnit.bind(this));
			delete this.Uses;
		}
		if (this.Prefix){
			this.setPrefix(this.Prefix);
			delete this.Prefix;
		}

		if (this.initSetup) Dispatcher.dispatch(function(){ self.initSetup.apply(self); });
		if (this.readySetup) this.subscribe('window.domready', function(){ self.readySetup(); });
		if (this.loadSetup) this.subscribe('window.load', function(){ self.loadSetup(); });
		return this;
	},

	extendUnit: function(obj){
		mix.call(this, obj);
		return this;
	},

	getPrefix: function(){
		return this.$unitPrefix;
	},

	setPrefix: function(str){
		this.$unitPrefix = (str || '').toString();
		return this;
	},

	isAttached: function(){
		return !!this.$unitAttached;
	},

	detachUnit: function(){
		var attached = this.$unitHandlers;
		if (!this.$unitAttached) return this;
		for (var key in attached){
			var len = attached[key].length;
			while (len--){
				Dispatcher.removeEvent(key, attached[key][len]);
			}
		}
		this.$unitAttached= false;
		return this;
	},

	attachUnit: function(){
		var attached = this.$unitHandlers;
		if (this.$unitAttached) return this;
		for (var key in attached){
			var len = attached[key].length;
			while (len--){
				Dispatcher.addEvent(key, attached[key][len]);
			}
		}
		this.$unitAttached= true;
		return this;
	},

	destroyUnit: function(){
		this.detachUnit();
		this.$unitHandlers = {};
		return this;
	},

	subscribe: function(key, fn, replay){
		if (typeof key == 'object'){
			for (var i in key) this.subscribe(i, key[i], fn);
		} else {
			if (key.charAt(0) == '!'){
				replay = true;
				key = key.substring(1);
			}
			fn.$ownerObj = this;
			if (!Dispatcher.redispatch(key, fn)){
				Events.prototype.addEvent.call({$events: this.$unitHandlers}, key, fn);
				if (this.$unitAttached){
					Dispatcher.addEvent(key, fn);
					if (replay) Dispatcher.replay(key, fn);
				}
			}
		}
		return this;
	},

	unsubscribe: function(key, fn){
		if (typeof key !== 'string'){
			for (var i in key) this.unsubscribe(i, key[i]);
		} else {
			Dispatcher.removeEvent(key, fn);
			Events.prototype.removeEvent.call({$events: this.$unitHandlers}, key, fn);
		}
		return this;
	},

	publish: function(type, args, finish){
		if (type.charAt(0) == '!') type = type.substring(1);
		else if (this.$unitPrefix) type = this.$unitPrefix + '.' + type;
		if (this.$unitAttached) Dispatcher.fireEvent.call(Dispatcher, type, args, finish);
		return this;
	}

});

// Dispatcher Inspection

var wrapDispatcherFn = function(origin){
	var fn = function(){
		fn.$spy.apply(null, arguments);
		fn.$unwrapped.apply(Dispatcher, arguments);
	};
	return Object.append(fn, {$unwrapped: origin});
};

Unit.Dispatcher = {

	flush: function(){
		Dispatcher.flush();
		return this;
	},

	getFinished: function(){
		return Object.clone(Dispatcher.$finished);
	},

	removeFinished: function(){
		Dispatcher.removeFinished();
		return this;
	},

	getDispatched: function(key){
		return key ? (Dispatcher.$dispatched[key] || []).clone() : Object.clone(Dispatcher.$dispatched);
	},

	removeDispatched: function(){
		Dispatcher.removeDispatched();
		return this;
	},

	getSubscribers: function(key){
		return key ? (Dispatcher.$events[key] || []).clone() : Object.clone(Dispatcher.$events);
	},

	spySubscribe: function(spy){
		var fnAddEvent = Dispatcher.addEvent;
		if (!fnAddEvent.$unwrapped) Dispatcher.addEvent = wrapDispatcherFn(fnAddEvent);
		Dispatcher.addEvent.$spy = spy;
		return this;
	},

	unspySubscribe: function(){
		var fnAddEvent = Dispatcher.addEvent;
		if (fnAddEvent.$unwrapped){
			Dispatcher.addEvent = fnAddEvent.$unwrapped;
		}
		return this;
	},

	spyUnsubscribe: function(spy){
		var fnRemoveEvent = Dispatcher.removeEvent;
		if (!fnRemoveEvent.$unwrapped) Dispatcher.removeEvent = wrapDispatcherFn(fnRemoveEvent);
		Dispatcher.removeEvent.$spy = spy;
		return this;
	},

	unspyUnsubscribe: function(){
		var fnRemoveEvent = Dispatcher.removeEvent;
		if (fnRemoveEvent.$unwrapped){
			Dispatcher.removeEvent = fnRemoveEvent.$unwrapped;
		}
		return this;
	},

	spyPublish: function(spy){
		var fnFireEvent = Dispatcher.fireEvent;
		if (!fnFireEvent.$unwrapped) Dispatcher.fireEvent = wrapDispatcherFn(fnFireEvent);
		Dispatcher.fireEvent.$spy = spy;
		return this;
	},

	unspyPublish: function(){
		var fnFireEvent = Dispatcher.fireEvent;
		if (fnFireEvent.$unwrapped){
			Dispatcher.fireEvent = fnFireEvent.$unwrapped;
		}
		return this;
	}

};

}).call(this);

<|endoftext|>


<commit_before>'use strict'

let _vertices = new Map();

/*
 * A class for a Vertex data structure containing a key, data and edges
 *
 * @author Jose Barrios
 * @version 0.5.0
 *
 * @class
 */
class Vertex {

  /*
   * A static method that compares two vertexes for equality.
   * @returns {boolean} true if they are equal, false otherwise
   */
  static equal(n1, n2){
    n1 = JSON.stringify(n1);
    n2 = JSON.stringify(n2);
    return n1 === n2;
  }

  /* Creates an instance of Vertex.
   *
   * @constructor
   * @this {Vertex}
   * @param {string|number} key - The key of the Vertex, used as a reference
   * @param {object} data - The data of the Vertex, can be any object
   */
  constructor(key = null, data = null){
    this.key = key;
    this.data = data;
    this.degree = 0;

    this.address = Symbol(`V${this.key}`);
    _vertices.set(this.address, this);
  }

  add(target){
    if(!_vertices.has(target)){
      _vertices.set(target);
      this.degree += _vertices.has(target)? 1 : 0;
    }
  }

  has(target){
    return _vertices.has(target)
  }

  delete(target){
    if(_vertices.has(target)){
      _vertices.delete(target);
      this.degree -= _vertices.has(target)? 0 : 1;
    }
  }

  static getMap(){ return _vertices; }

  /*
   * Returns a string representing the vertex.
   * @returns {string} The string representing the vertex.
   */
  toString(){ return JSON.stringify(this); }

  static fromString(str){ return JSON.parse(str); }

  serialize(){ return `${this.key}=${JSON.stringify(this.data)}`; }

  static deserialize(str){
    let [key, data] = str.split("=");
    let deserialized =  new Vertex(key, JSON.parse(data))
    return deserialized;
  }

  /*
   * Deletes the vertex neighbours, and nullifies key data. It also ensures
   * proper garbage collection by deallocating references to WeakMaps
   */
  clear(){
    _vertices = new WeakSet();
    this.data = null;
    this.key = null;
    this.degree = 0;
  }

}

module.exports = Vertex;
<commit_msg>Added a unique 'address' for each vertex using ES6 Symbols. That way, we can have vertex with the same key and value in the map<commit_after>'use strict'

let _vertices = new Map();

/*
 * A class for a Vertex data structure containing a key, data and edges
 *
 * @author Jose Barrios
 * @version 0.5.0
 *
 * @class
 */
class Vertex {

  /*
   * A static method that compares two vertexes for equality.
   * @returns {boolean} true if they are equal, false otherwise
   */
  static equal(n1, n2){
    n1 = JSON.stringify(n1);
    n2 = JSON.stringify(n2);
    return n1 === n2;
  }

  /* Creates an instance of Vertex.
   *
   * @constructor
   * @this {Vertex}
   * @param {string|number} key - The key of the Vertex, used as a reference
   * @param {object} data - The data of the Vertex, can be any object
   */
  constructor(key = null, data = null){
    this.key = key;
    this.data = data;
    this.degree = 0;

    let unique = Symbol(this.key)
    this.address = { unique };
    _vertices.set(this.address, this);
  }

  add(target){
    if(!_vertices.has(target)){
      _vertices.set(target);
      this.degree += 1;
    }
  }

  has(target){
    return _vertices.has(target)
  }

  delete(target){
    if(_vertices.has(target)){
      _vertices.delete(target);
      this.degree -= 1;
    }
  }

  static getMap(){ return _vertices; }

  /*
   * Returns a string representing the vertex.
   * @returns {string} The string representing the vertex.
   */
  toString(){ return JSON.stringify(this); }

  static fromString(str){ return JSON.parse(str); }

  serialize(){ return `${this.key}=${JSON.stringify(this.data)}`; }

  static deserialize(str){
    let [key, data] = str.split("=");
    let deserialized =  new Vertex(key, JSON.parse(data))
    return deserialized;
  }

  /*
   * Deletes the vertex neighbours, and nullifies key data. It also ensures
   * proper garbage collection by deallocating references to WeakMaps
   */
  clear(){
    _vertices.delete(this.address);
    this.data = null;
    this.key = null;
    this.degree = null;
  }

}

module.exports = Vertex;
<|endoftext|>


<commit_before>'use strict';

const rel = require('path').relative;
const xo = require('xo');

module.exports = function () {
	this.plugin('xo', {every: 0, files: 0}, function * (globs, opts) {
		opts = Object.assign({quiet: false}, opts);

		const report = yield xo.lintFiles(globs, opts);

		// truncate project root from paths
		let results = report.results.map(obj => {
			obj.filePath = rel(this.root, obj.filePath);
			return obj;
		});

		// hide warnings
		if (opts.quiet) {
			results = xo.getErrorResults(results);
		}

		if (report.errorCount > 0 || report.warningCount > 0) {
			this.$.log(xo.getFormatter()(results));
		}

		if (report.errorCount > 0) {
			const num = results.filter(el => el.errorCount > 0).length;
			const end = (num > 1) ? 'files' : 'file';

			this.emit('plugin_error', {
				plugin: 'fly-xo',
				error: `XO found ${report.errorCount} errors in ${num} ${end}!`
			});
		}
	});
};
<commit_msg>export as object definition<commit_after>'use strict';

const {relative} = require('path');
const xo = require('xo');

module.exports = {
	name: 'xo',
	every: false,
	files: false,
	* func(globs, opts) {
		opts = Object.assign({quiet: false}, opts);

		const report = yield xo.lintFiles(globs, opts);

		// truncate project root from paths
		let results = report.results.map(obj => {
			obj.filePath = relative(this.root, obj.filePath);
			return obj;
		});

		// hide warnings
		if (opts.quiet) {
			results = xo.getErrorResults(results);
		}

		if (report.errorCount > 0 || report.warningCount > 0) {
			this.$.log(xo.getFormatter()(results));
		}

		if (report.errorCount > 0) {
			const num = results.filter(el => el.errorCount > 0).length;
			const end = (num > 1) ? 'files' : 'file';

			this.emit('plugin_error', {
				plugin: 'fly-xo',
				error: `XO found ${report.errorCount} errors in ${num} ${end}!`
			});
		}
	}
};
<|endoftext|>


<commit_before>var yargs = require('yargs');
var fs    = require('fs');
var http  = require('http');

var argv = yargs
    .option('c', {
      alias: 'client',
      type: 'array'
    })
    .option('s', {
      alias: 'search',
      type: 'string'
    })
    .option('f', {
      alias: 'file',
      type: 'string'
    })
    .argv;

var
  clients = argv.client,
  search = argv.search,
  filename = argv.file,
  fileArray = [],
  countArray = 0,
  ocurrences = 0,
  postData = JSON.stringify({
    'content': fileArray[0],
    'search': search
  }),
  options = {
    protocol: 'http',
    host: 'localhost',
    port: 8080,
    method: 'POST',
    path: '/',
    headers: {
      'Content-Type': 'application/json'
    }
  },
  request = null;

fs.readFile(filename, 'utf8', function(err, data) {
  if (err) throw err;
  fileArray = data.match(/([^\s]+\s\s*){1,200}/g);
  console.log(fileArray);
});

for (var i = 0; i < clients.length; i++) {
  var client = clients[i];
  getOcurrences(client);
};

function getOcurrences(client) {
  if(countArray < fileArray.length) {
    // enviar o texto para cliente
    // chamar o metodo novamente
  }
};

request = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    var
      searchReturned = chunk.body.search,
      ocurrencesReturned = chunk.body.ocurrences;

    if(searchReturned == search) {
      ocurrences += ocurrencesReturned;

      countArray++;
    }
  });
  res.on('end', function() {
    console.log('No more data in response.')
  });
});

request.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

request.write(postData);
request.end();
<commit_msg>Fix protocol<commit_after>var yargs = require('yargs');
var fs    = require('fs');
var http  = require('http');

var argv = yargs
    .option('c', {
      alias: 'client',
      type: 'array'
    })
    .option('s', {
      alias: 'search',
      type: 'string'
    })
    .option('f', {
      alias: 'file',
      type: 'string'
    })
    .argv;

var
  clients = argv.client,
  search = argv.search,
  filename = argv.file,
  fileArray = [],
  countArray = 0,
  ocurrences = 0,
  postData = JSON.stringify({
    'content': fileArray[0],
    'search': search
  }),
  options = {
    protocol: 'http:',
    host: 'localhost',
    port: 8080,
    method: 'POST',
    path: '/',
    headers: {
      'Content-Type': 'application/json'
    }
  },
  request = null;

fs.readFile(filename, 'utf8', function(err, data) {
  if (err) throw err;
  fileArray = data.match(/([^\s]+\s\s*){1,200}/g);
  console.log(fileArray);
});

for (var i = 0; i < clients.length; i++) {
  var client = clients[i];
  getOcurrences(client);
};

function getOcurrences(client) {
  if(countArray < fileArray.length) {
    // enviar o texto para cliente
    // chamar o metodo novamente
  }
};

request = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    var
      searchReturned = chunk.body.search,
      ocurrencesReturned = chunk.body.ocurrences;

    if(searchReturned == search) {
      ocurrences += ocurrencesReturned;

      countArray++;
    }
  });
  res.on('end', function() {
    console.log('No more data in response.')
  });
});

request.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

request.write(postData);
request.end();
<|endoftext|>


<commit_before>/**
 * Flexible template engine powered by ES6 template strings.
 *
 * @author Wells Johnston <w@wellsjohnston.com>
 */

'use strict'

const fs = require('fs');
const vm = require('vm');
const path = require('path');
const stripComments = require('strip-comments');

const odesza = {};
const blocks = {};

const cache = {
  templates: {},
  paths: {}
};

// cache control
var useCache = true;

// matches keyword statements (block, include, extends)
const re = /(block|extends|include) ([\/\.\w]+)/g;

/**
 * Renders a template with the given variables.
 *
 * @param {string} template The template to render.
 * @param {object} options An object of key-value pairs representing the
 * variables to be used in the template.
 * @param {string} [basePath] Optional. The base path to use if extend or
 * include statements are present.
 * @return {string} The rendered template.
 */

odesza.render = function(template, options, basePath) {

  options = options && 'object' == typeof options ? options : {};

  template = stripComments(template);

  let s = getStatements(template);

  // if an extend statement is found, fill the extended template blocks in
  if (s.extends.length) {

    // only allow one extend statement
    if (s.extends.length > 1) {
      throw new Error('An odesza template can only extend one file');
    }

    // loop over block statements, putting them into memory
    s.block.forEach(block => {

      // if the block is in memory, this means there is multiple inheritence,
      // i.e. this has already extended
      if (blocks[block] != null) return;

      // gets the content between the block statements
      let start = template.indexOf(`block ${block}`) + `block ${block}`.length;
      let end = template.indexOf(`endblock`, start);

      if (end == -1) {
        throw new Error(`'endblock' statement required after ${block}`);
      }

      blocks[block] = template.substr(start, end - start).trim();
    });

    let extendPath = `${basePath}${s.extends[0]}`;
    template = odesza.renderFile(extendPath, options);
    s = getStatements(template);

  } else {
    s.block.forEach(block => {
      if (blocks[block] != null) {
        template = template.split(`block ${block}`).join(blocks[block]);
        delete blocks[block];
      } else {
        // if not in memory, it is a block statement that can be ignored
        template = template.split(`block ${block}`).join('');
      }
    });
  }

  // recursively replace each import statement with its rendered template
  s.include.forEach(statement => {
    let p = `${basePath}${statement}`;
    template = template
      .split(`include ${statement}`)
      .join(odesza.renderFile(p, options));
  });

  return vm.runInNewContext('`' + template + '`', options).trim();
};

/**
 * Renders a template file.
 *
 * @param {string} location The location to the template file.
 * @param {object} options Options passed in to render the template.
 * @return {string} The rendered template.
 */

odesza.renderFile = function(location, options) {
  var template;
  let basePath = location.substr(0, location.lastIndexOf('/') + 1);
  location = resolvePath(location);
  if (useCache && cache.templates[location] != null) {
    template = cache.templates[location];
  } else {
    template = fs.readFileSync(location).toString().trim();
    cache.templates[location] = template;
  }
  return odesza.render(template, options, basePath);
};

/**
 * Disables caching.
 *
 * @public
 */

odesza.disableCache = function() {
  useCache = false;
};

/**
 * Adds support for express.
 *
 * @public
 * @param {string} file
 * @param {object} options
 * @param {function} fn
 */

odesza.__express = function(file, options, fn) {
  try {
    return fn(null, odesza.renderFile(file, options));
  } catch (e) {
    return fn(e);
  }
};

/**
 * Returns an object of keyword statements for a given template string.
 *
 * @private
 * @param {string} template The template string to find keywords in.
 * @return {object} An object ontaining extends, block, and include statements
 * found in the template string.
 */

function getStatements(template) {
  var s = {
    extends: [],
    block: [],
    include: []
  };
  var m;
  while ((m = re.exec(template)) != null) {
    s[m[1]].push(m[2]);
  }
  return s;
}

/**
 * Resolves the template file path, throwing an error if anything is wrong
 *
 * @private
 * @param {string} file The relative file to the file.
 * @return {string} The resolved path for the file.
 */

function resolvePath(file) {
  if (typeof file != 'string') {
    throw new TypeError('invalid file: input must be a string');
  }
  if (useCache && cache.paths[file] != null) {
    return cache.paths[file];
  }
  var resolvedPath = path.resolve(file);
  if (!fs.existsSync(resolvedPath)) {
    if (fs.existsSync(`${resolvedPath}.ode`)) {
      resolvedPath += '.ode';
    } else if (fs.existsSync(`${resolvedPath}.odesza`)) {
      resolvedPath += '.odesza';
    } else {
      throw new Error(`cannot find file with file: ${file}`);
    }
  }
  cache.paths[file] = resolvedPath;
  return resolvedPath;
}

module.exports = odesza;
<commit_msg>fix bug with blocks being substrings of each other<commit_after>/**
 * Flexible template engine powered by ES6 template strings.
 *
 * @author Wells Johnston <w@wellsjohnston.com>
 */

'use strict'

const fs = require('fs');
const vm = require('vm');
const path = require('path');
const stripComments = require('strip-comments');

const odesza = {};
const blocks = {};

const cache = {
  templates: {},
  paths: {}
};

// cache control
var useCache = true;

// matches keyword statements (block, include, extends)
const re = /(block|extends|include) ([\/\.\w]+)/g;

/**
 * Renders a template with the given variables.
 *
 * @param {string} template The template to render.
 * @param {object} options An object of key-value pairs representing the
 * variables to be used in the template.
 * @param {string} [basePath] Optional. The base path to use if extend or
 * include statements are present.
 * @return {string} The rendered template.
 */

odesza.render = function(template, options, basePath) {

  options = options && 'object' == typeof options ? options : {};

  template = stripComments(template);

  let s = getStatements(template);

  // if an extend statement is found, fill the extended template blocks in
  if (s.extends.length) {

    // only allow one extend statement
    if (s.extends.length > 1) {
      throw new Error('An odesza template can only extend one file');
    }

    // loop over block statements, putting them into memory
    s.block.forEach(block => {

      // if the block is in memory, this means there is multiple inheritence,
      // i.e. this has already extended
      if (blocks[block] != null) return;

      // gets the content between the block statements
      let start = template.indexOf(`block ${block}`) + `block ${block}`.length;
      let end = template.indexOf(`endblock`, start);

      if (end == -1) {
        throw new Error(`'endblock' statement required after ${block}`);
      }

      blocks[block] = template.substr(start, end - start).trim();
    });

    let extendPath = `${basePath}${s.extends[0]}`;
    template = odesza.renderFile(extendPath, options);
    s = getStatements(template);

  } else {
    s.block.forEach(block => {
      if (blocks[block] != null) {
        template = template.split(`block ${block}`).join(blocks[block]);
        delete blocks[block];
      } else {
        // if not in memory, it is a block statement that can be ignored
        template = template.split(`block ${block}`).join('');
      }
    });
  }

  // recursively replace each import statement with its rendered template
  s.include.forEach(statement => {
    let p = `${basePath}${statement}`;
    template = template
      .split(`include ${statement}`)
      .join(odesza.renderFile(p, options));
  });

  return vm.runInNewContext('`' + template + '`', options).trim();
};

/**
 * Renders a template file.
 *
 * @param {string} location The location to the template file.
 * @param {object} options Options passed in to render the template.
 * @return {string} The rendered template.
 */

odesza.renderFile = function(location, options) {
  var template;
  let basePath = location.substr(0, location.lastIndexOf('/') + 1);
  location = resolvePath(location);
  if (useCache && cache.templates[location] != null) {
    template = cache.templates[location];
  } else {
    template = fs.readFileSync(location).toString().trim();
    cache.templates[location] = template;
  }
  return odesza.render(template, options, basePath);
};

/**
 * Disables caching.
 *
 * @public
 */

odesza.disableCache = function() {
  useCache = false;
};

/**
 * Adds support for express.
 *
 * @public
 * @param {string} file
 * @param {object} options
 * @param {function} fn
 */

odesza.__express = function(file, options, fn) {
  try {
    return fn(null, odesza.renderFile(file, options));
  } catch (e) {
    return fn(e);
  }
};

/**
 * Returns an object of keyword statements for a given template string.
 *
 * @private
 * @param {string} template The template string to find keywords in.
 * @return {object} An object ontaining extends, block, and include statements
 * found in the template string.
 */

function getStatements(template) {
  var s = {
    extends: [],
    block: [],
    include: []
  };
  var m;
  while ((m = re.exec(template)) != null) {
    s[m[1]].push(m[2]);
  }
  s.block.sort((a, b) => {
    if (a.length > b.length) {
      return -1;
    } else if (a.length < b.length) {
      return 1;
    }
    return 0;
  });
  return s;
}

/**
 * Resolves the template file path, throwing an error if anything is wrong
 *
 * @private
 * @param {string} file The relative file to the file.
 * @return {string} The resolved path for the file.
 */

function resolvePath(file) {
  if (typeof file != 'string') {
    throw new TypeError('invalid file: input must be a string');
  }
  if (useCache && cache.paths[file] != null) {
    return cache.paths[file];
  }
  var resolvedPath = path.resolve(file);
  if (!fs.existsSync(resolvedPath)) {
    if (fs.existsSync(`${resolvedPath}.ode`)) {
      resolvedPath += '.ode';
    } else if (fs.existsSync(`${resolvedPath}.odesza`)) {
      resolvedPath += '.odesza';
    } else {
      throw new Error(`cannot find file with file: ${file}`);
    }
  }
  cache.paths[file] = resolvedPath;
  return resolvedPath;
}

module.exports = odesza;
<|endoftext|>