<commit_before>/**
 * Created by moshensky on 6/17/15.
 */
import {inject} from 'aurelia-dependency-injection';
import {Session} from './session';
import {Logger} from './logger';
import {Locale} from './locale';
import {Config} from './config';
import {Redirect} from 'aurelia-router';

@inject(Session, Logger)
export class RolesAuthorizeStep {
  constructor(session, logger) {
    this.session = session;
    this.logger = logger;
    this.locale = Locale.Repository.default;
    this.loginRoute = Config.routerAuthStepOpts.loginRoute;
  }

  run(routingContext, next) {
    if (!this.session.isUserLoggedIn() && routingContext.nextInstruction.config.route !== this.loginRoute) {
      this.logger.warn(this.locale.translate('pleaseLogin'));
      return next.cancel(new Redirect(this.loginRoute));
    }

    let canAccess = routingContext.nextInstructions.every(i => {
      if (i.config.roles) {
        return this.session.userHasAtLeastOneRole(i.config.roles);
      }

      return true;
    });

    if (canAccess === false) {
      this.logger.error(this.locale.translate('notAuthorized'));
      return next.cancel();
    }

    return next();
  }
}

@inject(Session, Logger)
export class AccessRightsAuthorizeStep {
  constructor(session, logger) {
    this.session = session;
    this.logger = logger;
    this.locale = Locale.Repository.default;
  }

  run(routingContext, next) {
    if (!this.session.isUserLoggedIn() && routingContext.nextInstruction.config.route !== this.loginRoute) {
      this.logger.warn(this.locale.translate('pleaseLogin'));
      return next.cancel(new Redirect(this.loginRoute));
    }

    let neededAccessRights = routingContext.nextInstructions.reduce((acc, i) => {
      if (i.config.accessRight) {
        return acc.push(i.config.accessRight);
      }

      return acc;
    }, []);

    let canAccess = this.session.userHasAllAccessRights(neededAccessRights);

    if (canAccess === false) {
      this.logger.error(this.locale.translate('notAuthorized'));
      return next.cancel();
    }

    return next();
  }
}
<commit_msg>Update authorize-steps.js<commit_after>/**
 * Created by moshensky on 6/17/15.
 */
import {inject} from 'aurelia-dependency-injection';
import {Session} from './session';
import {Logger} from './logger';
import {Locale} from './locale';
import {Config} from './config';
import {Redirect} from 'aurelia-router';

@inject(Session, Logger)
export class RolesAuthorizeStep {
  constructor(session, logger) {
    this.session = session;
    this.logger = logger;
    this.locale = Locale.Repository.default;
    this.loginRoute = Config.routerAuthStepOpts.loginRoute;
  }

  run(routingContext, next) {
    if (!this.session.isUserLoggedIn() && routingContext.nextInstruction.config.route !== this.loginRoute) {
      this.logger.warn(this.locale.translate('pleaseLogin'));
      return next.cancel(new Redirect(this.loginRoute));
    }

    let canAccess = routingContext.nextInstructions.every(i => {
      if (i.config.roles) {
        return this.session.userHasAtLeastOneRole(i.config.roles);
      }

      return true;
    });

    if (canAccess === false) {
      this.logger.error(this.locale.translate('notAuthorized'));
      return next.cancel();
    }

    return next();
  }
}

@inject(Session, Logger)
export class AccessRightsAuthorizeStep {
  constructor(session, logger) {
    this.session = session;
    this.logger = logger;
    this.locale = Locale.Repository.default;
  }

  run(routingContext, next) {
    if (!this.session.isUserLoggedIn() && routingContext.nextInstruction.config.route !== this.loginRoute) {
      this.logger.warn(this.locale.translate('pleaseLogin'));
      return next.cancel(new Redirect(this.loginRoute));
    }

    let neededAccessRights = routingContext.nextInstructions.reduce((acc, i) => {
      if (i.config.accessRight) {
        acc.push(i.config.accessRight);
      }

      return acc;
    }, []);

    let canAccess = this.session.userHasAllAccessRights(neededAccessRights);

    if (canAccess === false) {
      this.logger.error(this.locale.translate('notAuthorized'));
      return next.cancel();
    }

    return next();
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

const available = require('../')
const connectivity = require('connectivity')
const minimist = require('minimist')

const argv = minimist(process.argv.slice(2), {
  boolean: ['offline', 'version', 'help'],
  alias: {
    o: 'offline',
    v: 'version',
    h: 'help'
  }
})

if (argv.help) {
  runHelp()
} else {
  if (argv.offline) { // Force offline mode
    run(false)
  } else {
    connectivity(run)
  }
}

function runHelp () {
  console.log(`
Usage:
    available [optional-name] <options>

    Scan npm for available package names.

Examples:

    Print lots of possible names:
        available
        available --offline

    Check for a certain name:
        available my-cool-name
        available my-cool-name --related
        available my-cool-name --offline

Flags:
    -r, --related    Search for related module names (Uses thesaurus)
    -o, --offline    Force offline mode (Does not verify names are actually available)
    -v, --version    Show current version
    -h, --help       Show usage information
  `)
}

function run (online) {
  if (argv._[0]) {
    runCheckName(argv._[0], online)
  } else {
    runGetNames(online)
  }
}

function runGetNames (online) {
  if (!online) {
    console.error('OFFLINE MODE: Printing list of likely available names...')
  }
  available.getNames({online}, printName)
  return
}

function runCheckName (name, online) {
  available.checkName(name, {
    online,
    related: argv.related
  }, printName)
}

function printName (err, name) {
  if (err) throw err
  console.log(name)
}
<commit_msg>always treat --related as boolean argument<commit_after>#!/usr/bin/env node

const available = require('../')
const connectivity = require('connectivity')
const minimist = require('minimist')

const argv = minimist(process.argv.slice(2), {
  boolean: ['related', 'offline', 'version', 'help'],
  alias: {
    o: 'offline',
    v: 'version',
    h: 'help'
  }
})

if (argv.help) {
  runHelp()
} else {
  if (argv.offline) { // Force offline mode
    run(false)
  } else {
    connectivity(run)
  }
}

function runHelp () {
  console.log(`
Usage:
    available [optional-name] <options>

    Scan npm for available package names.

Examples:

    Print lots of possible names:
        available
        available --offline

    Check for a certain name:
        available my-cool-name
        available my-cool-name --related
        available my-cool-name --offline

Flags:
    -r, --related    Search for related module names (Uses thesaurus)
    -o, --offline    Force offline mode (Does not verify names are actually available)
    -v, --version    Show current version
    -h, --help       Show usage information
  `)
}

function run (online) {
  if (argv._[0]) {
    runCheckName(argv._[0], online)
  } else {
    runGetNames(online)
  }
}

function runGetNames (online) {
  if (!online) {
    console.error('OFFLINE MODE: Printing list of likely available names...')
  }
  available.getNames({online}, printName)
  return
}

function runCheckName (name, online) {
  available.checkName(name, {
    online,
    related: argv.related
  }, printName)
}

function printName (err, name) {
  if (err) throw err
  console.log(name)
}
<|endoftext|>


<commit_before>/*!
 * chai
 * http://chaijs.com
 * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
 * MIT Licensed
 */

/*!
 * Module dependencies.
 */

var AssertionError = require('./error')
  , util = require('./utils')
  , flag = util.flag;

/*!
 * Module export.
 */

module.exports = Assertion;

/*!
 * Assertion Constructor
 *
 * Creates object for chaining.
 *
 * @api private
 */

function Assertion (obj, msg, stack) {
  flag(this, 'ssfi', stack || arguments.callee);
  flag(this, 'object', obj);
  flag(this, 'message', msg);
}

/*!
  * ### Assertion.includeStack
  *
  * User configurable property, influences whether stack trace
  * is included in Assertion error message. Default of false
  * suppresses stack trace in the error message
  *
  *     Assertion.includeStack = true;  // enable stack on error
  *
  * @api public
  */

Assertion.includeStack = false;

Assertion.addProperty = function (name, fn) {
  util.addProperty(this.prototype, name, fn);
};

Assertion.addMethod = function (name, fn) {
  util.addMethod(this.prototype, name, fn);
};

Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
  util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
};

Assertion.overwriteProperty = function (name, fn) {
  util.overwriteProperty(this.prototype, name, fn);
};

Assertion.overwriteMethod = function (name, fn) {
  util.overwriteMethod(this.prototype, name, fn);
};

/*!
 * ### .assert(expression, message, negateMessage, expected, actual)
 *
 * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
 *
 * @name assert
 * @param {Philosophical} expression to be tested
 * @param {String} message to display if fails
 * @param {String} negatedMessage to display if negated expression fails
 * @param {Mixed} expected value (remember to check for negation)
 * @param {Mixed} actual (optional) will default to `this.obj`
 * @api private
 */

Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
  var ok = util.test(this, arguments);
  if (true !== showDiff) showDiff = false;

  if (!ok) {
    var msg = util.getMessage(this, arguments)
      , actual = util.getActual(this, arguments);
    throw new AssertionError({
        message: msg
      , actual: actual
      , expected: expected
      , stackStartFunction: (Assertion.includeStack) ? this.assert : flag(this, 'ssfi')
      , showDiff: showDiff
    });
  }
};

/*!
 * ### ._obj
 *
 * Quick reference to stored `actual` value for plugin developers.
 *
 * @api private
 */

Object.defineProperty(Assertion.prototype, '_obj',
  { get: function () {
      return flag(this, 'object');
    }
  , set: function (val) {
      flag(this, 'object', val);
    }
});
<commit_msg>lib: [Assertion] add configurable showDiff flag. #132<commit_after>/*!
 * chai
 * http://chaijs.com
 * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
 * MIT Licensed
 */

/*!
 * Module dependencies.
 */

var AssertionError = require('./error')
  , util = require('./utils')
  , flag = util.flag;

/*!
 * Module export.
 */

module.exports = Assertion;

/*!
 * Assertion Constructor
 *
 * Creates object for chaining.
 *
 * @api private
 */

function Assertion (obj, msg, stack) {
  flag(this, 'ssfi', stack || arguments.callee);
  flag(this, 'object', obj);
  flag(this, 'message', msg);
}

/*!
  * ### Assertion.includeStack
  *
  * User configurable property, influences whether stack trace
  * is included in Assertion error message. Default of false
  * suppresses stack trace in the error message
  *
  *     Assertion.includeStack = true;  // enable stack on error
  *
  * @api public
  */

Assertion.includeStack = false;

/*!
 * ### Assertion.showDiff
 *
 * User configurable property, influences whether or not
 * the `showDiff` flag should be included in the thrown
 * AssertionErrors. `false` will always be `false`; `true`
 * will be true when the assertion has requested a diff
 * be shown.
 *
 * @api public
 */

Assertion.showDiff = true;

Assertion.addProperty = function (name, fn) {
  util.addProperty(this.prototype, name, fn);
};

Assertion.addMethod = function (name, fn) {
  util.addMethod(this.prototype, name, fn);
};

Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
  util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
};

Assertion.overwriteProperty = function (name, fn) {
  util.overwriteProperty(this.prototype, name, fn);
};

Assertion.overwriteMethod = function (name, fn) {
  util.overwriteMethod(this.prototype, name, fn);
};

/*!
 * ### .assert(expression, message, negateMessage, expected, actual)
 *
 * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
 *
 * @name assert
 * @param {Philosophical} expression to be tested
 * @param {String} message to display if fails
 * @param {String} negatedMessage to display if negated expression fails
 * @param {Mixed} expected value (remember to check for negation)
 * @param {Mixed} actual (optional) will default to `this.obj`
 * @api private
 */

Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
  var ok = util.test(this, arguments);
  if (true !== showDiff) showDiff = false;
  if (true !== Assertion.showDiff) showDiff = false;

  if (!ok) {
    var msg = util.getMessage(this, arguments)
      , actual = util.getActual(this, arguments);
    throw new AssertionError({
        message: msg
      , actual: actual
      , expected: expected
      , stackStartFunction: (Assertion.includeStack) ? this.assert : flag(this, 'ssfi')
      , showDiff: showDiff
    });
  }
};

/*!
 * ### ._obj
 *
 * Quick reference to stored `actual` value for plugin developers.
 *
 * @api private
 */

Object.defineProperty(Assertion.prototype, '_obj',
  { get: function () {
      return flag(this, 'object');
    }
  , set: function (val) {
      flag(this, 'object', val);
    }
});
<|endoftext|>


<commit_before>let prevSelTab = 1;
let currSelTab = 1;

browser.tabs.onActivated.addListener((activeInfo) => {
  prevSelTab = currSelTab;
  currSelTab = activeInfo.tabId;
});

const closeTab = (id) => {
  return browser.tabs.remove(id);
};

const reopenTab = () => {
  return browser.sessions.getRecentlyClosed({
    maxResults: 1
  }).then((sessions) => {
    if (sessions.length === 0) {
      return;
    }
    let session = sessions[0];
    if (session.tab) {
      return browser.sessions.restore(session.tab.sessionId);
    }
    return browser.sessions.restore(session.window.sessionId);
  });
};

const selectAt = (index) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    if (tabs.length < 2) {
      return;
    }
    if (index < 0 || tabs.length <= index) {
      throw new RangeError(`tab ${index + 1} does not exist`);
    }
    let id = tabs[index].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectByKeyword = (current, keyword) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let matched = tabs.filter((t) => {
      return t.url.includes(keyword) || t.title.includes(keyword);
    });

    if (matched.length === 0) {
      throw new RangeError('No matching buffer for ' + keyword);
    }
    for (let tab of matched) {
      if (tab.index > current.index) {
        return browser.tabs.update(tab.id, { active: true });
      }
    }
    return browser.tabs.update(matched[0].id, { active: true });
  });
};

const getCompletions = (keyword) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let matched = tabs.filter((t) => {
      return t.url.includes(keyword) || t.title.includes(keyword);
    });
    return matched;
  });
};

const selectPrevTab = (current, count) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    if (tabs.length < 2) {
      return;
    }
    let select = (current - count + tabs.length) % tabs.length;
    let id = tabs[select].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectNextTab = (current, count) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    if (tabs.length < 2) {
      return;
    }
    let select = (current + count) % tabs.length;
    let id = tabs[select].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectFirstTab = () => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let id = tabs[0].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectLastTab = () => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let id = tabs[tabs.length - 1].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectPrevSelTab = () => {
  return browser.tabs.update(prevSelTab, { active: true });
};

const reload = (current, cache) => {
  return browser.tabs.reload(
    current.id,
    { bypassCache: cache }
  );
};

const updateTabPinned = (current, pinned) => {
  return browser.tabs.query({ currentWindow: true, active: true })
    .then(() => {
      return browser.tabs.update(current.id, { pinned: pinned });
    });
};

const toggleTabPinned = (current) => {
  updateTabPinned(current, !current.pinned);
};

const duplicate = (id) => {
  return browser.tabs.duplicate(id);
};

export {
  closeTab, reopenTab, selectAt, selectByKeyword, getCompletions,
  selectPrevTab, selectNextTab, selectFirstTab, selectLastTab, selectPrevSelTab,
  reload, updateTabPinned, toggleTabPinned, duplicate
};
<commit_msg>Fix visible links test<commit_after>let prevSelTab = 1;
let currSelTab = 1;

browser.tabs.onActivated.addListener((activeInfo) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    prevSelTab = currSelTab;
    currSelTab = activeInfo.tabId;
  });
});

const closeTab = (id) => {
  return browser.tabs.remove(id);
};

const reopenTab = () => {
  return browser.sessions.getRecentlyClosed({
    maxResults: 1
  }).then((sessions) => {
    if (sessions.length === 0) {
      return;
    }
    let session = sessions[0];
    if (session.tab) {
      return browser.sessions.restore(session.tab.sessionId);
    }
    return browser.sessions.restore(session.window.sessionId);
  });
};

const selectAt = (index) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    if (tabs.length < 2) {
      return;
    }
    if (index < 0 || tabs.length <= index) {
      throw new RangeError(`tab ${index + 1} does not exist`);
    }
    let id = tabs[index].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectByKeyword = (current, keyword) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let matched = tabs.filter((t) => {
      return t.url.includes(keyword) || t.title.includes(keyword);
    });

    if (matched.length === 0) {
      throw new RangeError('No matching buffer for ' + keyword);
    }
    for (let tab of matched) {
      if (tab.index > current.index) {
        return browser.tabs.update(tab.id, { active: true });
      }
    }
    return browser.tabs.update(matched[0].id, { active: true });
  });
};

const getCompletions = (keyword) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let matched = tabs.filter((t) => {
      return t.url.includes(keyword) || t.title.includes(keyword);
    });
    return matched;
  });
};

const selectPrevTab = (current, count) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    if (tabs.length < 2) {
      return;
    }
    let select = (current - count + tabs.length) % tabs.length;
    let id = tabs[select].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectNextTab = (current, count) => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    if (tabs.length < 2) {
      return;
    }
    let select = (current + count) % tabs.length;
    let id = tabs[select].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectFirstTab = () => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let id = tabs[0].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectLastTab = () => {
  return browser.tabs.query({ currentWindow: true }).then((tabs) => {
    let id = tabs[tabs.length - 1].id;
    return browser.tabs.update(id, { active: true });
  });
};

const selectPrevSelTab = () => {
  return browser.tabs.update(prevSelTab, { active: true });
};

const reload = (current, cache) => {
  return browser.tabs.reload(
    current.id,
    { bypassCache: cache }
  );
};

const updateTabPinned = (current, pinned) => {
  return browser.tabs.query({ currentWindow: true, active: true })
    .then(() => {
      return browser.tabs.update(current.id, { pinned: pinned });
    });
};

const toggleTabPinned = (current) => {
  updateTabPinned(current, !current.pinned);
};

const duplicate = (id) => {
  return browser.tabs.duplicate(id);
};

export {
  closeTab, reopenTab, selectAt, selectByKeyword, getCompletions,
  selectPrevTab, selectNextTab, selectFirstTab, selectLastTab, selectPrevSelTab,
  reload, updateTabPinned, toggleTabPinned, duplicate
};
<|endoftext|>


<commit_before>/* Script that allows the user to select a package and writes
 * the selection to a file that can be loaded via the source
 * command. This allows it to be used in combination with bash
 * scripts.
 */

var smartdc = require('smartdc');
var url = require('url');
var List = require('term-list');
var util = require('util');
var fs = require('fs');

var common = require('smartdc/lib/cli_common');

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function (str) {
        return !this.indexOf(str);
    }
}

// --- Globals

var Options = {
    'account': String,
    'debug': Boolean,
    'help': Boolean,
    'keyId': String,
    'url': url,
    'version': Boolean,
    'verbose': Boolean,
    'user': String,
    'role': String
};

var ShortOptions = {
    'a': ['--account'],
    'd': ['--debug'],
    'h': ['--help'],
    '?': ['--help'],
    'k': ['--keyId'],
    'u': ['--url'],
    'v': ['--verbose'],
    'A': ['--user']
};

var usageStr = common.buildUsageString(Options);
usageStr += common.buildDetailedUsageString(Options);

var list = new List({ marker: '\033[36m› \033[0m', markerLength: 2 });

common.parseArguments(Options, ShortOptions, function (parsed) {
    var client = common.newClient(parsed);
    var output = parsed.argv.remain[0];
    var varname = parsed.argv.remain[1];
    var defaultPkg = parsed.argv.remain[2];

    list.on('keypress', function(key, item) {
        switch (key.name) {
            case 'return':
                list.stop();
                fs.open(output, 'a', function(err, data) {
                    if (err) {
                        console.error(err);
                    } else {
                        var line = util.format("%s=\"%s\"\n", varname, item);
                        fs.write(data, line);
                    }
                });
                break;
        }
    });

    var callback = function (err, obj) {
        if (err) {
            if (err.statusCode === 410) {
                console.error('Object is Gone (410)');
            } else {
                printErr(err);
            }

            process.exit(3);
        }

        var sortPackages = function(a, b) {
            return parseInt(a.memory) - parseInt(b.memory);
        };

        if (obj && process.stdout.isTTY) {
            var filtered = obj.filter(function(item) {
                return item.name && item.name.startsWith('t4');
            }).sort(sortPackages);

            if (filtered.length == 0) {
                filtered = obj.sort(sortPackages);
            }

            for (var key in filtered) {
                var item = filtered[key];
                var maxPad = 30;
                var spaces = maxPad - item.name.length;
                var spaceString = spaces > 0 ? Array(spaces).join(' ') : ' ';
                var defaulty = item.name == defaultPkg ? '*' : ' ';

                var display = util.format("%s%s%s [%sM]",
                    defaulty, item.name, spaceString, item.memory);

                list.add(item.id, display);

                // This moves the cursor to the default value
                if (item.name == defaultPkg) {
                    list.select(item.id);
                }

                list.start();
                console.log("Please select a package");
            }
        // detect if we are in a non-interactive terminal and just choose the default
        } else if (obj && !process.stdout.isTTY) {
            for (var key in obj) {
                var item = obj[key];

                if (item.name == defaultPkg) {
                    list.add(item.id, defaultPkg);
                    break;
                }
            }

            list._events.keypress({ name: 'return' }, item.id);
        }
    }

    client.listPackages(callback, 'hello');
}, usageStr);<commit_msg>Fixed issue with arrows not working.<commit_after>/* Script that allows the user to select a package and writes
 * the selection to a file that can be loaded via the source
 * command. This allows it to be used in combination with bash
 * scripts.
 */

var smartdc = require('smartdc');
var url = require('url');
var List = require('term-list');
var util = require('util');
var fs = require('fs');

var common = require('smartdc/lib/cli_common');

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function (str) {
        return !this.indexOf(str);
    }
}

// --- Globals

var Options = {
    'account': String,
    'debug': Boolean,
    'help': Boolean,
    'keyId': String,
    'url': url,
    'version': Boolean,
    'verbose': Boolean,
    'user': String,
    'role': String
};

var ShortOptions = {
    'a': ['--account'],
    'd': ['--debug'],
    'h': ['--help'],
    '?': ['--help'],
    'k': ['--keyId'],
    'u': ['--url'],
    'v': ['--verbose'],
    'A': ['--user']
};

var usageStr = common.buildUsageString(Options);
usageStr += common.buildDetailedUsageString(Options);

var list = new List({ marker: '\033[36m› \033[0m', markerLength: 2 });

common.parseArguments(Options, ShortOptions, function (parsed) {
    var client = common.newClient(parsed);
    var output = parsed.argv.remain[0];
    var varname = parsed.argv.remain[1];
    var defaultPkg = parsed.argv.remain[2];

    list.on('keypress', function(key, item) {
        switch (key.name) {
            case 'return':
                list.stop();
                fs.open(output, 'a', function(err, data) {
                    if (err) {
                        console.error(err);
                    } else {
                        var line = util.format("%s=\"%s\"\n", varname, item);
                        fs.write(data, line);
                    }
                });
                break;
        }
    });

    var callback = function (err, obj) {
        if (err) {
            if (err.statusCode === 410) {
                console.error('Object is Gone (410)');
            } else {
                printErr(err);
            }

            process.exit(3);
        }

        var sortPackages = function(a, b) {
            return parseInt(a.memory) - parseInt(b.memory);
        };

        if (obj && process.stdout.isTTY) {
            var filtered = obj.filter(function(item) {
                return item.name && item.name.startsWith('t4');
            }).sort(sortPackages);

            if (filtered.length == 0) {
                filtered = obj.sort(sortPackages);
            }

            for (var key in filtered) {
                var item = filtered[key];
                var maxPad = 30;
                var spaces = maxPad - item.name.length;
                var spaceString = spaces > 0 ? Array(spaces).join(' ') : ' ';
                var defaulty = item.name == defaultPkg ? '*' : ' ';

                var display = util.format("%s%s%s [%sM]",
                    defaulty, item.name, spaceString, item.memory);

                console.log(item.id);

                list.add(item.id, display);

                // This moves the cursor to the default value
                if (item.name == defaultPkg) {
                    list.select(item.id);
                }
            }

            list.start();
            console.log("Please select a package");
        // detect if we are in a non-interactive terminal and just choose the default
        } else if (obj && !process.stdout.isTTY) {
            for (var key in obj) {
                var item = obj[key];

                if (item.name == defaultPkg) {
                    list.add(item.id, defaultPkg);
                    break;
                }
            }

            list._events.keypress({ name: 'return' }, item.id);
        }
    }

    client.listPackages(callback);
}, usageStr);<|endoftext|>


<commit_before>'use strict';

const assert = require('assert');
const baumWelch = require('./baumWelch');

test1();

function test1() {
    const observations = 'AAATTTTATTACGTTTAGTAGAAGAGAAAGGTAAACATGATGG';
    const initTransitions = {
        I: { I: 0.5, A: 0.5, G1: 0.0, G2: 0.0, G3: 0.0, T: 0.0 },
        A: { I: 0.0, A: 0.0, G1: 1.0, G2: 0.0, G3: 0.0, T: 0.0 },
        G1: { I: 0.0, A: 0.0, G1: 0.0, G2: 1.0, G3: 0.0, T: 0.0 },
        G2: { I: 0.0, A: 0.0, G1: 0.0, G2: 0.0, G3: 1.0, T: 0.0 },
        G3: { I: 0.0, A: 0.0, G1: 0.5, G2: 0.0, G3: 0.0, T: 0.5 },
        T: { I: 1.0, A: 0.0, G1: 0.0, G2: 0.0, G3: 0.0, T: 0.0 },
    };
    const initEmissions = {
        I: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        A: { A: 1.0, T: 0.0, C: 0.0, G: 0.0 },
        G1: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        G2: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        G3: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        T: { A: 0.0, T: 1.0, C: 0.0, G: 0.0 },
    };
    const startTransProb = {
        I: 1,
        A: 0,
        G1: 0,
        G2: 0,
        G3: 0,
        T: 0,
    };
    const threshold = 0.001;

    // const expected = {
    //     transProb: {
    //         I: { I: 0.5, A: 0.5, G1: 0, G2: 0, G3: 0, T: 0 },
    //         A: { I: 0, A: 0, G1: 1, G2: 0, G3: 0, T: 0 },
    //         G1: { I: 0, A: 0, G1: 0, G2: 1, G3: 0, T: 0 },
    //         G2: { I: 0, A: 0, G1: 0, G2: 0, G3: 1, T: 0 },
    //         G3: { I: 0, A: 0, G1: 0.43055555555555564, G2: 0, G3: 0, T: 0.5694444444444444 },
    //         T: { I: 1, A: 0, G1: 0, G2: 0, G3: 0, T: 0 },
    //     },
    //     emisProb: {
    //         I: { A: 0.3942307692307693, T: 0.29807692307692313, C: 0.009615384615384618, G: 0.29807692307692313 },
    //         A: { A: 1, T: 0, C: 0, G: 0 },
    //         G1: { A: 0.36904761904761907, T: 0.25, C: 0.09126984126984129, G: 0.2896825396825397 },
    //         G2: { A: 0.36904761904761907, T: 0.25, C: 0.09126984126984129, G: 0.2896825396825397 },
    //         G3: { A: 0.36904761904761907, T: 0.25, C: 0.09126984126984129, G: 0.2896825396825397 },
    //         T: { A: 0, T: 1, C: 0, G: 0 }
    //     },
    //     lastProb: -53.447472039773395,
    // };

    const result = baumWelch(observations, initTransitions, initEmissions, startTransProb, threshold);

    // assert.deepEqual(result, expected);
}
<commit_msg>baumWelch: Testing<commit_after>'use strict';

const assert = require('assert');
const baumWelch = require('./baumWelch');

test1();

function test1() {
    const observations = 'AAATTTTATTACGTTTAGTAGAAGAGAAAGGTAAACATGATGG';
    const initTransitions = {
        I: { I: 0.5, A: 0.5, G1: 0.0, G2: 0.0, G3: 0.0, T: 0.0 },
        A: { I: 0.0, A: 0.0, G1: 1.0, G2: 0.0, G3: 0.0, T: 0.0 },
        G1: { I: 0.0, A: 0.0, G1: 0.0, G2: 1.0, G3: 0.0, T: 0.0 },
        G2: { I: 0.0, A: 0.0, G1: 0.0, G2: 0.0, G3: 1.0, T: 0.0 },
        G3: { I: 0.0, A: 0.0, G1: 0.5, G2: 0.0, G3: 0.0, T: 0.5 },
        T: { I: 1.0, A: 0.0, G1: 0.0, G2: 0.0, G3: 0.0, T: 0.0 },
    };
    const initEmissions = {
        I: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        A: { A: 1.0, T: 0.0, C: 0.0, G: 0.0 },
        G1: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        G2: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        G3: { A: 0.25, T: 0.25, C: 0.25, G: 0.25 },
        T: { A: 0.0, T: 1.0, C: 0.0, G: 0.0 },
    };
    const startTransProb = {
        I: 1,
        A: 0,
        G1: 0,
        G2: 0,
        G3: 0,
        T: 0,
    };
    const threshold = 0.001;

    const expected = {
        transProb: {
            I: { I: 0.7991604236771859, A: 0.20083957632281424, G1: 0, G2: 0, G3: 0, T: 0 },
            A: { I: 0, A: 0, G1: 1, G2: 0, G3: 0, T: 0 },
            G1: { I: 0, A: 0, G1: 0, G2: 1, G3: 0, T: 0 },
            G2: { I: 0, A: 0, G1: 0, G2: 0, G3: 1, T: 0 },
            G3: { I: 0, A: 0, G1: 0.00017410192522445187, G2: 0, G3: 0, T: 0.9998258980747755 },
            T: { I: 1, A: 0, G1: 0, G2: 0, G3: 0, T: 0 }
        },
        emisProb: {
            I: { A: 0.48557082538894436, T: 0.2286802227185041, C: 1.1225730907152437e-8, G: 0.28574894066682066 },
            A: { A: 1, T: 0, C: 0, G: 0 },
            G1: { A: 0.2319921727582478, T: 0.3269680876744538, C: 0.15402858370846173, G: 0.2870111558588368 },
            G2: { A: 0.2319921727582478, T: 0.3269680876744538, C: 0.15402858370846173, G: 0.2870111558588368 },
            G3: { A: 0.2319921727582478, T: 0.3269680876744538, C: 0.15402858370846173, G: 0.2870111558588368 },
            T: { A: 0, T: 1, C: 0, G: 0 }
        },
        lastProb: -49.402878890254605,
    };

    const result = baumWelch(observations, initTransitions, initEmissions, startTransProb, threshold);

    assert.deepEqual(result, expected);
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
/*
 * command line interface for nfd
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var exec = require('child_process').exec,
		fs 	 = require('fs');

var nscaleRoot = getUserHome() + '/.nscale';

function getUserHome() {
  return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
}

function start() {
	var logDir = nscaleRoot + '/log';
	var serverProcess = exec('nsd-server -c ' + config + ' > ' + logDir + '/server.log 2>&1 &');
	var apiProcess = exec('nsd-api -c ' + config + ' > ' + logDir + '/api.log 2>&1 &');
	var webProcess = exec('nsd-web -c ' + config + ' > ' + logDir + '/web.log 2>&1 &');
	console.log(command + " started");
}

var args = process.argv.slice(2);
var command = args[0];

if (command === 'server') {

	var action = args[1];
	if (action === 'start') {
		console.log(command + " starting..");

		var config = args[2] || nscaleRoot + '/config/config.json';

		// if config is default config then check if it exists, if not then run nsd-init before starting
		if (config === nscaleRoot + '/config/config.json' && (!fs.existsSync(config)) ) {
			var initProcess = exec('nsd-init');
			initProcess.on('exit', function () {
    		start();
			});
		} else {
			start();
		}

	} else if (action === 'stop') {

		console.log(command + " stopping..");

		exec("kill $(ps aux | grep [n]sd-web | awk '{print $2}')");
		exec("kill $(ps aux | grep [n]sd-api | awk '{print $2}')");
		exec("kill $(ps aux | grep [n]sd-server | awk '{print $2}')");

		console.log(command + " stopped");

	} else if (action === 'logs') {

		var logDir = nscaleRoot + '/log';
		var logfile = args[2] || 'server.log';
		var logProcess = exec('tail -f ' + logDir + '/' + logfile);
		logProcess.stdout.pipe(process.stdout)

	} else {
		console.log("'" + command + " " + action + "' command not supported.");
	}

} else {
	require('../lib/main')(process.argv.slice(2));
}

<commit_msg>Reformat and satisfy JSHint in `bin/nsd.js`<commit_after>#!/usr/bin/env node
/*
 * command line interface for nfd
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var exec = require('child_process').exec,
    fs   = require('fs');

var args = process.argv.slice(2);
var command = args[0];

function getUserHome() {
  return process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
}

var nscaleRoot = getUserHome() + '/.nscale';
var config = args[2] || nscaleRoot + '/config/config.json';

function start() {
  var logDir = nscaleRoot + '/log';
  var serverProcess = exec('nsd-server -c ' + config + ' > ' + logDir + '/server.log 2>&1 &');
  exec('nsd-api -c ' + config + ' > ' + logDir + '/api.log 2>&1 &');
  exec('nsd-web -c ' + config + ' > ' + logDir + '/web.log 2>&1 &');
  console.log(command + ' started');
}

if (command === 'server') {

  var action = args[1];
  if (action === 'start') {
    console.log(command + ' starting..');

    // if config is default config then check if it exists, if not then run nsd-init before starting
    if (config === nscaleRoot + '/config/config.json' && (!fs.existsSync(config)) ) {
      var initProcess = exec('nsd-init');
      initProcess.on('exit', function () {
        start();
      });
    }
    else {
      start();
    }

  }
  else if (action === 'stop') {

    console.log(command + ' stopping..');

    exec('kill $(ps aux | grep [n]sd-web | awk \'{print $2}\')');
    exec('kill $(ps aux | grep [n]sd-api | awk \'{print $2}\')');
    exec('kill $(ps aux | grep [n]sd-server | awk \'{print $2}\')');

    console.log(command + ' stopped');

  }
  else if (action === 'logs') {

    var logDir = nscaleRoot + '/log';
    var logfile = args[2] || 'server.log';
    var logProcess = exec('tail -f ' + logDir + '/' + logfile);
    logProcess.stdout.pipe(process.stdout);

  }
  else {
    console.log('\'' + command + ' ' + action + '\' command not supported.');
  }

} else {
  require('../lib/main')(process.argv.slice(2));
}
<|endoftext|>


<commit_before>Push.setBadge = function(count) {
  // XXX: Not implemented
};

var isConfigured = false;

Push.Configure = function(options) {
  var self = this;

  options = options || {};

  // check(options, {
  //   gcm: Match.Optional(Match.ObjectIncluding({
  //     projectNumber: String
  //   })),
  //   apn: Match.Optional(Match.ObjectIncluding({
  //     webServiceUrl: String,
  //     websitePushId: String
  //   })),
  // });

  // Block multiple calls
  if (isConfigured)
    throw new Error('Push.Configure should not be called more than once!');

  isConfigured = true;

  // Add debug info
  if (Push.debug) console.log('Push.Configure', options);

  // Client-side security warnings
  checkClientSecurity(options);

  // Start token updates
  initPushUpdates(options.appName);

  // Add support for the raix:iframe push solution Deprecate this at some
  // point mid aug 2015
  if (options.iframe) {
    // Rig iframe event listeners
    options.iframe.addEventListener('deviceready', function() {

      options.iframe.addEventListener('pushLaunch', function(evt) {
        // Reformat into new event
        self.emit('startup', evt);
      });

      options.iframe.addEventListener('pushSuccess', function(evt) {
        // Reformat into new event
        self.emit('register', evt.success);
      });

      options.iframe.addEventListener('pushToken', function(evt) {
        if (evt.androidToken) {
          // Format the android token
          Push.emit('token', { gcm: evt.androidToken });
        } else if (evt.iosToken) {
          // Format the ios token
          Push.emit('token', { apn: evt.iosToken });
        }
      });

      options.iframe.addEventListener('pushError', function(evt) {
        Push.emit('error', { type: 'cordova.browser', error: evt.error || evt });
      });

    });
  } // EO options iframe

  if (typeof chrome !== 'undefined' && chrome.gcm) {
    // chrome.gcm api is supported!
    // https://developer.chrome.com/extensions/gcm

    // Set max message size
    // chrome.gcm.MAX_MESSAGE_SIZE = 4096;

    if (options.gcm.projectNumber)
      chrome.gcm.register(options.gcm.projectNumber, function(token) {
        if (token) {
          self.emit('token', { gcm: token });
        } else {
          // Error
          self.emit('error', { type: 'gcm.browser', error: 'Access denied' });
        }
      });

  } else if ('safari' in window && 'pushNotification' in window.safari) {
    // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html#//apple_ref/doc/uid/TP40013225-CH3-SW1

    if (options.apn) {

      Meteor.startup(function() {
        // Ensure that the user can receive Safari Push Notifications.
        var permissionData = window.safari.pushNotification.permission(options.apn.websitePushId);
        checkRemotePermission(permissionData);
      });

      var checkRemotePermission = function (permissionData) {
          if (permissionData.permission === 'default') {
              // This is a new web service URL and its validity is unknown.
              window.safari.pushNotification.requestPermission(
                  options.apn.webServiceUrl, // The web service URL.
                  options.apn.websitePushId, // The Website Push ID.
                  {}, // Data that you choose to send to your server to help you identify the user.
                  checkRemotePermission         // The callback function.
              );
          }
          else if (permissionData.permission === 'denied') {
              // alert('denied');
              // The user said no.
              self.emit('error', { type: 'apn.browser', error: 'Access denied' });
          }
          else if (permissionData.permission === 'granted') {
              // alert('granted');
              // The web service URL is a valid push provider, and the user said yes.
              // permissionData.deviceToken is now available to use.
              self.emit('token', { apn: permissionData.deviceToken });
          }
      };

    }

  } else if (navigator && navigator.push && navigator.push.register && navigator.mozSetMessageHandler) {
    // check navigator.mozPush should be enough?
    // https://wiki.mozilla.org/WebAPI/SimplePush

    var channel = 'push';

    // Store the pushEndpoint
    var pushEndpoint;

    Meteor.startup(function() {
      setupAppRegistrations();
    });

    function setupAppRegistrations() {
      // Issue a register() call
      // to register to listen for a notification,
      // you simply call push.register
      // Here, we'll register a channel for "email" updates.
      // Channels can be for anything the app would like to get notifications for.
      var requestAccess = navigator.push.register();

      requestAccess.onsuccess = function(e) {
        // Store the endpoint
        pushEndpoint = e.target.result;

        self.emit('token', {
          SimplePush: {
            channel: channel,
            endPoint: pushEndpoint
          }
        });
      }

    }

    // Once we've registered, the AppServer can send version pings to the EndPoint.
    // This will trigger a 'push' message to be sent to this handler.
    navigator.mozSetMessageHandler('push', function(message) {
        if (message.pushEndpoint == pushEndpoint) {
          // Did we launch or were we already running?
          self.emit('startup', message);
        }
      });

    // // to unregister, you simply call..
    // AppFramework.addEventListener('user-logout', function() {
    //   navigator.push.unregister(pushEndpoint);
    // });

    // error recovery mechanism
    // will be called very rarely, but application
    // should register again when it is called
    navigator.mozSetMessageHandler('register', function(e) {
      setupAppRegistrations();
    });

  }

};

/*
TODO:

add event listener api

*/
<commit_msg>Add updated iframe code for consistency<commit_after>var onNotification = function(notification) {
  // alert('onNotification' + JSON.stringify(notification));

  // Emit alert event - this requires the app to be in forground
  if (notification.message && notification.foreground)
    Push.emit('alert', notification);

  // Emit sound event
  if (notification.sound) Push.emit('sound', notification);

  // Emit badge event
  if (notification.badge) Push.emit('badge', notification);

  // If within thres
  if (notification.open) {
    Push.emit('startup', notification);
  } else {
    Push.emit('message', notification);
  }
};

Push.setBadge = function(count) {
  // XXX: Not implemented
};

var isConfigured = false;

Push.Configure = function(options) {
  var self = this;

  options = options || {};

  // check(options, {
  //   gcm: Match.Optional(Match.ObjectIncluding({
  //     projectNumber: String
  //   })),
  //   apn: Match.Optional(Match.ObjectIncluding({
  //     webServiceUrl: String,
  //     websitePushId: String
  //   })),
  // });

  // Block multiple calls
  if (isConfigured)
    throw new Error('Push.Configure should not be called more than once!');

  isConfigured = true;

  // Add debug info
  if (Push.debug) console.log('Push.Configure', options);

  // Client-side security warnings
  checkClientSecurity(options);

  // Start token updates
  initPushUpdates(options.appName);

  // Add support for the raix:iframe push solution Deprecate this at some
  // point mid aug 2015
  if (options.iframe) {

    var coldstart = true;
    var startupTime = new Date();
    var startupThreshold = 1000; // ms

    var _atStartup = function() {
      // If startup time is less than startupThreshold ago then lets say this is
      // at startup.
      return (new Date() - startupTime < startupThreshold);
    };

    var _parsePayload = function(value) {
      // Android actually parses payload into an object - this is not the case with
      // iOS (here is it just a string)
      if (value !== ''+value) value = JSON.stringify(value);

      // Run the string through ejson
      try {
        return EJSON.parse(value);
      } catch(err) {
        return { error: err };
      }
    };

    // Rig iframe event listeners
    options.iframe.addEventListener('deviceready', function() {

      // Maintain properties

      // At initial startup set startup time
      startupTime = new Date();

      // Update flag if app coldstart
      options.iframe.addEventListener("pause", function() {
        coldstart = false;
      }, false);

      options.iframe.addEventListener('resume', function() {
        // Reset startup time at resume
        startupTime = new Date();
      });

      // EO Maintain properties

      options.iframe.addEventListener('pushLaunch', function(e) {

        if (e.event == 'message') {
          // Android event

          var sound = e.soundname || e.payload.sound;

          // Only prefix sound if actual text found
          if (sound && sound.length) sound = '/android_asset/www/' + sound;

          // XXX: Investigate if we need more defaults
          var unifiedMessage = {
            message: e.payload.message || e.msg || '',
            sound: sound,
            badge: e.payload.msgcnt,
            // Coldstart on android is a bit inconsistent - its only set when the
            // notification opens the app
            coldstart: (e.coldstart === !!e.coldstart) ? e.coldstart : coldstart,
            background: !e.foreground,
            foreground: !!e.foreground,
            // open: _atStartup(),  // This is the iOS implementation
            open: (e.coldstart === !!e.coldstart), // If set true / false its an open event
            type: 'gcm.cordova'
          };

          // If payload.ejson this is an object - we hand it over to parsePayload,
          // parsePayload will do the convertion for us
          if (e.payload.ejson) unifiedMessage.payload = _parsePayload(e.payload.ejson);

          // Trigger notification
          onNotification(unifiedMessage);

        } else {
          // iOS event
          var sound = e.sound;

          // Only prefix sound if actual text found
          if (sound && sound.length) sound = '' + sound;

          // XXX: Investigate if we need more defaults
          var unifiedMessage = {
            message: e.alert,
            sound: sound,
            badge: e.badge,
            coldstart: coldstart,
            background: !e.foreground,
            foreground: !!e.foreground,
            open: _atStartup(),
            type: 'apn.cordova'
          };

          // E.ejson should be a string - we send it directly to payload
          if (e.ejson) unifiedMessage.payload = _parsePayload(e.ejson);

          // Trigger notification
          onNotification(unifiedMessage);

        }

      });

      options.iframe.addEventListener('pushSuccess', function(evt) {
        // Reformat into new event
        self.emit('register', evt.success);
      });

      options.iframe.addEventListener('pushToken', function(evt) {
        if (evt.androidToken) {
          // Format the android token
          Push.emit('token', { gcm: evt.androidToken });
        } else if (evt.iosToken) {
          // Format the ios token
          Push.emit('token', { apn: evt.iosToken });
        }
      });

      options.iframe.addEventListener('pushError', function(evt) {
        Push.emit('error', { type: 'cordova.browser', error: evt.error || evt });
      });

    });
  } // EO options iframe

  if (typeof chrome !== 'undefined' && chrome.gcm) {
    // chrome.gcm api is supported!
    // https://developer.chrome.com/extensions/gcm

    // Set max message size
    // chrome.gcm.MAX_MESSAGE_SIZE = 4096;

    if (options.gcm.projectNumber)
      chrome.gcm.register(options.gcm.projectNumber, function(token) {
        if (token) {
          self.emit('token', { gcm: token });
        } else {
          // Error
          self.emit('error', { type: 'gcm.browser', error: 'Access denied' });
        }
      });

  } else if ('safari' in window && 'pushNotification' in window.safari) {
    // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html#//apple_ref/doc/uid/TP40013225-CH3-SW1

    if (options.apn) {

      Meteor.startup(function() {
        // Ensure that the user can receive Safari Push Notifications.
        var permissionData = window.safari.pushNotification.permission(options.apn.websitePushId);
        checkRemotePermission(permissionData);
      });

      var checkRemotePermission = function (permissionData) {
          if (permissionData.permission === 'default') {
              // This is a new web service URL and its validity is unknown.
              window.safari.pushNotification.requestPermission(
                  options.apn.webServiceUrl, // The web service URL.
                  options.apn.websitePushId, // The Website Push ID.
                  {}, // Data that you choose to send to your server to help you identify the user.
                  checkRemotePermission         // The callback function.
              );
          }
          else if (permissionData.permission === 'denied') {
              // alert('denied');
              // The user said no.
              self.emit('error', { type: 'apn.browser', error: 'Access denied' });
          }
          else if (permissionData.permission === 'granted') {
              // alert('granted');
              // The web service URL is a valid push provider, and the user said yes.
              // permissionData.deviceToken is now available to use.
              self.emit('token', { apn: permissionData.deviceToken });
          }
      };

    }

  } else if (navigator && navigator.push && navigator.push.register && navigator.mozSetMessageHandler) {
    // check navigator.mozPush should be enough?
    // https://wiki.mozilla.org/WebAPI/SimplePush

    var channel = 'push';

    // Store the pushEndpoint
    var pushEndpoint;

    Meteor.startup(function() {
      setupAppRegistrations();
    });

    function setupAppRegistrations() {
      // Issue a register() call
      // to register to listen for a notification,
      // you simply call push.register
      // Here, we'll register a channel for "email" updates.
      // Channels can be for anything the app would like to get notifications for.
      var requestAccess = navigator.push.register();

      requestAccess.onsuccess = function(e) {
        // Store the endpoint
        pushEndpoint = e.target.result;

        self.emit('token', {
          SimplePush: {
            channel: channel,
            endPoint: pushEndpoint
          }
        });
      }

    }

    // Once we've registered, the AppServer can send version pings to the EndPoint.
    // This will trigger a 'push' message to be sent to this handler.
    navigator.mozSetMessageHandler('push', function(message) {
        if (message.pushEndpoint == pushEndpoint) {
          // Did we launch or were we already running?
          self.emit('startup', message);
        }
      });

    // // to unregister, you simply call..
    // AppFramework.addEventListener('user-logout', function() {
    //   navigator.push.unregister(pushEndpoint);
    // });

    // error recovery mechanism
    // will be called very rarely, but application
    // should register again when it is called
    navigator.mozSetMessageHandler('register', function(e) {
      setupAppRegistrations();
    });

  }

};

/*
TODO:

add event listener api

*/
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict'

const opener = require('opener')
const node = process.execPath
const fs = require('fs')
const fg = require('foreground-child')
const spawn = require('child_process').spawn
const nycBin = require.resolve(
  'nyc/' + require('nyc/package.json').bin.nyc
)
const glob = require('glob')
const isexe = require('isexe')
const yaml = require('tap-yaml')
const path = require('path')
const exists = require('fs-exists-cached').sync
const os = require('os')
const isTTY = process.stdin.isTTY || process.env._TAP_IS_TTY === '1'
const tsNode = require.resolve(
  'ts-node/' + require('ts-node/package.json').bin['ts-node']
)

const main = options => {
  // tell chalk if we want color or not.
  if (!options.color)
    process.argv.push('--no-color')
  else {
    const c = process.argv.indexOf('--no-color')
    if (c !== -1)
      process.argv.splice(c, 1)
  }

  const rc = parseRcFile(options.rcfile)
  for (let i in rc) {
    if (!options._.explicit.has(i))
      options[i] = rc[i]
  }

  if (options.reporter === null)
    options.reporter = options.color ? 'classic' : 'tap'

  if (options['dump-config']) {
    console.log(yaml.stringify(Object.keys(options).filter(k =>
      k !== 'dump-config' && k !== '_' && !/^[A-Z_]+$/.test(k)
    ).sort().reduce((set, k) =>
      (set[k] = options[k], set), {})))
    return
  }

  if (options.versions) {
    return console.log(yaml.stringify({
      tap: require('../package.json').version,
      'tap-parser': require('tap-parser/package.json').version,
      nyc: require('nyc/package.json').version,
    }))
  }

  if (options.version)
    return console.log(require('../package.json').version)

  if (options['parser-version'])
    return console.log(require('tap-parser/package.json').version)

  if (options['nyc-version'])
    return console.log(require('nyc/package.json').version)

  if (options['nyc-help'])
    return nycHelp()

  options.files = globFiles(options._)

  process.stdout.on('error', er => {
    /* istanbul ignore else */
    if (er.code === 'EPIPE')
      process.exit()
    else
      throw er
  })

  options.grep = options.grep.map(strToRegExp)

  // this is only testable by escaping from the covered environment
  /* istanbul ignore next */
  if ((options._.explicit.has('coverage-report') ||
       options._.explicit.has('check-coverage')) &&
      options.files.length === 0)
    return runCoverageReportOnly(options)

  if (options.files.length === 0) {
    if (isTTY) {
      console.error(
        `Reading TAP data from stdin
(use '-' argument to suppress this notice or -h for usage)`)
    }
    options.files.push('-')
  }

  if (options.files.length === 1 && options.files[0] === '-') {
    if (options.coverage)
      console.error('Coverage disabled (stdin cannot be instrumented)')
    setupTapEnv(options)
    stdinOnly(options)
    return
  }

  /* istanbul ignore next */
  if (options.coverage && !process.env.NYC_CONFIG)
    respawnWithCoverage(options)
  else {
    setupTapEnv(options)
    runTests(options)
  }
}

/* istanbul ignore next */
const nycReporter = options =>
  options['coverage-report'] === 'html' ? 'lcov'
  : (options['coverage-report'] || 'text')

/* istanbul ignore next */
const runNyc = (cmd, programArgs, options, spawnOpts) => {
  const reporter = nycReporter(options)

  const args = [
    nycBin,
    ...cmd,
    ...(options['show-process-tree'] ? ['--show-process-tree'] : []),
    '--cache=true',
    '--branches=' + options.branches,
    '--functions=' + options.functions,
    '--lines=' + options.lines,
    '--statements=' + options.statements,
    '--reporter=' + reporter,
    ...options['nyc-arg'],
  ]
  if (options['check-coverage'])
    args.push('--check-coverage')

  args.push.apply(args, programArgs)

  const child = fg(node, args, spawnOpts)

  if (reporter === 'lcov' && options.browser) {
    child.removeAllListeners('close')
    child.on('close', (code, signal) =>
      openHtmlCoverageReport(options, code, signal))
  }
  return child
}

/* istanbul ignore next */
const runCoverageReportOnly = options => {
  runNyc(['report'], [], options)
}

/* istanbul ignore next */
const pipeToCoveralls = options => {

  const reporter = runNyc(['report'], [], {
    ...options,
    'coverage-report': 'text-lcov'
  }, {
    stdio: [0, 'pipe', 2]
  })
  reporter.removeAllListeners('close')

  /* istanbul ignore next */
  const bin = process.env.__TAP_COVERALLS_TEST__
    || require.resolve('coveralls/bin/coveralls.js')

  const ca = fg(node, [bin], { stdio: ['pipe', 1, 2] })
  reporter.stdout.pipe(ca.stdin)
}

/* istanbul ignore next */
const respawnWithCoverage = options => {
  runNyc([], [
    '--',
    node,
    ...process.execArgv,
    ...process.argv.slice(1)
  ], options)
}

/* istanbul ignore next */
const openHtmlCoverageReport = (options, code, signal) => {
  opener('coverage/lcov-report/index.html')
  if (signal) {
    setTimeout(() => {}, 200)
    process.kill(process.pid, signal)
  } else if (code) {
    process.exitCode = code
  }
}

const nycHelp = _ => fg(node, [nycBin, '--help'])

const setupTapEnv = options => {
  process.env.TAP_TIMEOUT = options.timeout
  if (options.color)
    process.env.TAP_COLORS = '1'
  else
    process.env.TAP_COLORS = '0'

  if (options.snapshot)
    process.env.TAP_SNAPSHOT = '1'

  if (options.bail)
    process.env.TAP_BAIL = '1'

  if (options.invert)
    process.env.TAP_GREP_INVERT = '1'

  if (options.grep.length)
    process.env.TAP_GREP = options.grep.map(p => p.toString())
      .join('\n')

  if (options.only)
    process.env.TAP_ONLY = '1'
}

const globFiles = files => files.reduce((acc, f) =>
  acc.concat(f === '-' ? f : glob.sync(f, { nonull: true })), [])

const makeReporter = options =>
  new (require('tap-mocha-reporter'))(options.reporter)

const stdinOnly = options => {
  // if we didn't specify any files, then just passthrough
  // to the reporter, so we don't get '/dev/stdin' in the suite list.
  // We have to pause() before piping to switch streams2 into old-mode
  process.stdin.pause()
  const reporter = makeReporter(options)
  process.stdin.pipe(reporter)
  if (options['output-file'] !== null)
    process.stdin.pipe(fs.createWriteStream(options['output-file']))
  process.stdin.resume()
}

const readSaveFile = options => {
  if (options.save)
    try {
      const s = fs.readFileSync(options.save, 'utf8').trim()
      if (s)
        return s.split('\n')
    } catch (er) {}

  return null
}

const saveFails = (options, tap) => {
  if (!options.save)
    return

  let fails = []
  const successes = []
  tap.on('result', res => {
    // we will continue to re-run todo tests, even though they're
    // not technically "failures".
    if (!res.ok && !res.extra.skip)
      fails.push(res.extra.file)
    else
      successes.push(res.extra.file)
  })

  const save = () => {
    fails = fails.reduce((set, f) => {
      f = f.replace(/\\/g, '/')
      if (set.indexOf(f) === -1)
        set.push(f)
      return set
    }, [])

    if (!fails.length)
      try {
        fs.unlinkSync(options.save)
      } catch (er) {}
    else
      try {
        fs.writeFileSync(options.save, fails.join('\n') + '\n')
      } catch (er) {}
  }

  tap.on('bailout', reason => {
    // add any pending test files to the fails list.
    fails.push.apply(fails, options.files.filter(file =>
      successes.indexOf(file) === -1))
    save()
  })

  tap.on('end', save)
}

const filterFiles = (files, saved, parallelOk) =>
  files.filter(file =>
    path.basename(file) === 'tap-parallel-ok' ?
      ((parallelOk[path.resolve(path.dirname(file))] = true), false)
    : path.basename(file) === 'tap-parallel-not-ok' ?
      parallelOk[path.resolve(path.dirname(file))] = false
    : onSavedList(saved, file)
  )

// check if the file is on the list, or if it's a parent dir of
// any items that are on the list.
const onSavedList = (saved, file) =>
  !saved || !saved.length ? true
  : saved.indexOf(file) !== -1 ? true
  : saved.some(f => f.indexOf(file + '/') === 0)

const isParallelOk = (parallelOk, file) => {
  const dir = path.resolve(path.dirname(file))
  return (dir in parallelOk) ? parallelOk[dir]
    : exists(dir + '/tap-parallel-ok')
    ? parallelOk[dir] = true
    : exists(dir + '/tap-parallel-not-ok')
    ? parallelOk[dir] = false
    : dir.length >= process.cwd().length
    ? isParallelOk(parallelOk, dir)
    : true
}

const runAllFiles = (options, saved, tap) => {
  let doStdin = false
  let parallelOk = Object.create(null)

  options.files = filterFiles(options.files, saved, parallelOk)
  let tapChildId = 0

  for (let i = 0; i < options.files.length; i++) {
    const opt = {}
    const file = options.files[i]

    // Pick up stdin after all the other files are handled.
    if (file === '-') {
      doStdin = true
      continue
    }

    let st
    try {
      st = fs.statSync(file)
    } catch (er) {
      continue
    }

    if (options.timeout)
      opt.timeout = options.timeout * 1000

    opt.file = file
    opt.childId = tapChildId++
    if (st.isDirectory()) {
      const dir = filterFiles(fs.readdirSync(file).map(f =>
        file + '/' + f), saved, parallelOk)
      options.files.splice(i, 1, ...dir)
      i--
    } else {
      if (options.jobs > 1)
        opt.buffered = isParallelOk(parallelOk, file) !== false

      if (file.match(/\.m?js$/)) {
        const args = [
          ...(options.esm ? ['-r', 'esm'] : []),
          ...options['node-arg'],
          file,
          ...options['test-arg']
        ]
        tap.spawn(node, args, opt, file)
      } else if (file.match(/\.ts$/)) {
        const args = [
          ...options['node-arg'],
          file,
          ...options['test-arg']
        ]
        tap.spawn(tsNode, args, opt, file)
      } else if (isexe.sync(options.files[i]))
        tap.spawn(options.files[i], options['test-arg'], opt, file)
    }
  }

  if (doStdin)
    tap.stdin()
}

const runTests = options => {
  const saved = readSaveFile(options)

  // At this point, we know we need to use the tap root,
  // because there are 1 or more files to spawn.
  const tap = require('../lib/tap.js')
  if (options.comments) {
    const onComment = c => {
      if (!c.match(/^# (time=[0-9\.]+m?s|Subtest(: .+))\n$/))
        console.error(c.substr(2).trim())
    }
    const onChild = p => {
      p.on('comment', onComment)
      p.on('child', onChild)
    }
    tap.parser.on('comment', onComment)
    tap.parser.on('child', onChild)
  }

  tap.runOnly = false

  // greps are passed to children, but not the runner itself
  tap.grep = []
  tap.jobs = options.jobs
  tap.patchProcess()

  // if not -Rtap, then output what the user wants.
  // otherwise just dump to stdout
  tap.pipe(options.reporter === 'tap' ? process.stdout: makeReporter(options))

  // need to replay the first version line, because the previous
  // line will have flushed it out to stdout or the reporter already.
  if (options['output-file'] !== null)
    tap.pipe(fs.createWriteStream(options['output-file'])).write('TAP version 13\n')

  saveFails(options, tap)

  runAllFiles(options, saved, tap)

  tap.end()
}

const parseRcFile = path => {
  try {
    const contents = fs.readFileSync(path, 'utf8')
    return yaml.parse(contents) || {}
  } catch (er) {
    // if no dotfile exists, or invalid yaml, fail gracefully
    return {}
  }
}

const strToRegExp = g => {
  const p = g.match(/^\/(.*)\/([a-z]*)$/)
  g = p ? p[1] : g
  const flags = p ? p[2] : ''
  return new RegExp(g, flags)
}

require('./jack.js')(main)
<commit_msg>Pull in esm based on resolved location, not just 'esm'<commit_after>#!/usr/bin/env node
'use strict'

const opener = require('opener')
const node = process.execPath
const fs = require('fs')
const fg = require('foreground-child')
const spawn = require('child_process').spawn
const nycBin = require.resolve(
  'nyc/' + require('nyc/package.json').bin.nyc
)
const glob = require('glob')
const isexe = require('isexe')
const yaml = require('tap-yaml')
const path = require('path')
const exists = require('fs-exists-cached').sync
const os = require('os')
const isTTY = process.stdin.isTTY || process.env._TAP_IS_TTY === '1'
const tsNode = require.resolve(
  'ts-node/' + require('ts-node/package.json').bin['ts-node']
)
const esm = require.resolve('esm')

const main = options => {
  // tell chalk if we want color or not.
  if (!options.color)
    process.argv.push('--no-color')
  else {
    const c = process.argv.indexOf('--no-color')
    if (c !== -1)
      process.argv.splice(c, 1)
  }

  const rc = parseRcFile(options.rcfile)
  for (let i in rc) {
    if (!options._.explicit.has(i))
      options[i] = rc[i]
  }

  if (options.reporter === null)
    options.reporter = options.color ? 'classic' : 'tap'

  if (options['dump-config']) {
    console.log(yaml.stringify(Object.keys(options).filter(k =>
      k !== 'dump-config' && k !== '_' && !/^[A-Z_]+$/.test(k)
    ).sort().reduce((set, k) =>
      (set[k] = options[k], set), {})))
    return
  }

  if (options.versions) {
    return console.log(yaml.stringify({
      tap: require('../package.json').version,
      'tap-parser': require('tap-parser/package.json').version,
      nyc: require('nyc/package.json').version,
    }))
  }

  if (options.version)
    return console.log(require('../package.json').version)

  if (options['parser-version'])
    return console.log(require('tap-parser/package.json').version)

  if (options['nyc-version'])
    return console.log(require('nyc/package.json').version)

  if (options['nyc-help'])
    return nycHelp()

  options.files = globFiles(options._)

  process.stdout.on('error', er => {
    /* istanbul ignore else */
    if (er.code === 'EPIPE')
      process.exit()
    else
      throw er
  })

  options.grep = options.grep.map(strToRegExp)

  // this is only testable by escaping from the covered environment
  /* istanbul ignore next */
  if ((options._.explicit.has('coverage-report') ||
       options._.explicit.has('check-coverage')) &&
      options.files.length === 0)
    return runCoverageReportOnly(options)

  if (options.files.length === 0) {
    if (isTTY) {
      console.error(
        `Reading TAP data from stdin
(use '-' argument to suppress this notice or -h for usage)`)
    }
    options.files.push('-')
  }

  if (options.files.length === 1 && options.files[0] === '-') {
    if (options.coverage)
      console.error('Coverage disabled (stdin cannot be instrumented)')
    setupTapEnv(options)
    stdinOnly(options)
    return
  }

  /* istanbul ignore next */
  if (options.coverage && !process.env.NYC_CONFIG)
    respawnWithCoverage(options)
  else {
    setupTapEnv(options)
    runTests(options)
  }
}

/* istanbul ignore next */
const nycReporter = options =>
  options['coverage-report'] === 'html' ? 'lcov'
  : (options['coverage-report'] || 'text')

/* istanbul ignore next */
const runNyc = (cmd, programArgs, options, spawnOpts) => {
  const reporter = nycReporter(options)

  const args = [
    nycBin,
    ...cmd,
    ...(options['show-process-tree'] ? ['--show-process-tree'] : []),
    '--cache=true',
    '--branches=' + options.branches,
    '--functions=' + options.functions,
    '--lines=' + options.lines,
    '--statements=' + options.statements,
    '--reporter=' + reporter,
    ...options['nyc-arg'],
  ]
  if (options['check-coverage'])
    args.push('--check-coverage')

  args.push.apply(args, programArgs)

  const child = fg(node, args, spawnOpts)

  if (reporter === 'lcov' && options.browser) {
    child.removeAllListeners('close')
    child.on('close', (code, signal) =>
      openHtmlCoverageReport(options, code, signal))
  }
  return child
}

/* istanbul ignore next */
const runCoverageReportOnly = options => {
  runNyc(['report'], [], options)
}

/* istanbul ignore next */
const pipeToCoveralls = options => {

  const reporter = runNyc(['report'], [], {
    ...options,
    'coverage-report': 'text-lcov'
  }, {
    stdio: [0, 'pipe', 2]
  })
  reporter.removeAllListeners('close')

  /* istanbul ignore next */
  const bin = process.env.__TAP_COVERALLS_TEST__
    || require.resolve('coveralls/bin/coveralls.js')

  const ca = fg(node, [bin], { stdio: ['pipe', 1, 2] })
  reporter.stdout.pipe(ca.stdin)
}

/* istanbul ignore next */
const respawnWithCoverage = options => {
  runNyc([], [
    '--',
    node,
    ...process.execArgv,
    ...process.argv.slice(1)
  ], options)
}

/* istanbul ignore next */
const openHtmlCoverageReport = (options, code, signal) => {
  opener('coverage/lcov-report/index.html')
  if (signal) {
    setTimeout(() => {}, 200)
    process.kill(process.pid, signal)
  } else if (code) {
    process.exitCode = code
  }
}

const nycHelp = _ => fg(node, [nycBin, '--help'])

const setupTapEnv = options => {
  process.env.TAP_TIMEOUT = options.timeout
  if (options.color)
    process.env.TAP_COLORS = '1'
  else
    process.env.TAP_COLORS = '0'

  if (options.snapshot)
    process.env.TAP_SNAPSHOT = '1'

  if (options.bail)
    process.env.TAP_BAIL = '1'

  if (options.invert)
    process.env.TAP_GREP_INVERT = '1'

  if (options.grep.length)
    process.env.TAP_GREP = options.grep.map(p => p.toString())
      .join('\n')

  if (options.only)
    process.env.TAP_ONLY = '1'
}

const globFiles = files => files.reduce((acc, f) =>
  acc.concat(f === '-' ? f : glob.sync(f, { nonull: true })), [])

const makeReporter = options =>
  new (require('tap-mocha-reporter'))(options.reporter)

const stdinOnly = options => {
  // if we didn't specify any files, then just passthrough
  // to the reporter, so we don't get '/dev/stdin' in the suite list.
  // We have to pause() before piping to switch streams2 into old-mode
  process.stdin.pause()
  const reporter = makeReporter(options)
  process.stdin.pipe(reporter)
  if (options['output-file'] !== null)
    process.stdin.pipe(fs.createWriteStream(options['output-file']))
  process.stdin.resume()
}

const readSaveFile = options => {
  if (options.save)
    try {
      const s = fs.readFileSync(options.save, 'utf8').trim()
      if (s)
        return s.split('\n')
    } catch (er) {}

  return null
}

const saveFails = (options, tap) => {
  if (!options.save)
    return

  let fails = []
  const successes = []
  tap.on('result', res => {
    // we will continue to re-run todo tests, even though they're
    // not technically "failures".
    if (!res.ok && !res.extra.skip)
      fails.push(res.extra.file)
    else
      successes.push(res.extra.file)
  })

  const save = () => {
    fails = fails.reduce((set, f) => {
      f = f.replace(/\\/g, '/')
      if (set.indexOf(f) === -1)
        set.push(f)
      return set
    }, [])

    if (!fails.length)
      try {
        fs.unlinkSync(options.save)
      } catch (er) {}
    else
      try {
        fs.writeFileSync(options.save, fails.join('\n') + '\n')
      } catch (er) {}
  }

  tap.on('bailout', reason => {
    // add any pending test files to the fails list.
    fails.push.apply(fails, options.files.filter(file =>
      successes.indexOf(file) === -1))
    save()
  })

  tap.on('end', save)
}

const filterFiles = (files, saved, parallelOk) =>
  files.filter(file =>
    path.basename(file) === 'tap-parallel-ok' ?
      ((parallelOk[path.resolve(path.dirname(file))] = true), false)
    : path.basename(file) === 'tap-parallel-not-ok' ?
      parallelOk[path.resolve(path.dirname(file))] = false
    : onSavedList(saved, file)
  )

// check if the file is on the list, or if it's a parent dir of
// any items that are on the list.
const onSavedList = (saved, file) =>
  !saved || !saved.length ? true
  : saved.indexOf(file) !== -1 ? true
  : saved.some(f => f.indexOf(file + '/') === 0)

const isParallelOk = (parallelOk, file) => {
  const dir = path.resolve(path.dirname(file))
  return (dir in parallelOk) ? parallelOk[dir]
    : exists(dir + '/tap-parallel-ok')
    ? parallelOk[dir] = true
    : exists(dir + '/tap-parallel-not-ok')
    ? parallelOk[dir] = false
    : dir.length >= process.cwd().length
    ? isParallelOk(parallelOk, dir)
    : true
}

const runAllFiles = (options, saved, tap) => {
  let doStdin = false
  let parallelOk = Object.create(null)

  options.files = filterFiles(options.files, saved, parallelOk)
  let tapChildId = 0

  for (let i = 0; i < options.files.length; i++) {
    const opt = {}
    const file = options.files[i]

    // Pick up stdin after all the other files are handled.
    if (file === '-') {
      doStdin = true
      continue
    }

    let st
    try {
      st = fs.statSync(file)
    } catch (er) {
      continue
    }

    if (options.timeout)
      opt.timeout = options.timeout * 1000

    opt.file = file
    opt.childId = tapChildId++
    if (st.isDirectory()) {
      const dir = filterFiles(fs.readdirSync(file).map(f =>
        file + '/' + f), saved, parallelOk)
      options.files.splice(i, 1, ...dir)
      i--
    } else {
      if (options.jobs > 1)
        opt.buffered = isParallelOk(parallelOk, file) !== false

      if (file.match(/\.m?js$/)) {
        const args = [
          ...(options.esm ? ['-r', esm] : []),
          ...options['node-arg'],
          file,
          ...options['test-arg']
        ]
        tap.spawn(node, args, opt, file)
      } else if (file.match(/\.ts$/)) {
        const args = [
          ...options['node-arg'],
          file,
          ...options['test-arg']
        ]
        tap.spawn(tsNode, args, opt, file)
      } else if (isexe.sync(options.files[i]))
        tap.spawn(options.files[i], options['test-arg'], opt, file)
    }
  }

  if (doStdin)
    tap.stdin()
}

const runTests = options => {
  const saved = readSaveFile(options)

  // At this point, we know we need to use the tap root,
  // because there are 1 or more files to spawn.
  const tap = require('../lib/tap.js')
  if (options.comments) {
    const onComment = c => {
      if (!c.match(/^# (time=[0-9\.]+m?s|Subtest(: .+))\n$/))
        console.error(c.substr(2).trim())
    }
    const onChild = p => {
      p.on('comment', onComment)
      p.on('child', onChild)
    }
    tap.parser.on('comment', onComment)
    tap.parser.on('child', onChild)
  }

  tap.runOnly = false

  // greps are passed to children, but not the runner itself
  tap.grep = []
  tap.jobs = options.jobs
  tap.patchProcess()

  // if not -Rtap, then output what the user wants.
  // otherwise just dump to stdout
  tap.pipe(options.reporter === 'tap' ? process.stdout: makeReporter(options))

  // need to replay the first version line, because the previous
  // line will have flushed it out to stdout or the reporter already.
  if (options['output-file'] !== null)
    tap.pipe(fs.createWriteStream(options['output-file'])).write('TAP version 13\n')

  saveFails(options, tap)

  runAllFiles(options, saved, tap)

  tap.end()
}

const parseRcFile = path => {
  try {
    const contents = fs.readFileSync(path, 'utf8')
    return yaml.parse(contents) || {}
  } catch (er) {
    // if no dotfile exists, or invalid yaml, fail gracefully
    return {}
  }
}

const strToRegExp = g => {
  const p = g.match(/^\/(.*)\/([a-z]*)$/)
  g = p ? p[1] : g
  const flags = p ? p[2] : ''
  return new RegExp(g, flags)
}

require('./jack.js')(main)
<|endoftext|>