<commit_before>module.exports = deglob

var findRoot = require('find-root')
var fs = require('fs')
var glob = require('glob')
var ignorePkg = require('ignore')
var os = require('os')
var parallel = require('run-parallel')
var path = require('path')
var pkgConfig = require('pkg-config')
var uniq = require('uniq')

function deglob (files, opts, cb) {
  if (typeof opts === 'function') return deglob(files, null, opts)
  opts = parseOpts(opts)

  if (typeof files === 'string') files = [ files ]
  if (files.length === 0) return nextTick(cb, null, [])

  // traverse filesystem
  parallel(files.map(function (pattern) {
    return function (callback) {
      glob(pattern, {
        cwd: opts.cwd,
        ignore: opts._ignore,
        nodir: true
      }, callback)
    }
  }), function (err, results) {
    if (err) return cb(err)

    // flatten nested arrays
    var files = results.reduce(function (files, result) {
      result.forEach(function (file) {
        files.push(path.resolve(opts.cwd, file))
      })
      return files
    }, [])

    // de-dupe
    files = uniq(files)

    if (opts._gitignore) {
      files = toRelative(opts.cwd, files)
      if (os.platform() === 'win32') files = toUnix(files)
      files = opts._gitignore.filter(files)
      files = toAbsolute(opts.cwd, files)
      if (os.platform() === 'win32') files = toWin32(files)
    }

    return cb(null, files)
  })
}

function parseOpts (opts) {
  if (!opts) opts = {}
  opts = Object.assign({
    useGitIgnore: true,
    usePackageJson: true,
    configKey: 'config',
    gitIgnoreFile: '.gitignore'
  }, opts)

  if (!opts.cwd) opts.cwd = process.cwd()

  opts._ignore = []
  opts._gitignore = ignorePkg()

  function addIgnorePattern (patterns) {
    opts._ignore = opts._ignore.concat(patterns)
    opts._gitignore.addPattern(patterns)
  }

  if (opts.ignore) addIgnorePattern(opts.ignore)

  // return if we're not looking for packageJson or gitIgnore
  if (!opts.useGitIgnore && !opts.usePackageJson) {
    return opts
  }

  // Find package.json in the project root
  var root
  try {
    root = findRoot(opts.cwd)
  } catch (e) {}

  if (root) {
    if (opts.usePackageJson) {
      var packageOpts = pkgConfig(opts.configKey, { root: false, cwd: opts.cwd })
      if (packageOpts && packageOpts.ignore) {
        // Use ignore patterns from package.json ("config.ignore" property)
        addIgnorePattern(packageOpts.ignore)
      }
    }

    if (opts.useGitIgnore) {
      // Use ignore patterns from project root .gitignore
      var gitignore
      try {
        gitignore = fs.readFileSync(path.join(root, opts.gitIgnoreFile), 'utf8')
      } catch (e) {}
      if (gitignore) opts._gitignore.addPattern(gitignore.split(/\r?\n/))
    }
  }

  return opts
}

function toAbsolute (cwd, files) {
  return files.map(function (file) {
    return path.join(cwd, file)
  })
}

function toRelative (cwd, files) {
  return files.map(function (file) {
    return path.relative(cwd, file)
  })
}

function toUnix (files) {
  return files.map(function (file) {
    return file.replace(/\\/g, '/')
  })
}

function toWin32 (files) {
  return files.map(function (file) {
    return file.replace(/\//g, '\\')
  })
}

function nextTick (cb, err, val) {
  process.nextTick(function () {
    cb(err, val)
  })
}
<commit_msg>standard<commit_after>module.exports = deglob

var findRoot = require('find-root')
var fs = require('fs')
var glob = require('glob')
var ignorePkg = require('ignore')
var os = require('os')
var parallel = require('run-parallel')
var path = require('path')
var pkgConfig = require('pkg-config')
var uniq = require('uniq')

function deglob (files, opts, cb) {
  if (typeof opts === 'function') return deglob(files, null, opts)
  opts = parseOpts(opts)

  if (typeof files === 'string') files = [files]
  if (files.length === 0) return nextTick(cb, null, [])

  // traverse filesystem
  parallel(files.map(function (pattern) {
    return function (callback) {
      glob(pattern, {
        cwd: opts.cwd,
        ignore: opts._ignore,
        nodir: true
      }, callback)
    }
  }), function (err, results) {
    if (err) return cb(err)

    // flatten nested arrays
    var files = results.reduce(function (files, result) {
      result.forEach(function (file) {
        files.push(path.resolve(opts.cwd, file))
      })
      return files
    }, [])

    // de-dupe
    files = uniq(files)

    if (opts._gitignore) {
      files = toRelative(opts.cwd, files)
      if (os.platform() === 'win32') files = toUnix(files)
      files = opts._gitignore.filter(files)
      files = toAbsolute(opts.cwd, files)
      if (os.platform() === 'win32') files = toWin32(files)
    }

    return cb(null, files)
  })
}

function parseOpts (opts) {
  if (!opts) opts = {}
  opts = Object.assign({
    useGitIgnore: true,
    usePackageJson: true,
    configKey: 'config',
    gitIgnoreFile: '.gitignore'
  }, opts)

  if (!opts.cwd) opts.cwd = process.cwd()

  opts._ignore = []
  opts._gitignore = ignorePkg()

  function addIgnorePattern (patterns) {
    opts._ignore = opts._ignore.concat(patterns)
    opts._gitignore.addPattern(patterns)
  }

  if (opts.ignore) addIgnorePattern(opts.ignore)

  // return if we're not looking for packageJson or gitIgnore
  if (!opts.useGitIgnore && !opts.usePackageJson) {
    return opts
  }

  // Find package.json in the project root
  var root
  try {
    root = findRoot(opts.cwd)
  } catch (e) {}

  if (root) {
    if (opts.usePackageJson) {
      var packageOpts = pkgConfig(opts.configKey, { root: false, cwd: opts.cwd })
      if (packageOpts && packageOpts.ignore) {
        // Use ignore patterns from package.json ("config.ignore" property)
        addIgnorePattern(packageOpts.ignore)
      }
    }

    if (opts.useGitIgnore) {
      // Use ignore patterns from project root .gitignore
      var gitignore
      try {
        gitignore = fs.readFileSync(path.join(root, opts.gitIgnoreFile), 'utf8')
      } catch (e) {}
      if (gitignore) opts._gitignore.addPattern(gitignore.split(/\r?\n/))
    }
  }

  return opts
}

function toAbsolute (cwd, files) {
  return files.map(function (file) {
    return path.join(cwd, file)
  })
}

function toRelative (cwd, files) {
  return files.map(function (file) {
    return path.relative(cwd, file)
  })
}

function toUnix (files) {
  return files.map(function (file) {
    return file.replace(/\\/g, '/')
  })
}

function toWin32 (files) {
  return files.map(function (file) {
    return file.replace(/\//g, '\\')
  })
}

function nextTick (cb, err, val) {
  process.nextTick(function () {
    cb(err, val)
  })
}
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');

var through = require('through2');
var Readable = require('readable-stream').Readable;

var concat = require('concat-stream');
var duplexer = require('duplexer2');
var falafel = require('falafel');
var unparse = require('escodegen').generate;
var inspect = require('object-inspect');
var evaluate = require('static-eval');
var copy = require('shallow-copy');

module.exports = function (modules, opts) {
    var varNames = {};
    if (!opts) opts = {};
    var vars = opts.vars || {};
    var pending = 0;
    var updates = [];

    function pushUpdate (node, s) {
        var rep = String(s);
        var prev = node.range[1] - node.range[0];
        updates.push({ offset: prev - rep.length });
        node.update(rep);
    }

    var output = through();
    return duplexer(concat(function (body) {
        try { var src = parse(body.toString('utf8')) }
        catch (err) { return error(err) }
        if (pending === 0) finish(src);
    }), output);

    function finish (src) {
        var offset = 0, pos = 0;
        src = String(src);

        (function next () {
            if (updates.length === 0) return done();

            var s = updates.shift();
            if (!s.stream) {
                offset += s.offset;
                return next();
            }

            output.push(src.slice(pos, s.range[0] - offset));
            pos = s.range[0] - offset;
            offset += s.range[1] - s.range[0];

            s.stream.on('end', next);
            s.stream.pipe(output, { end: false });
        })();

        function done () {
            output.push(src.slice(pos));
            output.push(null);
        }
    }

    function error (msg) {
        output.emit('error', new Error(msg));
    }

    function parse (body) {
        var output = falafel(body, function (node) {
            if (isRequire(node) && has(modules, node.arguments[0].value)
            && node.parent.type === 'VariableDeclarator'
            && node.parent.id.type === 'Identifier') {
                varNames[node.parent.id.name] = node.arguments[0].value;
                var decs = node.parent.parent.declarations;
                if (decs.length === 1) {
                    pushUpdate(node.parent.parent, '');
                }
                else {
                    pushUpdate(node.parent, '');
                }
            }
            if (isRequire(node) && has(modules, node.arguments[0].value)
            && node.parent.type === 'AssignmentExpression'
            && node.parent.left.type === 'Identifier') {
                varNames[node.parent.left.name] = node.arguments[0].value;
                pushUpdate(node, '{}');
            }

            if (node.type === 'Identifier' && varNames[node.name]) {
                traverse(node);
            }
        });
        return output;
    }

    function traverse (node) {
        var val = modules[varNames[node.name]];
        if (node.parent.type === 'CallExpression') {
            if (typeof val !== 'function') {
                return error(
                    'tried to statically call ' + inspect(val)
                    + ' as a function'
                );
            }
            var xvars = copy(vars);
            xvars[node.name] = val;
            var res = evaluate(node.parent, xvars);
            if (res !== undefined) pushUpdate(node.parent, res);
        }
        else if (node.parent.type === 'MemberExpression') {
            if (node.parent.property.type !== 'Identifier') {
                return error(
                    'dynamic property in member expression: '
                    + node.parent.source()
                );
            }

            var cur = node.parent.parent;

            if (cur.type === 'MemberExpression') {
                cur = cur.parent;
                if (cur.type !== 'CallExpression'
                && cur.parent.type === 'CallExpression') {
                    cur = cur.parent;
                }
            }
            if (node.parent.type === 'MemberExpression'
            && (cur.type !== 'CallExpression'
            && cur.type !== 'MemberExpression')) {
                cur = node.parent;
            }

            var xvars = copy(vars);
            xvars[node.name] = val;

            var res = evaluate(cur, xvars);
            if (isStream(res)) {
                updates.push({
                    range: cur.range,
                    stream: wrapStream(res)
                });
                cur.update('');
            }
            else if (res !== undefined) {
                pushUpdate(cur, res);
            }
        }
        else {
            output.emit('error', new Error(
                'unsupported type for static module: ' + node.parent.type
            ));
        }
    }
};

function isRequire (node) {
    var c = node.callee;
    return c
        && node.type === 'CallExpression'
        && c.type === 'Identifier'
        && c.name === 'require'
    ;
}

function has (obj, key) {
    return {}.hasOwnProperty.call(obj, key);
}

function isStream (s) {
    return s && typeof s === 'object' && typeof s.pipe === 'function';
}

function wrapStream (s) {
    if (typeof s.read === 'function') return s
    else return (new Readable).wrap(s)
}
<commit_msg>passing attribute test<commit_after>var fs = require('fs');
var path = require('path');

var through = require('through2');
var Readable = require('readable-stream').Readable;

var concat = require('concat-stream');
var duplexer = require('duplexer2');
var falafel = require('falafel');
var unparse = require('escodegen').generate;
var inspect = require('object-inspect');
var evaluate = require('static-eval');
var copy = require('shallow-copy');

module.exports = function (modules, opts) {
    var varNames = {};
    if (!opts) opts = {};
    var vars = opts.vars || {};
    var pending = 0;
    var updates = [];

    function pushUpdate (node, s) {
        var rep = String(s);
        var prev = node.range[1] - node.range[0];
        updates.push({ offset: prev - rep.length });
        node.update(rep);
    }

    var output = through();
    return duplexer(concat(function (body) {
        try { var src = parse(body.toString('utf8')) }
        catch (err) { return error(err) }
        if (pending === 0) finish(src);
    }), output);

    function finish (src) {
        var offset = 0, pos = 0;
        src = String(src);

        (function next () {
            if (updates.length === 0) return done();

            var s = updates.shift();
            if (!s.stream) {
                offset += s.offset;
                return next();
            }

            output.push(src.slice(pos, s.range[0] - offset));
            pos = s.range[0] - offset;
            offset += s.range[1] - s.range[0];

            s.stream.on('end', next);
            s.stream.pipe(output, { end: false });
        })();

        function done () {
            output.push(src.slice(pos));
            output.push(null);
        }
    }

    function error (msg) {
        output.emit('error', new Error(msg));
    }

    function parse (body) {
        var output = falafel(body, function (node) {
            if (isRequire(node) && has(modules, node.arguments[0].value)
            && node.parent.type === 'VariableDeclarator'
            && node.parent.id.type === 'Identifier') {
                varNames[node.parent.id.name] = node.arguments[0].value;
                var decs = node.parent.parent.declarations;
                if (decs.length === 1) {
                    pushUpdate(node.parent.parent, '');
                }
                else {
                    pushUpdate(node.parent, '');
                }
            }
            else if (isRequire(node) && has(modules, node.arguments[0].value)
            && node.parent.type === 'AssignmentExpression'
            && node.parent.left.type === 'Identifier') {
                varNames[node.parent.left.name] = node.arguments[0].value;
                pushUpdate(node, '{}');
            }
            else if (isRequire(node) && has(modules, node.arguments[0].value)
            && node.parent.type === 'MemberExpression'
            && node.parent.property.type === 'Identifier'
            && node.parent.parent.type === 'VariableDeclarator'
            && node.parent.parent.id.type === 'Identifier') {
                varNames[node.parent.parent.id.name] = [
                    node.arguments[0].value, node.parent.property.name
                ];
                var decs = node.parent.parent.parent.declarations;
                if (decs.length === 1) {
                    pushUpdate(node.parent.parent.parent, '');
                }
                else {
                    pushUpdate(node.parent.parent, '');
                }
            }

            if (node.type === 'Identifier' && varNames[node.name]) {
                traverse(node);
            }
        });
        return output;
    }

    function traverse (node) {
        var vn = varNames[node.name];
        var val;
        if (Array.isArray(vn)) {
            val = modules[vn[0]][vn[1]];
        }
        else {
            val = modules[vn];
        }

        if (node.parent.type === 'CallExpression') {
            if (typeof val !== 'function') {
                return error(
                    'tried to statically call ' + inspect(val)
                    + ' as a function'
                );
            }
            var xvars = copy(vars);
            xvars[node.name] = val;
            var res = evaluate(node.parent, xvars);

            if (isStream(res)) {
                updates.push({
                    range: node.parent.range,
                    stream: wrapStream(res)
                });
                node.parent.update('');
            }
            else if (res !== undefined) pushUpdate(node.parent, res);
        }
        else if (node.parent.type === 'MemberExpression') {
            if (node.parent.property.type !== 'Identifier') {
                return error(
                    'dynamic property in member expression: '
                    + node.parent.source()
                );
            }

            var cur = node.parent.parent;

            if (cur.type === 'MemberExpression') {
                cur = cur.parent;
                if (cur.type !== 'CallExpression'
                && cur.parent.type === 'CallExpression') {
                    cur = cur.parent;
                }
            }
            if (node.parent.type === 'MemberExpression'
            && (cur.type !== 'CallExpression'
            && cur.type !== 'MemberExpression')) {
                cur = node.parent;
            }

            var xvars = copy(vars);
            xvars[node.name] = val;

            var res = evaluate(cur, xvars);
            if (isStream(res)) {
                updates.push({
                    range: cur.range,
                    stream: wrapStream(res)
                });
                cur.update('');
            }
            else if (res !== undefined) {
                pushUpdate(cur, res);
            }
        }
        else {
            output.emit('error', new Error(
                'unsupported type for static module: ' + node.parent.type
            ));
        }
    }
};

function isRequire (node) {
    var c = node.callee;
    return c
        && node.type === 'CallExpression'
        && c.type === 'Identifier'
        && c.name === 'require'
    ;
}

function has (obj, key) {
    return {}.hasOwnProperty.call(obj, key);
}

function isStream (s) {
    return s && typeof s === 'object' && typeof s.pipe === 'function';
}

function wrapStream (s) {
    if (typeof s.read === 'function') return s
    else return (new Readable).wrap(s)
}
<|endoftext|>


<commit_before>// Dependencies
var loaderUtils = require('loader-utils');
var assign = require('object-assign');

// Modules
var linter = require('./lib/linter');

function apply(options, compiler) {
  // acces to compiler and options
  compiler.plugin('compilation', function(compilation, params) {
    // Linter returns a simple report of FilePath + Warning or Errors
    var contexts = options.context || [compiler.context];
    var report = [];
    contexts.forEach(function(context) {
      report = report.concat(linter(context + '/' + options.glob, options));
    });

    // Hook into the compilation as early as possible, at the seal step
    compilation.plugin('seal', function() {
      // We need to keep the reference to the compilation's scope
      var _this = this;

      // Errors/Warnings are pushed to the compilation's error handling
      // so we can drop out of the processing tree on warn/error
      report.forEach(function(x) {
        if(x.error) {
          _this.errors.push(x.file);
        } else {
          _this.warnings.push(x.file);
        }
      });
    });
  });
}

// makes it easier to pass and check options to the plugin thank you webpack doc
// [https://webpack.github.io/docs/plugins.html#the-compiler-instance]
module.exports = function(options) {
  options = options || {};
  // Default Glob is any directory level of scss and/or sass file,
  // under webpack's context and specificity changed via globbing patterns
  options.glob = options.glob || '**/*.s?(c|a)ss';

  if (options.ignoreFiles && !Array.isArray(options.ignoreFiles)) {
    options.ignoreFiles = [options.ignoreFiles];
  }

  if (options.context && !Array.isArray(options.context)) {
    options.context = [options.context];
  }

  if (options instanceof Array) {
    options = {
      include: options,
    };
  }

  if (!Array.isArray(options.include)) {
    options.include = [options.include];
  }

  return {
    apply: apply.bind(this, options)
  };
};<commit_msg>Remove redunt linting via adding option<commit_after>// Dependencies
var loaderUtils = require('loader-utils');
var assign = require('object-assign');

// Modules
var linter = require('./lib/linter');

function apply(options, compiler) {
  // access to compiler and options
  compiler.plugin('compilation', function(compilation, params) {
    // Avoid redundant lint when it comes to running with other plugins
    if (options.ignorePlugins &&
      options.ignorePlugins.indexOf(compilation.name) > -1
    ) {
      return;
    }

    // Linter returns a simple report of FilePath + Warning or Errors
    var contexts = options.context || [compiler.context];
    var report = [];
    contexts.forEach(function(context) {
      report = report.concat(linter(context + '/' + options.glob, options));
    });

    // Hook into the compilation as early as possible, at the seal step
    compilation.plugin('seal', function() {
      // We need to keep the reference to the compilation's scope
      var _this = this;

      // Errors/Warnings are pushed to the compilation's error handling
      // so we can drop out of the processing tree on warn/error
      report.forEach(function(x) {
        if(x.error) {
          _this.errors.push(x.file);
        } else {
          _this.warnings.push(x.file);
        }
      });
    });
  });
}

// makes it easier to pass and check options to the plugin thank you webpack doc
// [https://webpack.github.io/docs/plugins.html#the-compiler-instance]
module.exports = function(options) {
  options = options || {};
  // Default Glob is any directory level of scss and/or sass file,
  // under webpack's context and specificity changed via globbing patterns
  options.glob = options.glob || '**/*.s?(c|a)ss';

  var arrayOptions = [
    'ignoreFiles',
    'ignorePlugins',
    'context'
  ];

  arrayOptions.forEach(function(option) {
    if(options[option] && typeof options[option] === 'string') {
      options[option] = [options[option]];
    }
  });

  if (options instanceof Array) {
    options = {
      include: options,
    };
  }

  if (!Array.isArray(options.include)) {
    options.include = [options.include];
  }

  return {
    apply: apply.bind(this, options)
  };
};<|endoftext|>


<commit_before>var fs = require('graceful-fs');
var path = require('path');

var sourcemapUrlRegeExp = /^\/\/#\s*sourceMappingURL=/;

var createSourceMapLocatorPreprocessor = function(args, logger) {
  var log = logger.create('preprocessor.sourcemap');
  var charsetRegex = /^;charset=([^;]+);/;

  return function(content, file, done) {
    function sourceMapData(data){
      file.sourceMap = JSON.parse(data);
      done(content);
    }

    function inlineMap(inlineData){

      var charset = 'utf-8';

      if (charsetRegex.test(inlineData)) {
        var matches = inlineData.match(charsetRegex);

        if (matches.length === 2) {
          charset = matches[1];
          inlineData = inlineData.slice(matches[0].length -1);
        }
      }

      if (/^;base64,/.test(inlineData)) {
        // base64-encoded JSON string
        log.debug('base64-encoded source map for', file.originalPath);
        var buffer = new Buffer(inlineData.slice(';base64,'.length), 'base64');
        sourceMapData(buffer.toString(charset));
      } else {
        // straight-up URL-encoded JSON string
        log.debug('raw inline source map for', file.originalPath);
        sourceMapData(decodeURIComponent(inlineData));
      }
    }

    function fileMap(mapPath){
      fs.exists(mapPath, function(exists) {
        if (!exists) {
          done(content);
          return;
        }
        fs.readFile(mapPath, function(err, data) {
          if (err){ throw err; }

          log.debug('external source map exists for', file.originalPath);
          sourceMapData(data);
        });
      });
    }

    var lines = content.split(/\n/);
    var lastLine = lines.pop();
    while (/^\s*$/.test(lastLine)) {
      lastLine = lines.pop();
    }

    var mapUrl;

    if (sourcemapUrlRegeExp.test(lastLine)) {
      mapUrl = lastLine.replace(sourcemapUrlRegeExp, '');
    }

    if (!mapUrl) {
      fileMap(file.path + ".map");
    } else if (/^data:application\/json/.test(mapUrl)) {
      inlineMap(mapUrl.slice('data:application/json'.length));
    } else {
      fileMap(path.resolve(path.dirname(file.path), mapUrl));
    }
  };
};

createSourceMapLocatorPreprocessor.$inject = ['args', 'logger'];

// PUBLISH DI MODULE
module.exports = {
  'preprocessor:sourcemap': ['factory', createSourceMapLocatorPreprocessor]
};
<commit_msg>Replace Buffer() ctor call with Buffer.from().<commit_after>var fs = require('graceful-fs');
var path = require('path');

var sourcemapUrlRegeExp = /^\/\/#\s*sourceMappingURL=/;

var createSourceMapLocatorPreprocessor = function(args, logger) {
  var log = logger.create('preprocessor.sourcemap');
  var charsetRegex = /^;charset=([^;]+);/;

  return function(content, file, done) {
    function sourceMapData(data){
      file.sourceMap = JSON.parse(data);
      done(content);
    }

    function inlineMap(inlineData){

      var charset = 'utf-8';

      if (charsetRegex.test(inlineData)) {
        var matches = inlineData.match(charsetRegex);

        if (matches.length === 2) {
          charset = matches[1];
          inlineData = inlineData.slice(matches[0].length -1);
        }
      }

      if (/^;base64,/.test(inlineData)) {
        // base64-encoded JSON string
        log.debug('base64-encoded source map for', file.originalPath);
        var buffer = Buffer.from(inlineData.slice(';base64,'.length), 'base64');
        sourceMapData(buffer.toString(charset));
      } else {
        // straight-up URL-encoded JSON string
        log.debug('raw inline source map for', file.originalPath);
        sourceMapData(decodeURIComponent(inlineData));
      }
    }

    function fileMap(mapPath){
      fs.exists(mapPath, function(exists) {
        if (!exists) {
          done(content);
          return;
        }
        fs.readFile(mapPath, function(err, data) {
          if (err){ throw err; }

          log.debug('external source map exists for', file.originalPath);
          sourceMapData(data);
        });
      });
    }

    var lines = content.split(/\n/);
    var lastLine = lines.pop();
    while (/^\s*$/.test(lastLine)) {
      lastLine = lines.pop();
    }

    var mapUrl;

    if (sourcemapUrlRegeExp.test(lastLine)) {
      mapUrl = lastLine.replace(sourcemapUrlRegeExp, '');
    }

    if (!mapUrl) {
      fileMap(file.path + ".map");
    } else if (/^data:application\/json/.test(mapUrl)) {
      inlineMap(mapUrl.slice('data:application/json'.length));
    } else {
      fileMap(path.resolve(path.dirname(file.path), mapUrl));
    }
  };
};

createSourceMapLocatorPreprocessor.$inject = ['args', 'logger'];

// PUBLISH DI MODULE
module.exports = {
  'preprocessor:sourcemap': ['factory', createSourceMapLocatorPreprocessor]
};
<|endoftext|>


<commit_before>import gulpLoadPlugins from 'gulp-load-plugins';
import minimist from 'minimist';
import del from 'del';
import lazypipe from 'lazypipe';
import normalize from 'normalize-path';
import { readFileSync } from 'fs';

const knownOptions = {
    string: ['env', 'config']
};

const options = minimist(process.argv.slice(2), knownOptions);

/**
 * Returns a config object by checking three sources in this order:
 *  1. If there was a --config option passed in the cli options, use the
 *  config.json file provided there.
 *  2. If 1 failed, and there is a config.json file in the project folder, use that config.json
 *  3. If 1 and 2 failed, and there is an environment variable PSTASKS_ROOT, use the config.json in that directory.
 *  4. If the first 3 failed, throw an error.
 *
 * @return {object|null}
 */
function loadConfig() {
    if (options.config) {
        console.log(`Using config.json found at ${options.config}`);
        const normalizedPath = normalize(options.config);
        const configStr = readFileSync(`${normalizedPath}/config.json`).toString();
        return JSON.parse(configStr);
    }
    try {
        const configStr = readFileSync('./config.json').toString();
        console.log('Using config.json found in project folder');
        return JSON.parse(configStr);
    } catch (e) {
        const psTasksRoot = process.env['PSTASKS_ROOT'];
        if (!psTasksRoot) {
            throw new Error('Unable to locate config. PSTASKS_ROOT env var not set.');
        } else {
            const normalizedPath = normalize(psTasksRoot);
            try {
                const configStr = readFileSync(`${psTasksRoot}/config.json`).toString();
                console.log(`using config.json in PSTASKS_ROOT: ${psTasksRoot}`);
                return JSON.parse(configStr);
            } catch (e) {
                console.log(`error reading config.json found at ${psTasksRoot}`);
            }
        }

    }
    console.log('Could not load config.json -- all three loading methods failed');
    return null;
}

/**
 * registers the following gulp tasks to the project-level (local) gulp
 * @param  {object} gulp default export
 * @param  {string} __dirname of the project folder that gulp command was executed from
 * @return {undefined}
 */
export default function (gulp, projectPath) {
    const config = loadConfig();
    if (!options.env) {
        options.env = config.default_deploy_target;
    }

    const plugins = gulpLoadPlugins();

    if (!config.default_deploy_target && !knownOptions.env) {
        throw new Error('No deploy target provided in cli options or the default_deploy_target config option');
    }

    // No image server
    gulp.task("build-plugin", () =>
        gulp.src(["plugin/**", "plugin.xml"])
        .pipe(gulp.dest("dist"))
    );

    gulp.task("build-src", ["build-plugin"], () =>
        gulp.src("src/**")
        .pipe(gulp.dest("dist/web_root"))
    );

    gulp.task("zip", ["build-src"], () =>
        gulp.src("dist")
        .pipe(plugins.zip("plugin.zip"))
        .pipe(gulp.dest("dist"))
    );

    gulp.task("clean", ["zip"], () => {
        del(["dist/*", "!dist/*.zip"])
    });

    gulp.task("build-no-img", ["build-plugin", "build-src", "zip", "clean"])

    gulp.task("deploy", () =>
        gulp.src("dist/src/**")
        .pipe(plugins.debug())
        .pipe(deploy())
    );

    gulp.task("watch-deploy", () =>
        gulp.src("src/**")
        .pipe(plugins.watch("src/**"))
        .pipe(preprocess())
        .pipe(deploy())
    );

    gulp.task("build", ["less", "build-static", "babel"], () =>
        gulp.src([
            "./plugin/**/*",
            "./src/**/*",
            "./queries_root/**/*",
            "plugin/plugin.xml",
            "!src/**/*.less",
            "!src/**/*.{png,gif,jpg,bmp,swf,js}",
            "!src/**/ext/**",
            "!src/less{,/**}"
        ], {
            base: "./src"
        })
        .pipe(plugins.debug())
        .pipe(preprocess())
        .pipe(gulp.dest("dist"))
    );

    gulp.task("build-static", () =>
        gulp.src([
            "./src/**/*.{jpg,png,gif,bmp,swf}",
            "./src/**/ext/**"
        ], {
            base: "./src"
        })
        .pipe(gulp.dest("dist/src"))
    );

    gulp.task("package", () =>
        gulp.src("dist/plugin/**")
        .pipe(plugins.zip("plugin.zip"))
        .pipe(gulp.dest("dist"))
    );

    gulp.task("babel", () =>
        gulp.src([
            "./src/**/*.js",
            "!src/**/ext/**"
        ], {
            base: "./src"
        })
        .pipe(plugins.debug())
        .pipe(preprocess())
        .pipe(plugins.babel())
        .pipe(gulp.dest("dist"))
    );

    const deploy = lazypipe()
        .pipe(() => {
            const env = options.env;
            return plugins.if(config.hasOwnProperty(env), plugins.sftp(config[env].deploy_credentials))
        });

    const preprocess = lazypipe()
        .pipe(() => {
            const env = options.env;
            return plugins.if(config.hasOwnProperty(env), plugins.preprocess({
                context: {
                    SAMS_URL: config[env].sams_url,
                    API_URL: config[env].api_url
                }
            }));
        });

    gulp.task("lint", () =>
        gulp.src("src/**/*.js")
        .pipe(plugins.eslint())
        .pipe(plugins.eslint.format())
    );

    gulp.task("less", () =>
        gulp.src([
            "src/**/*.less",
            "!src/**/ext/**",
            "!src/**/less/**"
        ])
        .pipe(plugins.less())
        .pipe(preprocess())
        .pipe(gulp.dest("dist/src"))
    );
}
<commit_msg>Reformatted code, fixed build-static output path<commit_after>import gulpLoadPlugins from 'gulp-load-plugins';
import minimist from 'minimist';
import del from 'del';
import lazypipe from 'lazypipe';
import normalize from 'normalize-path';
import { readFileSync } from 'fs';

const knownOptions = {
  string: ['env', 'config']
};

const options = minimist(process.argv.slice(2), knownOptions);

/**
 * Returns a config object by checking three sources in this order:
 *  1. If there was a --config option passed in the cli options, use the
 *  config.json file provided there.
 *  2. If 1 failed, and there is a config.json file in the project folder, use that config.json
 *  3. If 1 and 2 failed, and there is an environment variable PSTASKS_ROOT, use the config.json in that directory.
 *  4. If the first 3 failed, throw an error.
 *
 * @return {object|null}
 */
function loadConfig() {
  if (options.config) {
    console.log(`Using config.json found at ${options.config}`);
    const normalizedPath = normalize(options.config);
    const configStr = readFileSync(`${normalizedPath}/config.json`)
      .toString();
    return JSON.parse(configStr);
  }
  try {
    const configStr = readFileSync('./config.json')
      .toString();
    console.log('Using config.json found in project folder');
    return JSON.parse(configStr);
  } catch (e) {
    const psTasksRoot = process.env['PSTASKS_ROOT'];
    if (!psTasksRoot) {
      throw new Error('Unable to locate config. PSTASKS_ROOT env var not set.');
    } else {
      const normalizedPath = normalize(psTasksRoot);
      try {
        const configStr = readFileSync(`${psTasksRoot}/config.json`)
          .toString();
        console.log(`using config.json in PSTASKS_ROOT: ${psTasksRoot}`);
        return JSON.parse(configStr);
      } catch (e) {
        console.log(`error reading config.json found at ${psTasksRoot}`);
      }
    }

  }
  console.log('Could not load config.json -- all three loading methods failed');
  return null;
}

/**
 * registers the following gulp tasks to the project-level (local) gulp
 * @param  {object} gulp default export
 * @param  {string} __dirname of the project folder that gulp command was executed from
 * @return {undefined}
 */
export default function (gulp, projectPath) {
  const config = loadConfig();
  if (!options.env) {
    options.env = config.default_deploy_target;
  }

  const plugins = gulpLoadPlugins();

  if (!config.default_deploy_target && !knownOptions.env) {
    throw new Error('No deploy target provided in cli options or the default_deploy_target config option');
  }

  // No image server
  gulp.task("build-plugin", () =>
    gulp.src(["plugin/**", "plugin.xml"])
    .pipe(gulp.dest("dist"))
  );

  gulp.task("build-src", ["build-plugin"], () =>
    gulp.src("src/**")
    .pipe(gulp.dest("dist/web_root"))
  );

  gulp.task("zip", ["build-src"], () =>
    gulp.src("dist")
    .pipe(plugins.zip("plugin.zip"))
    .pipe(gulp.dest("dist"))
  );

  gulp.task("clean", ["zip"], () => {
    del(["dist/*", "!dist/*.zip"])
  });

  gulp.task("build-no-img", ["build-plugin", "build-src", "zip", "clean"])

  gulp.task("deploy", () =>
    gulp.src("dist/src/**")
    .pipe(plugins.debug())
    .pipe(deploy())
  );

  gulp.task("watch-deploy", () =>
    gulp.src("src/**")
    .pipe(plugins.watch("src/**"))
    .pipe(preprocess())
    .pipe(deploy())
  );

  gulp.task("build", ["less", "build-static", "babel"], () =>
    gulp.src([
      "./plugin/**/*",
      "./src/**/*",
      "./queries_root/**/*",
      "plugin/plugin.xml",
      "!src/**/*.less",
      "!src/**/*.{png,gif,jpg,bmp,swf,js}",
      "!src/**/ext/**",
      "!src/less{,/**}"
    ], {
      base: "./"
    })
    .pipe(plugins.debug())
    .pipe(preprocess())
    .pipe(gulp.dest("dist"))
  );

  gulp.task("build-static", () =>
    gulp.src([
      "./src/**/*.{jpg,png,gif,bmp,swf}",
      "./src/**/ext/**"
    ], {
      base: "./"
    })
    .pipe(gulp.dest("dist/"))
  );

  gulp.task("package", () =>
    gulp.src("dist/plugin/**")
    .pipe(plugins.zip("plugin.zip"))
    .pipe(gulp.dest("dist"))
  );

  gulp.task("babel", () =>
    gulp.src([
      "./src/**/*.js",
      "!src/**/ext/**"
    ], {
      base: "./"
    })
    .pipe(plugins.debug())
    .pipe(preprocess())
    .pipe(plugins.babel())
    .pipe(gulp.dest("dist"))
  );

  const deploy = lazypipe()
    .pipe(() => {
      const env = options.env;
      return plugins.if(config.hasOwnProperty(env), plugins.sftp(config[env].deploy_credentials))
    });

  const preprocess = lazypipe()
    .pipe(() => {
      const env = options.env;
      return plugins.if(config.hasOwnProperty(env), plugins.preprocess({
        context: {
          SAMS_URL: config[env].sams_url,
          API_URL: config[env].api_url
        }
      }));
    });

  gulp.task("lint", () =>
    gulp.src("src/**/*.js")
    .pipe(plugins.eslint())
    .pipe(plugins.eslint.format())
  );

  gulp.task("less", () =>
    gulp.src([
      "src/**/*.less",
      "!src/**/ext/**",
      "!src/**/less/**"
    ])
    .pipe(plugins.less())
    .pipe(preprocess())
    .pipe(gulp.dest("dist/src"))
  );
}
<|endoftext|>


<commit_before>'use strict';

// see https://github.com/nodejs/node/blob/master/lib/module.js
// and https://github.com/nodejs/node/blob/master/lib/internal/module.js
const Module = module.constructor;

Module.invalidate = function() {

	for ( var id in Module._cache )
		if ( 'invalidate' in Module._cache[id] )
			Module._cache[id].invalidate();
}

Module.invalidateByExports = function(exports) {

	for ( var id in Module._cache )
		if ( Module._cache[id].exports === exports )
			Module._cache[id].invalidate();
}

Module.prototype.invalidateByPath = function(path) {

	Module._cache[Module._resolveFilename(path, this, this.parent === null)].invalidate();
}

Module.prototype.invalidate = function() {

	if ( this.invalidable )
		this._exports = null;
}

function reload(mod) {

	mod._exports = {}; // resets _exports
	mod.loaded = false;
	mod.load(mod.filename);
}

function createProxy(mod) {

	return new Proxy(function() {}, {

		getPrototypeOf: (target) => {

			mod._exports === null && reload(mod);
			return Reflect.getPrototypeOf(mod._exports);
		},

		setPrototypeOf: (target, prototype) => {

			mod._exports === null && reload(mod);
			return Reflect.setPrototypeOf(mod._exports, prototype);
		},

		isExtensible: (target) => {

			mod._exports === null && reload(mod);
			return Reflect.isExtensible(mod._exports);
		},

		preventExtensions: (target) => {

			mod._exports === null && reload(mod);
			return Reflect.preventExtensions(mod._exports);
		},

		getOwnPropertyDescriptor: (target, prop) => {

			mod._exports === null && reload(mod);
			return Reflect.getOwnPropertyDescriptor(mod._exports, prop);
		},

		defineProperty: (target, property, descriptor) => {

			// console.log('P defineProperty', property)

			mod._exports === null && reload(mod);
			return Reflect.defineProperty(mod._exports, property, descriptor);
		},

		has: (target, prop) => {

			mod._exports === null && reload(mod);
			return Reflect.has(mod._exports, prop);
		},

		get: (target, property, receiver) => {

			// console.log('P get', property)

			mod._exports === null && reload(mod);

			// see http://stackoverflow.com/questions/42496414/illegal-invocation-error-using-es6-proxy-and-node-js
			// see https://github.com/nodejs/node/issues/11629
			//var val = Reflect.get(mod._exports, property, receiver);
			//return typeof(val) === 'function' ? val.bind(mod._exports) : val;
			return Reflect.get(mod._exports, property, receiver);
		},

		set: (target, property, value, receiver) => {

			// console.log('P set', property)

			mod._exports === null && reload(mod);
			return Reflect.set(mod._exports, property, value, receiver);
		},

		deleteProperty: (target, property) => {

			mod._exports === null && reload(mod);
			return Reflect.deleteProperty(mod._exports, property);
		},

		ownKeys: (target) => {

			mod._exports === null && reload(mod);
			// see https://tc39.github.io/ecma262/#sec-invariants-of-the-essential-internal-methods
			throw new TypeError('ownKeys not implemented');
			//return [...Reflect.ownKeys(target), ...Reflect.ownKeys(mod._exports)];
			//return Reflect.ownKeys(mod._exports);
		},

		apply: (target, thisArg, argumentsList) => {

			//console.log('P apply', mod._exports.name);

			mod._exports === null && reload(mod);
			return Reflect.apply(mod._exports, thisArg, argumentsList);
		},

		construct: (target, argumentsList, newTarget) => {

			// console.log('P construct');

			mod._exports === null && reload(mod);
			return Reflect.construct(mod._exports, argumentsList, newTarget);
		}
	});
}

Object.defineProperty(Module.prototype, 'invalidable', {
	get: function() {

		return !!this._proxy;
	},
	set: function(value) {

		if ( this._proxy ) {

			if ( !value )
				this._proxy = null;
		} else {

			if ( value )
				this._proxy = createProxy(this);
		}
	}
});

Object.defineProperty(Module.prototype, 'exports', {
	get: function() {

		return this._proxy ? this._proxy : this._exports;
	},
	set: function(value) {

		this._exports = value;
	}
});

/* test
Module.prototype._unload = function() {

	this.exports = null;

	// remove this module from all module children
	for ( var path in this.cache ) {

		var children = this.cache[path].children;
		var pos = children.indexOf(this);
		if ( pos != -1 )
			children.splice(pos);
	}

	// remove module from Module._cache
	delete this.constructor._cache[this.filename];

	this.parent = null;

	this.children.length = 0;

	// remove module from Module._pathCache
	var pathCache = this.constructor._pathCache;
	var keys = Object.keys(pathCache);
	for ( var i = 0; i < keys.length; ++i )
		if ( pathCache[keys[i]] == this.filename )
			delete pathCache[keys[i]];
}
*/
<commit_msg>- cleanup<commit_after>'use strict';

// see https://github.com/nodejs/node/blob/master/lib/module.js
// and https://github.com/nodejs/node/blob/master/lib/internal/module.js
const Module = module.constructor;

Module.invalidate = function() {

	for ( var id in Module._cache )
		if ( 'invalidate' in Module._cache[id] )
			Module._cache[id].invalidate();
}

Module.invalidateByExports = function(exports) {

	for ( var id in Module._cache )
		if ( Module._cache[id].exports === exports )
			Module._cache[id].invalidate();
}

Module.prototype.invalidateByPath = function(path) {

	Module._cache[Module._resolveFilename(path, this, this.parent === null)].invalidate();
}

Module.prototype.invalidate = function() {

	if ( this.invalidable )
		this._exports = null;
}

function reload(mod) {

	mod._exports = {}; // resets _exports
	mod.loaded = false;
	mod.load(mod.filename);
}

function createProxy(mod) {

	return new Proxy(function() {}, {

		getPrototypeOf: (target) => {

			mod._exports === null && reload(mod);
			return Reflect.getPrototypeOf(mod._exports);
		},

		setPrototypeOf: (target, prototype) => {

			mod._exports === null && reload(mod);
			return Reflect.setPrototypeOf(mod._exports, prototype);
		},

		isExtensible: (target) => {

			mod._exports === null && reload(mod);
			return Reflect.isExtensible(mod._exports);
		},

		preventExtensions: (target) => {

			mod._exports === null && reload(mod);
			return Reflect.preventExtensions(mod._exports);
		},

		getOwnPropertyDescriptor: (target, prop) => {

			mod._exports === null && reload(mod);
			return Reflect.getOwnPropertyDescriptor(mod._exports, prop);
		},

		defineProperty: (target, property, descriptor) => {

			mod._exports === null && reload(mod);
			return Reflect.defineProperty(mod._exports, property, descriptor);
		},

		has: (target, prop) => {

			mod._exports === null && reload(mod);
			return Reflect.has(mod._exports, prop);
		},

		get: (target, property, receiver) => {

			mod._exports === null && reload(mod);

			// see http://stackoverflow.com/questions/42496414/illegal-invocation-error-using-es6-proxy-and-node-js
			// see https://github.com/nodejs/node/issues/11629
			//var val = Reflect.get(mod._exports, property, receiver);
			//return typeof(val) === 'function' ? val.bind(mod._exports) : val;
			return Reflect.get(mod._exports, property, receiver);
		},

		set: (target, property, value, receiver) => {

			mod._exports === null && reload(mod);
			return Reflect.set(mod._exports, property, value, receiver);
		},

		deleteProperty: (target, property) => {

			mod._exports === null && reload(mod);
			return Reflect.deleteProperty(mod._exports, property);
		},

		ownKeys: (target) => {

			mod._exports === null && reload(mod);
			// see https://tc39.github.io/ecma262/#sec-invariants-of-the-essential-internal-methods
			throw new TypeError('ownKeys not implemented');
			//return [...Reflect.ownKeys(target), ...Reflect.ownKeys(mod._exports)];
			//return Reflect.ownKeys(mod._exports);
		},

		apply: (target, thisArg, argumentsList) => {

			mod._exports === null && reload(mod);
			return Reflect.apply(mod._exports, thisArg, argumentsList);
		},

		construct: (target, argumentsList, newTarget) => {

			mod._exports === null && reload(mod);
			return Reflect.construct(mod._exports, argumentsList, newTarget);
		}
	});
}

Object.defineProperty(Module.prototype, 'invalidable', {
	get: function() {

		return !!this._proxy;
	},
	set: function(value) {

		if ( this._proxy ) {

			if ( !value )
				this._proxy = null;
		} else {

			if ( value )
				this._proxy = createProxy(this);
		}
	}
});

Object.defineProperty(Module.prototype, 'exports', {
	get: function() {

		return this._proxy ? this._proxy : this._exports;
	},
	set: function(value) {

		this._exports = value;
	}
});

/* test
Module.prototype._unload = function() {

	this.exports = null;

	// remove this module from all module children
	for ( var path in this.cache ) {

		var children = this.cache[path].children;
		var pos = children.indexOf(this);
		if ( pos != -1 )
			children.splice(pos);
	}

	// remove module from Module._cache
	delete this.constructor._cache[this.filename];

	this.parent = null;

	this.children.length = 0;

	// remove module from Module._pathCache
	var pathCache = this.constructor._pathCache;
	var keys = Object.keys(pathCache);
	for ( var i = 0; i < keys.length; ++i )
		if ( pathCache[keys[i]] == this.filename )
			delete pathCache[keys[i]];
}
*/
<|endoftext|>


<commit_before>var exec = require('child_process').exec;
var path = require('path');

const DBUS_COMMAND = "bash "+__dirname+"/dbus.sh ";
const DBUS_DEST_DEFAULT = 'org.mpris.MediaPlayer2.omxplayer';

class OmxInstance {

	constructor(options) {
		this.options = options;

		if (options && options.layer) {
			this.dbusDest = DBUS_DEST_DEFAULT + '_layer' + options.layer;
			this.layer = options.layer;
			console.log('setup for layered mode');
		} else {
			this.dbusDest = DBUS_DEST_DEFAULT;
			this.layer = 1;
			console.log('not layered mode');
		}
		console.log('dbus name will be', this.dbusDest);

		exec('mkfifo omxpipe'+this.layer);

		this.defaults = null;
		this.progressHandler = null;

	}

	getLayer() {
		return this.layer;
	}

	cancelProgressHandlerIfActive() {
		if (this.progressHandler) {
			clearInterval(this.progressHandler);
			console.log('progressHandler cancelled');
		}
	}

	dbusCommand (command)  {
		let merge = "bash " +__dirname+"/dbus.sh " + this.dbusDest + " " + command;
		if (command != 'getplaystatus' && command !='getvolume' && command != 'getposition') { console.log('merge:', merge); }
		return merge;
	}

	resume () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already playing
			if (stdout.indexOf("Paused")>-1) {
				this.togglePlay();
			}
		});
	}

	pause () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already paused
			if (stdout.indexOf("Playing")>-1) {
				this.togglePlay();
			}
		});
	}

	stop () {
		exec(this.dbusCommand('stop'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
		});
	}

	quit () {
		exec(this.dbusCommand('quit'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
	  });
	}

	togglePlay () {
		exec(this.dbusCommand('toggleplay'), (error, stdout, stderr) => {});
	}

	seek (offset) {
		//seek offset in seconds; relative from current position; negative values will cause a jump back;
		exec(this.dbusCommand('seek ' +Math.round(offset*1000000)), (error, stdout, stderr) => {});
	}

	setPosition (position) {
		//position in seconds from start; //positions larger than the duration will stop the player;
		exec(this.dbusCommand('setposition '+Math.round(position*1000000)), (error, stdout, stderr) => {});
	}

	setVolume (volume) {
		// volume range [0.0, 1.0];
		if (volume > 0 && volume < 1.0) {
			exec(this.dbusCommand('setvolume '+volume), (error, stdout, stderr) => {});
		}
	}

	setVisibility (visible) {
		let command = visible ? 'unhidevideo' : 'hidevideo';
		exec(this.dbusCommand(command), (err, stdout, stderr) => {});
	}

	setAlpha (alpha) {
		exec(this.dbusCommand('setalpha ' + alpha), (err, stdout, stderr) => {});
	}

	getCurrentPosition () {
		exec(this.dbusCommand('getposition'), (error, stdout, stderr) => {
			if (error) return null;
			let position = parseInt(stdout);
			console.log('currentPosition:', position, 'or in seconds:', position / 1000);
			return position;
	  });
	}

	getIsPlaying () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			if (error) return null;
			return stdout === 'Playing'? true : false;
	  });
	}

	getDuration () {
		exec( this.dbusCommand('getduration'), (error, stdout, stderr) => {
			if (error) return null;
			let duration = parseInt(stdout);
			console.log('getDuration:', duration, 'or in seconds:', duration / 1000);
    	// let duration = Math.round(Math.max(0,Math.round(parseInt(stdout.substring((stdout.indexOf("int64")>-1 ? stdout.indexOf("int64")+6:0)))/10000)/100));

	  });
	}

	getVolume () {
		exec(this.dbusCommand('getvolume'), (error, stdout, stderr) => {
			if (error) return null;
			let volume = parseFloat(stdout);
			console.log('getVolume:', volume);
		});	}

	onProgress (callback) {
		console.log('add new progress handler for layer', this.layer);
		this.progressHandler = setInterval( () => {
			if(this.isPlaying){
				callback({'position': this.getCurrentPosition(), 'duration': this.getDuration()});
			} else {
				callback({ 'playing': false });
			}
		}, 1000);
	}

	onStart (callback) {
		console.log('onStart event');
		if (callback) {
			callback();
		}
	}

	waitTillPlaying (callback) {
		console.log('waitTillPlaying');
		let countAttempts = 0;
		let interval;
		interval = setInterval( () => {
			countAttempts++;
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) {
					console.log('error on getplaystus:', error);
				} else {
					console.log('getplaystatus result after', countAttempts, ':', stdout);
					clearInterval(interval);
					callback();
				}
			});
		}, 1000);
	}

	open (path, doneCallback, holdMode) {
		console.log('OmxInstance open() for layer #', this.layer, 'holdMode?', holdMode);
		let settings = this.options || {};
		let args = [];
		let command = 'omxplayer';

		args.push('"'+path+'"');

		if (['hdmi','local','both'].indexOf(settings.audioOutput) != -1) {
			args.push('-o');
			args.push(settings.audioOutput);
		}

		if (settings.blackBackground !== false) { // defaults to true
			args.push('-b');
		}

		if (settings.disableKeys === true) { //defaults to  false
			args.push('--no-keys')
		}

		if (settings.disableOnScreenDisplay === true) { //defaults to  false
			args.push('--no-osd')
		}

		if (settings.disableGhostbox === true) { //defaults to  false
			args.push('--no-ghost-box');
		}

		if (settings.loop === true) { // defaults to false
			args.push('--loop');
		}

		if (settings.subtitlePath && settings.subtitlePath != "" ){
			args.push('--subtitles');
			args.push('"'+settings.subtitlePath+'"');
		}

		if (settings.startAt){
			args.push('--pos');
			args.push(''+settings.startAt+'');
		}

		if (settings.layer) {
			args.push('--layer');
			args.push(settings.layer);
		}

		if (holdMode) {
			args.push('--alpha');
			args.push(0);
		}

		args.push('--dbus_name');
		args.push(this.dbusDest);

		let finalOpenCommand = command+' '+args.join(' ')+' < omxpipe'+this.layer;
		console.log('finalOpenCommand:', finalOpenCommand);

	  exec(finalOpenCommand, (error, stdout, stderr) => {
			doneCallback();
			console.log('omxpipe done for layer', this.layer);
  		this.cancelProgressHandlerIfActive();
	  	console.log(stdout);
	  });
	  exec(' . > omxpipe'+this.layer, (error, stdout, stderr) => {
			this.waitTillPlaying( () => {
				console.log('started ok');
				this.onStart();
				if (holdMode) {
					console.log('holdMode ON, so immediately pause and hide');
					this.pause();
					this.setVisibility(false);
				}
			});
		});

	}

}

module.exports = OmxInstance;
<commit_msg>log getCurrentPosition results<commit_after>var exec = require('child_process').exec;
var path = require('path');

const DBUS_COMMAND = "bash "+__dirname+"/dbus.sh ";
const DBUS_DEST_DEFAULT = 'org.mpris.MediaPlayer2.omxplayer';

class OmxInstance {

	constructor(options) {
		this.options = options;

		if (options && options.layer) {
			this.dbusDest = DBUS_DEST_DEFAULT + '_layer' + options.layer;
			this.layer = options.layer;
			console.log('setup for layered mode');
		} else {
			this.dbusDest = DBUS_DEST_DEFAULT;
			this.layer = 1;
			console.log('not layered mode');
		}
		console.log('dbus name will be', this.dbusDest);

		exec('mkfifo omxpipe'+this.layer);

		this.defaults = null;
		this.progressHandler = null;

	}

	getLayer() {
		return this.layer;
	}

	cancelProgressHandlerIfActive() {
		if (this.progressHandler) {
			clearInterval(this.progressHandler);
			console.log('progressHandler cancelled');
		}
	}

	dbusCommand (command)  {
		let merge = "bash " +__dirname+"/dbus.sh " + this.dbusDest + " " + command;
		if (command != 'getplaystatus' && command !='getvolume' && command != 'getposition') { console.log('merge:', merge); }
		return merge;
	}

	resume () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already playing
			if (stdout.indexOf("Paused")>-1) {
				this.togglePlay();
			}
		});
	}

	pause () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already paused
			if (stdout.indexOf("Playing")>-1) {
				this.togglePlay();
			}
		});
	}

	stop () {
		exec(this.dbusCommand('stop'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
		});
	}

	quit () {
		exec(this.dbusCommand('quit'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
	  });
	}

	togglePlay () {
		exec(this.dbusCommand('toggleplay'), (error, stdout, stderr) => {});
	}

	seek (offset) {
		//seek offset in seconds; relative from current position; negative values will cause a jump back;
		exec(this.dbusCommand('seek ' +Math.round(offset*1000000)), (error, stdout, stderr) => {});
	}

	setPosition (position) {
		//position in seconds from start; //positions larger than the duration will stop the player;
		exec(this.dbusCommand('setposition '+Math.round(position*1000000)), (error, stdout, stderr) => {});
	}

	setVolume (volume) {
		// volume range [0.0, 1.0];
		if (volume > 0 && volume < 1.0) {
			exec(this.dbusCommand('setvolume '+volume), (error, stdout, stderr) => {});
		}
	}

	setVisibility (visible) {
		let command = visible ? 'unhidevideo' : 'hidevideo';
		exec(this.dbusCommand(command), (err, stdout, stderr) => {});
	}

	setAlpha (alpha) {
		exec(this.dbusCommand('setalpha ' + alpha), (err, stdout, stderr) => {});
	}

	getCurrentPosition () {
		console.log('getCurrentPosition');
		exec(this.dbusCommand('getposition'), (error, stdout, stderr) => {
			consoel.log('getCurrentPosition error, stdout, stderr:', error, stdout, stderr);
			if (error) return null;
			let position = parseInt(stdout);
			console.log('currentPosition:', position, 'or in seconds:', position / 1000);
			return position;
	  });
	}

	getIsPlaying () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			if (error) return null;
			return stdout === 'Playing'? true : false;
	  });
	}

	getDuration () {
		exec( this.dbusCommand('getduration'), (error, stdout, stderr) => {
			if (error) return null;
			let duration = parseInt(stdout);
			console.log('getDuration:', duration, 'or in seconds:', duration / 1000);
    	// let duration = Math.round(Math.max(0,Math.round(parseInt(stdout.substring((stdout.indexOf("int64")>-1 ? stdout.indexOf("int64")+6:0)))/10000)/100));

	  });
	}

	getVolume () {
		exec(this.dbusCommand('getvolume'), (error, stdout, stderr) => {
			if (error) return null;
			let volume = parseFloat(stdout);
			console.log('getVolume:', volume);
		});	}

	onProgress (callback) {
		console.log('add new progress handler for layer', this.layer);
		this.progressHandler = setInterval( () => {
			if(this.isPlaying){
				callback({'position': this.getCurrentPosition(), 'duration': this.getDuration()});
			} else {
				callback({ 'playing': false });
			}
		}, 1000);
	}

	onStart (callback) {
		console.log('onStart event');
		if (callback) {
			callback();
		}
	}

	waitTillPlaying (callback) {
		console.log('waitTillPlaying');
		let countAttempts = 0;
		let interval;
		interval = setInterval( () => {
			countAttempts++;
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) {
					console.log('error on getplaystus:', error);
				} else {
					console.log('getplaystatus result after', countAttempts, ':', stdout);
					clearInterval(interval);
					callback();
				}
			});
		}, 1000);
	}

	open (path, doneCallback, holdMode) {
		console.log('OmxInstance open() for layer #', this.layer, 'holdMode?', holdMode);
		let settings = this.options || {};
		let args = [];
		let command = 'omxplayer';

		args.push('"'+path+'"');

		if (['hdmi','local','both'].indexOf(settings.audioOutput) != -1) {
			args.push('-o');
			args.push(settings.audioOutput);
		}

		if (settings.blackBackground !== false) { // defaults to true
			args.push('-b');
		}

		if (settings.disableKeys === true) { //defaults to  false
			args.push('--no-keys')
		}

		if (settings.disableOnScreenDisplay === true) { //defaults to  false
			args.push('--no-osd')
		}

		if (settings.disableGhostbox === true) { //defaults to  false
			args.push('--no-ghost-box');
		}

		if (settings.loop === true) { // defaults to false
			args.push('--loop');
		}

		if (settings.subtitlePath && settings.subtitlePath != "" ){
			args.push('--subtitles');
			args.push('"'+settings.subtitlePath+'"');
		}

		if (settings.startAt){
			args.push('--pos');
			args.push(''+settings.startAt+'');
		}

		if (settings.layer) {
			args.push('--layer');
			args.push(settings.layer);
		}

		if (holdMode) {
			args.push('--alpha');
			args.push(0);
		}

		args.push('--dbus_name');
		args.push(this.dbusDest);

		let finalOpenCommand = command+' '+args.join(' ')+' < omxpipe'+this.layer;
		console.log('finalOpenCommand:', finalOpenCommand);

	  exec(finalOpenCommand, (error, stdout, stderr) => {
			doneCallback();
			console.log('omxpipe done for layer', this.layer);
  		this.cancelProgressHandlerIfActive();
	  	console.log(stdout);
	  });
	  exec(' . > omxpipe'+this.layer, (error, stdout, stderr) => {
			this.waitTillPlaying( () => {
				console.log('started ok');
				this.onStart();
				if (holdMode) {
					console.log('holdMode ON, so immediately pause and hide');
					this.pause();
					this.setVisibility(false);
				}
			});
		});

	}

}

module.exports = OmxInstance;
<|endoftext|>


<commit_before>var vdf = require('vdf');
var fs = require('fs');
var SteamID = require('steamid');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	var interval = setInterval(function() {
		// TODO: Clear interval when we shut down TF2 in case the GC connection is never established
		if(self.haveGCSession) {
			clearInterval(interval);
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 5000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype.craft = function(items, recipe) {
	var buffer = new Buffer(2 + 2 + (8 * items.length));
	buffer.writeInt16LE(recipe || -2, 0); // -2 is wildcard
	buffer.writeInt16LE(items.length, 2);
	for(var i = 0; i < items.length; i++) {
		buffer.writeUInt64LE(items[i], 4 + (i * 8));
	}

	this._send(Language.Craft, null, buffer);
};

TeamFortress2.prototype.trade = function(steamID) {
	var buffer = new Buffer(12);
	buffer.writeUInt32LE(0, 0);
	buffer.writeUInt64LE(steamID, 4);
	this._send(Language.Trading_InitiateTradeRequest, null, buffer);
};

TeamFortress2.prototype.setStyle = function(item, style) {
	var buffer = new Buffer(12);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt32LE(style, 8);
	this._send(Language.SetItemStyle, null, buffer);
};

TeamFortress2.prototype.setPosition = function(item, position) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt64LE(position, 8);
	this._send(Language.SetSingleItemPosition, null, buffer);
};

TeamFortress2.prototype.deleteItem = function(item) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(item);
	this._send(Language.Delete, null, buffer);
};

TeamFortress2.prototype.wrapItem = function(wrapID, itemID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(wrapID, 0);
	buffer.writeUInt64LE(itemID, 8);
	this._send(Language.GiftWrapItem, null, buffer);
};

TeamFortress2.prototype.deliverGift = function(gift, steamID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(gift, 0);
	buffer.writeUInt64LE(steamID, 8);
	this._send(Language.DeliverGift, null, buffer);
};

TeamFortress2.prototype.unwrapGift = function(gift) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(gift);
	this._send(Language.UnwrapGiftRequest, null, buffer);
};

TeamFortress2.prototype.useItem = function(item) {
	this._send(Language.UseItemRequest, base_gcmessages.CMsgUseItem, {"itemId": item});
};

TeamFortress2.prototype.sortBackpack = function(sortType) {
	this._send(Language.SortItems, base_gcmessages.CMsgSortItems, {"sortType": sortType});
};

TeamFortress2.prototype.sendProfessorSpeks = function(accountID) {
	this._send(Language.FreeTrial_ChooseMostHelpfulFriend, tf_gcmessages.CMsgTFFreeTrialChooseMostHelpfulFriend, {"accountIdFriend": accountID});
};

TeamFortress2.prototype.createServerIdentity = function() {
	this._send(Language.GameServer_CreateIdentity, tf_gcmessages.CMsgGC_GameServer_CreateIdentity, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.getRegisteredServers = function() {
	this._send(Language.GameServer_List, tf_gcmessages.CMsgGC_GameServer_List, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.resetServerIdentity = function(id) {
	this._send(Language.GameServer_ResetIdentity, tf_gcmessages.CMsgGC_GameServer_ResetIdentity, {"gameServerAccountId": id});
};

TeamFortress2.prototype._handlers = {};

require('./enums.js');
require('./handlers.js');<commit_msg>Make sendProfessorSpeks take a steamID<commit_after>var vdf = require('vdf');
var fs = require('fs');
var SteamID = require('steamid');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	var interval = setInterval(function() {
		// TODO: Clear interval when we shut down TF2 in case the GC connection is never established
		if(self.haveGCSession) {
			clearInterval(interval);
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 5000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype.craft = function(items, recipe) {
	var buffer = new Buffer(2 + 2 + (8 * items.length));
	buffer.writeInt16LE(recipe || -2, 0); // -2 is wildcard
	buffer.writeInt16LE(items.length, 2);
	for(var i = 0; i < items.length; i++) {
		buffer.writeUInt64LE(items[i], 4 + (i * 8));
	}

	this._send(Language.Craft, null, buffer);
};

TeamFortress2.prototype.trade = function(steamID) {
	var buffer = new Buffer(12);
	buffer.writeUInt32LE(0, 0);
	buffer.writeUInt64LE(steamID, 4);
	this._send(Language.Trading_InitiateTradeRequest, null, buffer);
};

TeamFortress2.prototype.setStyle = function(item, style) {
	var buffer = new Buffer(12);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt32LE(style, 8);
	this._send(Language.SetItemStyle, null, buffer);
};

TeamFortress2.prototype.setPosition = function(item, position) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(item, 0);
	buffer.writeUInt64LE(position, 8);
	this._send(Language.SetSingleItemPosition, null, buffer);
};

TeamFortress2.prototype.deleteItem = function(item) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(item);
	this._send(Language.Delete, null, buffer);
};

TeamFortress2.prototype.wrapItem = function(wrapID, itemID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(wrapID, 0);
	buffer.writeUInt64LE(itemID, 8);
	this._send(Language.GiftWrapItem, null, buffer);
};

TeamFortress2.prototype.deliverGift = function(gift, steamID) {
	var buffer = new Buffer(16);
	buffer.writeUInt64LE(gift, 0);
	buffer.writeUInt64LE(steamID, 8);
	this._send(Language.DeliverGift, null, buffer);
};

TeamFortress2.prototype.unwrapGift = function(gift) {
	var buffer = new Buffer(8);
	buffer.writeUInt64LE(gift);
	this._send(Language.UnwrapGiftRequest, null, buffer);
};

TeamFortress2.prototype.useItem = function(item) {
	this._send(Language.UseItemRequest, base_gcmessages.CMsgUseItem, {"itemId": item});
};

TeamFortress2.prototype.sortBackpack = function(sortType) {
	this._send(Language.SortItems, base_gcmessages.CMsgSortItems, {"sortType": sortType});
};

TeamFortress2.prototype.sendProfessorSpeks = function(steamID) {
	this._send(Language.FreeTrial_ChooseMostHelpfulFriend, tf_gcmessages.CMsgTFFreeTrialChooseMostHelpfulFriend, {"accountIdFriend": new SteamID(steamID).accountid});
};

TeamFortress2.prototype.createServerIdentity = function() {
	this._send(Language.GameServer_CreateIdentity, tf_gcmessages.CMsgGC_GameServer_CreateIdentity, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.getRegisteredServers = function() {
	this._send(Language.GameServer_List, tf_gcmessages.CMsgGC_GameServer_List, {"accountId": new SteamID(this._steam.steamID).accountid});
};

TeamFortress2.prototype.resetServerIdentity = function(id) {
	this._send(Language.GameServer_ResetIdentity, tf_gcmessages.CMsgGC_GameServer_ResetIdentity, {"gameServerAccountId": id});
};

TeamFortress2.prototype._handlers = {};

require('./enums.js');
require('./handlers.js');<|endoftext|>


<commit_before>
module.exports = function (expected) {
	var steps = expected || [];
	var step = 0;

	var stub = function () {
		if (step > steps.length - 1) {
			var tooManyTimes = 'Stepper was called too many times. Offending arguments:';
			for( var argIndex in arguments) {
				tooManyTimes += '\n index: ' + argIndex + ' value: ' + arguments[argIndex];
			}
			throw new Error(tooManyTimes);
		}

		return steps[step++].apply(null, arguments);
	};

	stub.add = function (fn, count) {
	  count = count || 1;
	  for(var i = 0; i < count; i++) {
	    steps.push(fn);
	  }
		return stub;
	};

	stub.onCall = function (i, fn) {
		steps[i] = fn;
		return stub;
	};

	stub.onFirstCall = function (fn) {
		return stub.onCall(0, fn);
	};

	stub.onSecondCall = function (fn) {
		return stub.onCall(1, fn);
	};

	stub.onThirdCall = function (fn) {
		return stub.onCall(2, fn);
	};

	stub.reset = function (newsteps) {
		step = 0;
		if (Array.isArray(newsteps)) {
			steps = newsteps;
		} else if (newsteps === true) {
			steps = [];
		}
	};

	stub.as = function (name) {
		return stub.bind(null, name);
	};

	return stub;
};
<commit_msg>Fix .reset not returning the stepper instance for chaining<commit_after>
module.exports = function (expected) {
	var steps = expected || [];
	var step = 0;

	var stub = function () {
		if (step > steps.length - 1) {
			var tooManyTimes = 'Stepper was called too many times. Offending arguments:';
			for( var argIndex in arguments) {
				tooManyTimes += '\n index: ' + argIndex + ' value: ' + arguments[argIndex];
			}
			throw new Error(tooManyTimes);
		}

		return steps[step++].apply(null, arguments);
	};

	stub.add = function (fn, count) {
	  count = count || 1;
	  for(var i = 0; i < count; i++) {
	    steps.push(fn);
	  }
		return stub;
	};

	stub.onCall = function (i, fn) {
		steps[i] = fn;
		return stub;
	};

	stub.onFirstCall = function (fn) {
		return stub.onCall(0, fn);
	};

	stub.onSecondCall = function (fn) {
		return stub.onCall(1, fn);
	};

	stub.onThirdCall = function (fn) {
		return stub.onCall(2, fn);
	};

	stub.reset = function (newsteps) {
		step = 0;
		if (Array.isArray(newsteps)) {
			steps = newsteps;
		} else if (newsteps === true) {
			steps = [];
		}
		return stub;
	};

	stub.as = function (name) {
		return stub.bind(null, name);
	};

	return stub;
};
<|endoftext|>


<commit_before>'use strict'

module.exports = [
  '0.0.1'
, '0.0.2'
, '0.0.3'
, '0.0.4'
, '0.0.5'
, '0.0.6'
, '0.1.0'
, '0.1.1'
, '0.1.2'
, '0.1.3'
, '0.1.4'
, '0.1.5'
, '0.1.6'
, '0.1.7'
, '0.1.8'
, '0.1.9'
, '0.1.10'
, '0.1.11'
, '0.1.12'
, '0.1.13'
, '0.1.14'
, '0.1.15'
, '0.1.16'
, '0.1.17'
, '0.1.18'
, '0.1.19'
, '0.1.20'
, '0.1.21'
, '0.1.22'
, '0.1.23'
, '0.1.24'
, '0.1.25'
, '0.1.26'
, '0.1.27'
, '0.1.28'
, '0.1.29'
, '0.1.30'
, '0.1.31'
, '0.1.32'
, '0.1.33'
, '0.1.90'
, '0.1.91'
, '0.1.92'
, '0.1.93'
, '0.1.94'
, '0.1.95'
, '0.1.96'
, '0.1.97'
, '0.1.98'
, '0.1.99'
, '0.1.100'
, '0.1.101'
, '0.1.102'
, '0.1.103'
, '0.1.104'
, '0.2.0'
, '0.2.1'
, '0.2.2'
, '0.2.3'
, '0.2.4'
, '0.2.5'
, '0.2.6'
, '0.3.0'
, '0.3.1'
, '0.3.2'
, '0.3.3'
, '0.3.4'
, '0.3.5'
, '0.3.6'
, '0.3.7'
, '0.3.8'
, '0.4.0'
, '0.4.1'
, '0.4.2'
, '0.4.3'
, '0.4.4'
, '0.4.5'
, '0.4.6'
, '0.4.7'
, '0.4.8'
, '0.4.9'
, '0.4.10'
, '0.4.11'
, '0.4.12'
, '0.5.0'
, '0.5.1'
, '0.5.2'
, '0.5.3'
, '0.5.4'
, '0.5.5'
, '0.5.6'
, '0.5.7'
, '0.5.8'
, '0.5.9'
, '0.5.10'
, '0.6.0'
, '0.6.1'
, '0.6.2'
, '0.6.3'
, '0.6.4'
, '0.6.5'
, '0.6.6'
, '0.6.7'
, '0.6.8'
, '0.6.9'
, '0.6.10'
, '0.6.11'
, '0.6.12'
, '0.6.13'
, '0.6.14'
, '0.6.15'
, '0.6.16'
, '0.6.17'
, '0.6.18'
, '0.6.19'
, '0.6.20'
, '0.6.21'
, '0.7.0'
, '0.7.1'
, '0.7.2'
, '0.7.3'
, '0.7.4'
, '0.7.5'
, '0.7.6'
, '0.7.7'
, '0.7.8'
, '0.7.9'
, '0.7.10'
, '0.7.11'
, '0.7.12'
, '0.8.0'
, '0.8.1'
, '0.8.2'
, '0.8.3'
, '0.8.4'
, '0.8.5'
, '0.8.6'
, '0.8.7'
, '0.8.8'
, '0.8.9'
, '0.8.10'
, '0.8.11'
, '0.8.12'
, '0.8.13'
, '0.8.14'
, '0.8.15'
, '0.8.16'
, '0.8.17'
, '0.8.18'
, '0.8.19'
, '0.8.20'
, '0.8.21'
, '0.8.22'
, '0.8.23'
, '0.8.24'
, '0.8.25'
, '0.8.26'
, '0.8.27'
, '0.8.28'
, '0.9.0'
, '0.9.1'
, '0.9.2'
, '0.9.3'
, '0.9.4'
, '0.9.5'
, '0.9.6'
, '0.9.7'
, '0.9.8'
, '0.9.9'
, '0.9.10'
, '0.9.11'
, '0.9.12'
, '0.10.0'
, '0.10.1'
, '0.10.2'
, '0.10.3'
, '0.10.4'
, '0.10.5'
, '0.10.6'
, '0.10.7'
, '0.10.8'
, '0.10.9'
, '0.10.10'
, '0.10.11'
, '0.10.12'
, '0.10.13'
, '0.10.14'
, '0.10.15'
, '0.10.16'
, '0.10.17'
, '0.10.18'
, '0.10.19'
, '0.10.20'
, '0.10.21'
, '0.10.22'
, '0.10.23'
, '0.10.24'
, '0.10.25'
, '0.10.26'
, '0.10.27'
, '0.10.28'
, '0.10.29'
, '0.10.30'
, '0.10.31'
, '0.10.32'
, '0.10.33'
, '0.10.34'
, '0.10.35'
, '0.10.36'
, '0.10.37'
, '0.10.38'
, '0.10.39'
, '0.10.40'
, '0.10.41'
, '0.10.42'
, '0.10.43'
, '0.10.44'
, '0.11.0'
, '0.11.1'
, '0.11.2'
, '0.11.3'
, '0.11.4'
, '0.11.5'
, '0.11.6'
, '0.11.7'
, '0.11.8'
, '0.11.9'
, '0.11.10'
, '0.11.11'
, '0.11.12'
, '0.11.13'
, '0.11.14'
, '0.11.15'
, '0.11.16'
, '0.12.0'
, '0.12.1'
, '0.12.2'
, '0.12.3'
, '0.12.4'
, '0.12.5'
, '0.12.6'
, '0.12.7'
, '0.12.8'
, '0.12.9'
, '0.12.10'
, '0.12.11'
, '0.12.12'
, '0.12.13'
, '1.0.0'
, '1.0.1'
, '1.0.2'
, '1.0.3'
, '1.0.4'
, '1.1.0'
, '1.2.0'
, '1.3.0'
, '1.4.1'
, '1.4.2'
, '1.4.3'
, '1.5.0'
, '1.5.1'
, '1.6.0'
, '1.6.1'
, '1.6.2'
, '1.6.3'
, '1.6.4'
, '1.7.0'
, '1.7.1'
, '1.8.1'
, '1.8.2'
, '1.8.3'
, '1.8.4'
, '2.0.0'
, '2.0.1'
, '2.0.2'
, '2.1.0'
, '2.2.0'
, '2.2.1'
, '2.3.0'
, '2.3.1'
, '2.3.2'
, '2.3.3'
, '2.3.4'
, '2.4.0'
, '2.5.0'
, '3.0.0'
, '3.1.0'
, '3.2.0'
, '3.3.0'
, '3.3.1'
, '4.0.0'
, '4.1.0'
, '4.1.1'
, '4.1.2'
, '4.2.0'
, '4.2.1'
, '4.2.2'
, '4.2.3'
, '4.2.4'
, '4.2.5'
, '4.2.6'
, '4.3.0'
, '4.3.1'
, '4.3.2'
, '4.4.0'
, '4.4.1'
, '4.4.2'
, '4.4.3'
, '5.0.0'
, '5.1.0'
, '5.1.1'
, '5.2.0'
, '5.3.0'
, '5.4.0'
, '5.4.1'
, '5.5.0'
, '5.6.0'
, '5.7.0'
, '5.7.1'
, '5.8.0'
, '5.9.0'
, '5.9.1'
, '5.10.0'
, '5.10.1'
, '5.11.0'
, '6.0.0'
]
<commit_msg>add v0.10.45<commit_after>'use strict'

module.exports = [
  '0.0.1'
, '0.0.2'
, '0.0.3'
, '0.0.4'
, '0.0.5'
, '0.0.6'
, '0.1.0'
, '0.1.1'
, '0.1.2'
, '0.1.3'
, '0.1.4'
, '0.1.5'
, '0.1.6'
, '0.1.7'
, '0.1.8'
, '0.1.9'
, '0.1.10'
, '0.1.11'
, '0.1.12'
, '0.1.13'
, '0.1.14'
, '0.1.15'
, '0.1.16'
, '0.1.17'
, '0.1.18'
, '0.1.19'
, '0.1.20'
, '0.1.21'
, '0.1.22'
, '0.1.23'
, '0.1.24'
, '0.1.25'
, '0.1.26'
, '0.1.27'
, '0.1.28'
, '0.1.29'
, '0.1.30'
, '0.1.31'
, '0.1.32'
, '0.1.33'
, '0.1.90'
, '0.1.91'
, '0.1.92'
, '0.1.93'
, '0.1.94'
, '0.1.95'
, '0.1.96'
, '0.1.97'
, '0.1.98'
, '0.1.99'
, '0.1.100'
, '0.1.101'
, '0.1.102'
, '0.1.103'
, '0.1.104'
, '0.2.0'
, '0.2.1'
, '0.2.2'
, '0.2.3'
, '0.2.4'
, '0.2.5'
, '0.2.6'
, '0.3.0'
, '0.3.1'
, '0.3.2'
, '0.3.3'
, '0.3.4'
, '0.3.5'
, '0.3.6'
, '0.3.7'
, '0.3.8'
, '0.4.0'
, '0.4.1'
, '0.4.2'
, '0.4.3'
, '0.4.4'
, '0.4.5'
, '0.4.6'
, '0.4.7'
, '0.4.8'
, '0.4.9'
, '0.4.10'
, '0.4.11'
, '0.4.12'
, '0.5.0'
, '0.5.1'
, '0.5.2'
, '0.5.3'
, '0.5.4'
, '0.5.5'
, '0.5.6'
, '0.5.7'
, '0.5.8'
, '0.5.9'
, '0.5.10'
, '0.6.0'
, '0.6.1'
, '0.6.2'
, '0.6.3'
, '0.6.4'
, '0.6.5'
, '0.6.6'
, '0.6.7'
, '0.6.8'
, '0.6.9'
, '0.6.10'
, '0.6.11'
, '0.6.12'
, '0.6.13'
, '0.6.14'
, '0.6.15'
, '0.6.16'
, '0.6.17'
, '0.6.18'
, '0.6.19'
, '0.6.20'
, '0.6.21'
, '0.7.0'
, '0.7.1'
, '0.7.2'
, '0.7.3'
, '0.7.4'
, '0.7.5'
, '0.7.6'
, '0.7.7'
, '0.7.8'
, '0.7.9'
, '0.7.10'
, '0.7.11'
, '0.7.12'
, '0.8.0'
, '0.8.1'
, '0.8.2'
, '0.8.3'
, '0.8.4'
, '0.8.5'
, '0.8.6'
, '0.8.7'
, '0.8.8'
, '0.8.9'
, '0.8.10'
, '0.8.11'
, '0.8.12'
, '0.8.13'
, '0.8.14'
, '0.8.15'
, '0.8.16'
, '0.8.17'
, '0.8.18'
, '0.8.19'
, '0.8.20'
, '0.8.21'
, '0.8.22'
, '0.8.23'
, '0.8.24'
, '0.8.25'
, '0.8.26'
, '0.8.27'
, '0.8.28'
, '0.9.0'
, '0.9.1'
, '0.9.2'
, '0.9.3'
, '0.9.4'
, '0.9.5'
, '0.9.6'
, '0.9.7'
, '0.9.8'
, '0.9.9'
, '0.9.10'
, '0.9.11'
, '0.9.12'
, '0.10.0'
, '0.10.1'
, '0.10.2'
, '0.10.3'
, '0.10.4'
, '0.10.5'
, '0.10.6'
, '0.10.7'
, '0.10.8'
, '0.10.9'
, '0.10.10'
, '0.10.11'
, '0.10.12'
, '0.10.13'
, '0.10.14'
, '0.10.15'
, '0.10.16'
, '0.10.17'
, '0.10.18'
, '0.10.19'
, '0.10.20'
, '0.10.21'
, '0.10.22'
, '0.10.23'
, '0.10.24'
, '0.10.25'
, '0.10.26'
, '0.10.27'
, '0.10.28'
, '0.10.29'
, '0.10.30'
, '0.10.31'
, '0.10.32'
, '0.10.33'
, '0.10.34'
, '0.10.35'
, '0.10.36'
, '0.10.37'
, '0.10.38'
, '0.10.39'
, '0.10.40'
, '0.10.41'
, '0.10.42'
, '0.10.43'
, '0.10.44'
, '0.10.45'
, '0.11.0'
, '0.11.1'
, '0.11.2'
, '0.11.3'
, '0.11.4'
, '0.11.5'
, '0.11.6'
, '0.11.7'
, '0.11.8'
, '0.11.9'
, '0.11.10'
, '0.11.11'
, '0.11.12'
, '0.11.13'
, '0.11.14'
, '0.11.15'
, '0.11.16'
, '0.12.0'
, '0.12.1'
, '0.12.2'
, '0.12.3'
, '0.12.4'
, '0.12.5'
, '0.12.6'
, '0.12.7'
, '0.12.8'
, '0.12.9'
, '0.12.10'
, '0.12.11'
, '0.12.12'
, '0.12.13'
, '1.0.0'
, '1.0.1'
, '1.0.2'
, '1.0.3'
, '1.0.4'
, '1.1.0'
, '1.2.0'
, '1.3.0'
, '1.4.1'
, '1.4.2'
, '1.4.3'
, '1.5.0'
, '1.5.1'
, '1.6.0'
, '1.6.1'
, '1.6.2'
, '1.6.3'
, '1.6.4'
, '1.7.0'
, '1.7.1'
, '1.8.1'
, '1.8.2'
, '1.8.3'
, '1.8.4'
, '2.0.0'
, '2.0.1'
, '2.0.2'
, '2.1.0'
, '2.2.0'
, '2.2.1'
, '2.3.0'
, '2.3.1'
, '2.3.2'
, '2.3.3'
, '2.3.4'
, '2.4.0'
, '2.5.0'
, '3.0.0'
, '3.1.0'
, '3.2.0'
, '3.3.0'
, '3.3.1'
, '4.0.0'
, '4.1.0'
, '4.1.1'
, '4.1.2'
, '4.2.0'
, '4.2.1'
, '4.2.2'
, '4.2.3'
, '4.2.4'
, '4.2.5'
, '4.2.6'
, '4.3.0'
, '4.3.1'
, '4.3.2'
, '4.4.0'
, '4.4.1'
, '4.4.2'
, '4.4.3'
, '5.0.0'
, '5.1.0'
, '5.1.1'
, '5.2.0'
, '5.3.0'
, '5.4.0'
, '5.4.1'
, '5.5.0'
, '5.6.0'
, '5.7.0'
, '5.7.1'
, '5.8.0'
, '5.9.0'
, '5.9.1'
, '5.10.0'
, '5.10.1'
, '5.11.0'
, '6.0.0'
]
<|endoftext|>


<commit_before>'use strict';

var Leverage = require('leverage');

//
// Expose the Metroplex plugin.
//
var metroplex = module.exports;

/**
 * Add defaults to the supplied options. The following options are available:
 *
 * - redis: The Redis instance we should use to store data
 * - namespace: The namespace prefix to prevent collision's.
 * - interval: Expire interval to keep the server alive in Redis
 * - timeout: Timeout for sparks who are alive.
 * - latency: Time it takes for our Redis commands to execute.
 *
 * @param {Primus} primus The Primus instance that received the plugin.
 * @param {Object} options Configuration.
 * @returns {Object} Options.
 * @api public
 */
metroplex.options = function optional(primus, options) {
  var address = primus.server.address();

  options = options || {};

  options.redis = options.redis || require('redis').createClient();
  options.namespace = options.namespace || 'metroplex';
  options.interval = options.interval || 5 * 60 * 1000;
  options.timeout = options.timeout || 30 * 60;
  options.latency = options.latency || 2000;

  if (address) {
    options.address = options.address || 'http://localhost:'+ address.port;
  }

  options.leverage = new Leverage(options.redis, {
    namespace: options.namespace
  });

  return options;
};

/**
 * Keep the presence or "state" of each connection in Redis.
 *
 * @param {Primus} primus The Primus instance that received the plugin.
 * @param {Object} options The options that were supplied to Primus.
 * @api public
 */
metroplex.server = function server(primus, options)  {
  primus.options = options = metroplex.options(primus, options);

  var namespace = options.namespace +':'
    , leverage = options.leverage
    , address = options.address
    , redis = options.redis;

  primus.on('connection', function connection(spark) {
    redis.multi()
      .hadd(namespace +':sparks', spark.id, address)
      .sadd(namespace +':'+ address, spark.id)
    .exec();
  }).on('disconnection', function disconnection(spark) {
    redis.multi()
      .hdel(namespace +':sparks', spark.id)
      .srem(namespace +':'+ address, spark.id)
    .exec();
  });

  primus.on('close', function close() {
    if (address) redis.srem(namespace +':servers', address, function (err) {
      primus.emit('unregister', address);
    });
  }).server.on('listening', function listening() {
    var local = 'http://localhost:'+ primus.server.address().port
      , stored = !!options.address;

    //
    // We can only get the server's port number when the server starts
    // listening. So if our address is still undefined, it's only now that we
    // can provide a default value.
    //
    address = options.address = options.address || local;

    //
    // Only store the address if we haven't stored it already.
    //
    if (!stored) metroplex.register(primus, options);
  });

  /**
   * Get all current registered servers except our selfs.
   *
   * @param {Function} fn Callback
   * @api private
   */
  primus.servers = function servers(fn) {
    redis.smembers(namespace +':servers', function (err, members) {
      fn(err, (members || []).filter(function filter(address) {
        return address !== options.address;
      }));
    });
  };

  if (address) metroplex.register(primus, options);

  //
  // We need to make sure that this server is alive, the most easy and dirty way
  // of doing this is setting an interval which bumps the expire of our
  // dedicated server key. If we go off line, the key will expire and we will be
  // K.O. The value indicates the last "ping" that we got from the node server
  // so you can see when the last update was.
  //
  var alive = setInterval(function interval() {
    redis.setex(namespace +':'+ address, options.interval, Date.now());
  }, options.interval - options.latency);

  if ('function' === alive.unref) alive.unref();
};

/**
 * Scan the Redis database for dead servers and reap the dead servers.
 *
 * @param {Primus} primus Our current Primus instance.
 * @param {Object} options The options.
 * @api private
 */
metroplex.scan = function scan(primus, options) {
  var namespace = options.namespace
    , leverage = options.leverage
    , redis = options.redis;

  primus.servers(function find(err, servers) {
    servers.forEach(function expired(address) {
      redis.get(namespace +':'+ address, function get(err, stamp) {
        if (err || Date.now() - +stamp < options.interval) return;

        leverage.annihilate(address);
      });
    });
  });
};

/**
 * Register a new Primus server in the Redis database.
 *
 * @param {Primus} primus Our current Primus instance.
 * @param {Object} options The options.
 * @api private
 */
metroplex.register = function register(primus, options) {
  var namespace = options.namespace
    , leverage = options.leverage
    , redis = options.redis;

  leverage.annihilate(options.address, function (err) {
    if (err) console.error('metroplex:register:error', err.stack);

    redis.multi()
      .setex(namespace +':'+ options.address, options.interval, Date.now())
      .sadd(namespace +':servers', options.address)
    .exec(function register(err) {
      if (err) console.error('metroplex:register:error', err.stack);

      primus.emit('register', options.address);
    });
  });
};
<commit_msg>[fix] Extend the list of reserved events with `metroplex` events<commit_after>'use strict';

var Leverage = require('leverage');

//
// Expose the Metroplex plugin.
//
var metroplex = module.exports;

/**
 * Add defaults to the supplied options. The following options are available:
 *
 * - redis: The Redis instance we should use to store data
 * - namespace: The namespace prefix to prevent collision's.
 * - interval: Expire interval to keep the server alive in Redis
 * - timeout: Timeout for sparks who are alive.
 * - latency: Time it takes for our Redis commands to execute.
 *
 * @param {Primus} primus The Primus instance that received the plugin.
 * @param {Object} options Configuration.
 * @returns {Object} Options.
 * @api public
 */
metroplex.options = function optional(primus, options) {
  var address = primus.server.address();

  options = options || {};

  options.redis = options.redis || require('redis').createClient();
  options.namespace = options.namespace || 'metroplex';
  options.interval = options.interval || 5 * 60 * 1000;
  options.timeout = options.timeout || 30 * 60;
  options.latency = options.latency || 2000;

  if (address) {
    options.address = options.address || 'http://localhost:'+ address.port;
  }

  options.leverage = new Leverage(options.redis, {
    namespace: options.namespace
  });

  return options;
};

/**
 * Keep the presence or "state" of each connection in Redis.
 *
 * @param {Primus} primus The Primus instance that received the plugin.
 * @param {Object} options The options that were supplied to Primus.
 * @api public
 */
metroplex.server = function server(primus, options)  {
  primus.options = options = metroplex.options(primus, options);

  var namespace = options.namespace +':'
    , address = options.address
    , redis = options.redis;

  primus.on('connection', function connection(spark) {
    redis.multi()
      .hadd(namespace +':sparks', spark.id, address)
      .sadd(namespace +':'+ address, spark.id)
    .exec();
  }).on('disconnection', function disconnection(spark) {
    redis.multi()
      .hdel(namespace +':sparks', spark.id)
      .srem(namespace +':'+ address, spark.id)
    .exec();
  });

  primus.on('close', function close() {
    if (address) redis.srem(namespace +':servers', address, function (err) {
      if (err) return console.error('metroplex:unregister:error', err.stack);

      primus.emit('unregister', address);
    });
  }).server.on('listening', function listening() {
    var local = 'http://localhost:'+ primus.server.address().port
      , stored = !!options.address;

    //
    // We can only get the server's port number when the server starts
    // listening. So if our address is still undefined, it's only now that we
    // can provide a default value.
    //
    address = options.address = options.address || local;

    //
    // Only store the address if we haven't stored it already.
    //
    if (!stored) metroplex.register(primus, options);
  });

  //
  // Extend the list of reserved events with `metroplex` events.
  //
  ['register', 'unregister'].forEach(function reserved(event) {
    primus.reserved.events[event] = 1;
  });

  /**
   * Get all current registered servers except our selfs.
   *
   * @param {Function} fn Callback
   * @api private
   */
  primus.servers = function servers(fn) {
    redis.smembers(namespace +':servers', function (err, members) {
      fn(err, (members || []).filter(function filter(address) {
        return address !== options.address;
      }));
    });
  };

  if (address) metroplex.register(primus, options);

  //
  // We need to make sure that this server is alive, the most easy and dirty way
  // of doing this is setting an interval which bumps the expire of our
  // dedicated server key. If we go off line, the key will expire and we will be
  // K.O. The value indicates the last "ping" that we got from the node server
  // so you can see when the last update was.
  //
  var alive = setInterval(function interval() {
    redis.setex(namespace +':'+ address, options.interval, Date.now());
  }, options.interval - options.latency);

  if ('function' === alive.unref) alive.unref();
};

/**
 * Scan the Redis database for dead servers and reap the dead servers.
 *
 * @param {Primus} primus Our current Primus instance.
 * @param {Object} options The options.
 * @api private
 */
metroplex.scan = function scan(primus, options) {
  var namespace = options.namespace
    , leverage = options.leverage
    , redis = options.redis;

  primus.servers(function find(err, servers) {
    servers.forEach(function expired(address) {
      redis.get(namespace +':'+ address, function get(err, stamp) {
        if (err || Date.now() - +stamp < options.interval) return;

        leverage.annihilate(address);
      });
    });
  });
};

/**
 * Register a new Primus server in the Redis database.
 *
 * @param {Primus} primus Our current Primus instance.
 * @param {Object} options The options.
 * @api private
 */
metroplex.register = function register(primus, options) {
  var namespace = options.namespace
    , leverage = options.leverage
    , redis = options.redis;

  leverage.annihilate(options.address, function (err) {
    if (err) return console.error('metroplex:register:error', err.stack);

    redis.multi()
      .setex(namespace +':'+ options.address, options.interval, Date.now())
      .sadd(namespace +':servers', options.address)
    .exec(function register(err) {
      if (err) return console.error('metroplex:register:error', err.stack);

      primus.emit('register', options.address);
    });
  });
};
<|endoftext|>