<commit_before>var acornToEsprima = require("acorn-to-esprima");
var assign         = require("lodash.assign");
var pick           = require("lodash.pick");
var Module         = require("module");
var path           = require("path");
var parse          = require("babylon").parse;
var t              = require("babel-types");
var tt             = require("babylon").tokTypes;
var traverse       = require("babel-traverse").default;

var estraverse;
var hasPatched = false;

function createModule(filename) {
  var mod = new Module(filename);
  mod.filename = filename;
  mod.paths = Module._nodeModulePaths(path.dirname(filename));
  return mod;
}

function monkeypatch() {
  if (hasPatched) return;
  hasPatched = true;

  var eslintLoc;
  try {
    // avoid importing a local copy of eslint, try to find a peer dependency
    eslintLoc = Module._resolveFilename("eslint", module.parent);
  } catch (err) {
    try {
      // avoids breaking in jest where module.parent is undefined
      eslintLoc = require.resolve("eslint");
    } catch (err) {
      throw new ReferenceError("couldn't resolve eslint");
    }
  }

  // get modules relative to what eslint will load
  var eslintMod = createModule(eslintLoc);
  var escopeLoc = Module._resolveFilename("escope", eslintMod);
  var escopeMod = createModule(escopeLoc);

  // npm 3: monkeypatch estraverse if it's in escope
  var estraverseRelative = escopeMod;
  try {
    var esrecurseLoc = Module._resolveFilename("esrecurse", eslintMod);
    estraverseRelative = createModule(esrecurseLoc);
  } catch (err) {}

  // monkeypatch estraverse
  estraverse = estraverseRelative.require("estraverse");
  assign(estraverse.VisitorKeys, t.VISITOR_KEYS);

  // monkeypatch estraverse-fb
  var estraverseFb = eslintMod.require("estraverse-fb");
  assign(estraverseFb.VisitorKeys, t.VISITOR_KEYS);

  // ESLint v1.9.0 uses estraverse directly to work around https://github.com/npm/npm/issues/9663
  var estraverseOfEslint = eslintMod.require("estraverse");
  if (estraverseOfEslint !== estraverseFb) {
    assign(estraverseOfEslint.VisitorKeys, t.VISITOR_KEYS);
  }

  // monkeypatch escope
  var escope  = require(escopeLoc);
  var analyze = escope.analyze;
  escope.analyze = function (ast, opts) {
    opts.ecmaVersion = 6;
    opts.sourceType = "module";
    var results = analyze.call(this, ast, opts);
    return results;
  };

  // monkeypatch escope/referencer
  var referencerLoc;
  try {
    referencerLoc = Module._resolveFilename("./referencer", escopeMod);
  } catch (err) {
    throw new ReferenceError("couldn't resolve escope/referencer");
  }
  var referencerMod = createModule(referencerLoc);
  var referencer = require(referencerLoc);

  // monkeypatch escope/pattern-visitor
  var patternVisitorLoc;
  var patternVisitorMod;
  var patternVisitor;
  try {
    patternVisitorLoc = Module._resolveFilename("./pattern-visitor", escopeMod);
    patternVisitorMod = createModule(patternVisitorLoc);
    patternVisitor = require(patternVisitorLoc);
  } catch (err) {
    // When eslint uses old escope, we cannot find pattern visitor.
    // Fallback to the old way.
  }

  // reference Definition
  var definitionLoc;
  try {
    definitionLoc = Module._resolveFilename("./definition", referencerMod);
  } catch (err) {
    throw new ReferenceError("couldn't resolve escope/definition");
  }
  var Definition = require(definitionLoc).Definition;

  // if there are decorators, then visit each
  function visitDecorators(node) {
    if (!node.decorators) {
      return;
    }
    for (var i = 0; i < node.decorators.length; i++) {
      if (node.decorators[i].expression) {
        this.visit(node.decorators[i]);
      }
    }
  }

  // iterate through part of t.VISITOR_KEYS
  var visitorKeysMap = pick(t.VISITOR_KEYS, function(k) {
    return t.FLIPPED_ALIAS_KEYS.Flow.concat([
      "ArrayPattern",
      "ClassDeclaration",
      "ClassExpression",
      "FunctionDeclaration",
      "FunctionExpression",
      "Identifier",
      "ObjectPattern",
      "RestElement"
    ]).indexOf(k) === -1;
  });

  var propertyTypes = {
    // loops
    callProperties: { type: "loop", values: ["value"] },
    indexers: { type: "loop", values: ["key", "value"] },
    properties: { type: "loop", values: ["value"] },
    types: { type: "loop" },
    params: { type: "loop" },
    // single property
    argument: { type: "single" },
    elementType: { type: "single" },
    qualification: { type: "single" },
    rest: { type: "single" },
    returnType: { type: "single" },
    // others
    typeAnnotation: { type: "typeAnnotation" },
    typeParameters: { type: "typeParameters" },
    id: { type: "id" }
  };

  function visitTypeAnnotation(node) {
    // get property to check (params, id, etc...)
    var visitorValues = visitorKeysMap[node.type];
    if (!visitorValues) {
      return;
    }

    // can have multiple properties
    for (var i = 0; i < visitorValues.length; i++) {
      var visitorValue = visitorValues[i];
      var propertyType = propertyTypes[visitorValue];
      var nodeProperty = node[visitorValue];
      // check if property or type is defined
      if (propertyType == null || nodeProperty == null) {
        continue;
      }
      if (propertyType.type === "loop") {
        for (var j = 0; j < nodeProperty.length; j++) {
          if (Array.isArray(propertyType.values)) {
            for (var k = 0; k < propertyType.values.length; k++) {
              checkIdentifierOrVisit.call(this, nodeProperty[j][propertyType.values[k]]);
            }
          } else {
            checkIdentifierOrVisit.call(this, nodeProperty[j]);
          }
        }
      } else if (propertyType.type === "single") {
        checkIdentifierOrVisit.call(this, nodeProperty);
      } else if (propertyType.type === "typeAnnotation") {
        visitTypeAnnotation.call(this, node.typeAnnotation);
      } else if (propertyType.type === "typeParameters") {
        for (var l = 0; l < node.typeParameters.params.length; l++) {
          checkIdentifierOrVisit.call(this, node.typeParameters.params[l]);
        }
      } else if (propertyType.type === "id") {
        if (node.id.type === "Identifier") {
          checkIdentifierOrVisit.call(this, node.id);
        } else {
          visitTypeAnnotation.call(this, node.id);
        }
      }
    }
  }

  function checkIdentifierOrVisit(node) {
    if (node.typeAnnotation) {
      visitTypeAnnotation.call(this, node.typeAnnotation);
    } else if (node.type === "Identifier") {
      this.visit(node);
    } else {
      visitTypeAnnotation.call(this, node);
    }
  }

  function nestTypeParamScope(manager, node) {
    var parentScope = manager.__currentScope;
    var scope = new escope.Scope(manager, "type-parameters", parentScope, node, false);
    manager.__nestScope(scope);
    for (var j = 0; j < node.typeParameters.params.length; j++) {
      var name = node.typeParameters.params[j];
      scope.__define(name, new Definition("TypeParameter", name, name));
    }
    scope.__define = function() {
      return parentScope.__define.apply(parentScope, arguments);
    };
    return scope;
  }

  // visit decorators that are in: ClassDeclaration / ClassExpression
  var visitClass = referencer.prototype.visitClass;
  referencer.prototype.visitClass = function(node) {
    visitDecorators.call(this, node);
    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    // visit flow type: ClassImplements
    if (node.implements) {
      for (var i = 0; i < node.implements.length; i++) {
        checkIdentifierOrVisit.call(this, node.implements[i]);
      }
    }
    if (node.superTypeParameters) {
      for (var k = 0; k < node.superTypeParameters.params.length; k++) {
        checkIdentifierOrVisit.call(this, node.superTypeParameters.params[k]);
      }
    }
    visitClass.call(this, node);
    if (typeParamScope) {
      this.close(node);
    }
  };
    // visit decorators that are in: Property / MethodDefinition
  var visitProperty = referencer.prototype.visitProperty;
  referencer.prototype.visitProperty = function(node) {
    if (node.value && node.value.type === "TypeCastExpression") {
      visitTypeAnnotation.call(this, node.value);
    }
    visitDecorators.call(this, node);
    visitProperty.call(this, node);
  };

  // visit flow type in FunctionDeclaration, FunctionExpression, ArrowFunctionExpression
  var visitFunction = referencer.prototype.visitFunction;
  referencer.prototype.visitFunction = function(node) {
    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    if (node.returnType) {
      checkIdentifierOrVisit.call(this, node.returnType);
    }
    // only visit if function parameters have types
    if (node.params) {
      for (var i = 0; i < node.params.length; i++) {
        var param = node.params[i];
        if (param.typeAnnotation) {
          checkIdentifierOrVisit.call(this, param);
        } else if (t.isAssignmentPattern(param)) {
          if (param.left.typeAnnotation) {
            checkIdentifierOrVisit.call(this, param.left);
          }
        }
      }
    }
    visitFunction.call(this, node);
    if (typeParamScope) {
      this.close(node);
    }
  };

  if (patternVisitor) {
    patternVisitor.prototype.SpreadProperty = function (node) {
      this.visit(node.argument);
    };
  }

  // visit flow type in VariableDeclaration
  var variableDeclaration = referencer.prototype.VariableDeclaration;
  referencer.prototype.VariableDeclaration = function(node) {
    if (node.declarations) {
      for (var i = 0; i < node.declarations.length; i++) {
        var id = node.declarations[i].id;
        var typeAnnotation = id.typeAnnotation;
        if (typeAnnotation) {
          checkIdentifierOrVisit.call(this, typeAnnotation);
        }
        if (id.type === "ObjectPattern") {
          // check if object destructuring has a spread
          var hasSpread = id.properties.filter(function(p) {
            return p._babelType === "SpreadProperty" || p._babelType === "RestProperty";
          });
          // visit properties if so
          if (hasSpread.length > 0) {
            for (var j = 0; j < id.properties.length; j++) {
              this.visit(id.properties[j]);
            }
          }
        }
      }
    }
    variableDeclaration.call(this, node);
  };

  function createScopeVariable (node, name) {
    this.currentScope().variableScope.__define(name,
      new Definition(
        "Variable",
        name,
        node,
        null,
        null,
        null
      )
    );
  }

  referencer.prototype.TypeAlias = function(node) {
    createScopeVariable.call(this, node, node.id);
    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    if (node.right) {
      visitTypeAnnotation.call(this, node.right);
    }
    if (typeParamScope) {
      this.close(node);
    }
  };

  referencer.prototype.DeclareModule =
  referencer.prototype.DeclareFunction =
  referencer.prototype.DeclareVariable =
  referencer.prototype.DeclareClass = function(node) {
    if (node.id) {
      createScopeVariable.call(this, node, node.id);
    }

    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    if (typeParamScope) {
      this.close(node);
    }
  };
}

exports.parse = function (code) {
  try {
    monkeypatch();
  } catch (err) {
    console.error(err.stack);
    process.exit(1);
  }

  return exports.parseNoPatch(code);
}

exports.parseNoPatch = function (code) {
  var opts = {
    sourceType: "module",
    strictMode: true,
    allowImportExportEverywhere: false, // consistent with espree
    allowReturnOutsideFunction: true,
    allowSuperOutsideMethod: true,
    plugins: [
        "flow",
        "jsx",
        "asyncFunctions",
        "asyncGenerators",
        "classConstructorCall",
        "classProperties",
        "decorators",
        "doExpressions",
        "exponentiationOperator",
        "exportExtensions",
        "functionBind",
        "objectRestSpread",
        "trailingFunctionCommas"
    ]
  };

  var ast;
  try {
    ast = parse(code, opts);
  } catch (err) {
    if (err instanceof SyntaxError) {
      err.lineNumber = err.loc.line;
      err.column = err.loc.column;

      // remove trailing "(LINE:COLUMN)" acorn message and add in esprima syntax error message start
      err.message = "Line " + err.lineNumber + ": " + err.message.replace(/ \((\d+):(\d+)\)$/, "");
    }

    throw err;
  }

  // remove EOF token, eslint doesn't use this for anything and it interferes with some rules
  // see https://github.com/babel/babel-eslint/issues/2 for more info
  // todo: find a more elegant way to do this
  ast.tokens.pop();

  // convert tokens
  ast.tokens = acornToEsprima.toTokens(ast.tokens, tt);

  // add comments
  acornToEsprima.convertComments(ast.comments);

  // transform esprima and acorn divergent nodes
  acornToEsprima.toAST(ast, traverse);

  // ast.program.tokens = ast.tokens;
  // ast.program.comments = ast.comments;
  // ast = ast.program;

  // remove File
  ast.type = 'Program';
  ast.sourceType = ast.program.sourceType;
  ast.directives = ast.program.directives;
  ast.body = ast.program.body;
  delete ast.program;
  delete ast._paths;

  acornToEsprima.attachComments(ast, ast.comments, ast.tokens);

  return ast;
}
<commit_msg>add functionSent to parser<commit_after>var acornToEsprima = require("acorn-to-esprima");
var assign         = require("lodash.assign");
var pick           = require("lodash.pick");
var Module         = require("module");
var path           = require("path");
var parse          = require("babylon").parse;
var t              = require("babel-types");
var tt             = require("babylon").tokTypes;
var traverse       = require("babel-traverse").default;

var estraverse;
var hasPatched = false;

function createModule(filename) {
  var mod = new Module(filename);
  mod.filename = filename;
  mod.paths = Module._nodeModulePaths(path.dirname(filename));
  return mod;
}

function monkeypatch() {
  if (hasPatched) return;
  hasPatched = true;

  var eslintLoc;
  try {
    // avoid importing a local copy of eslint, try to find a peer dependency
    eslintLoc = Module._resolveFilename("eslint", module.parent);
  } catch (err) {
    try {
      // avoids breaking in jest where module.parent is undefined
      eslintLoc = require.resolve("eslint");
    } catch (err) {
      throw new ReferenceError("couldn't resolve eslint");
    }
  }

  // get modules relative to what eslint will load
  var eslintMod = createModule(eslintLoc);
  var escopeLoc = Module._resolveFilename("escope", eslintMod);
  var escopeMod = createModule(escopeLoc);

  // npm 3: monkeypatch estraverse if it's in escope
  var estraverseRelative = escopeMod;
  try {
    var esrecurseLoc = Module._resolveFilename("esrecurse", eslintMod);
    estraverseRelative = createModule(esrecurseLoc);
  } catch (err) {}

  // monkeypatch estraverse
  estraverse = estraverseRelative.require("estraverse");
  assign(estraverse.VisitorKeys, t.VISITOR_KEYS);

  // monkeypatch estraverse-fb
  var estraverseFb = eslintMod.require("estraverse-fb");
  assign(estraverseFb.VisitorKeys, t.VISITOR_KEYS);

  // ESLint v1.9.0 uses estraverse directly to work around https://github.com/npm/npm/issues/9663
  var estraverseOfEslint = eslintMod.require("estraverse");
  if (estraverseOfEslint !== estraverseFb) {
    assign(estraverseOfEslint.VisitorKeys, t.VISITOR_KEYS);
  }

  // monkeypatch escope
  var escope  = require(escopeLoc);
  var analyze = escope.analyze;
  escope.analyze = function (ast, opts) {
    opts.ecmaVersion = 6;
    opts.sourceType = "module";
    var results = analyze.call(this, ast, opts);
    return results;
  };

  // monkeypatch escope/referencer
  var referencerLoc;
  try {
    referencerLoc = Module._resolveFilename("./referencer", escopeMod);
  } catch (err) {
    throw new ReferenceError("couldn't resolve escope/referencer");
  }
  var referencerMod = createModule(referencerLoc);
  var referencer = require(referencerLoc);

  // monkeypatch escope/pattern-visitor
  var patternVisitorLoc;
  var patternVisitorMod;
  var patternVisitor;
  try {
    patternVisitorLoc = Module._resolveFilename("./pattern-visitor", escopeMod);
    patternVisitorMod = createModule(patternVisitorLoc);
    patternVisitor = require(patternVisitorLoc);
  } catch (err) {
    // When eslint uses old escope, we cannot find pattern visitor.
    // Fallback to the old way.
  }

  // reference Definition
  var definitionLoc;
  try {
    definitionLoc = Module._resolveFilename("./definition", referencerMod);
  } catch (err) {
    throw new ReferenceError("couldn't resolve escope/definition");
  }
  var Definition = require(definitionLoc).Definition;

  // if there are decorators, then visit each
  function visitDecorators(node) {
    if (!node.decorators) {
      return;
    }
    for (var i = 0; i < node.decorators.length; i++) {
      if (node.decorators[i].expression) {
        this.visit(node.decorators[i]);
      }
    }
  }

  // iterate through part of t.VISITOR_KEYS
  var visitorKeysMap = pick(t.VISITOR_KEYS, function(k) {
    return t.FLIPPED_ALIAS_KEYS.Flow.concat([
      "ArrayPattern",
      "ClassDeclaration",
      "ClassExpression",
      "FunctionDeclaration",
      "FunctionExpression",
      "Identifier",
      "ObjectPattern",
      "RestElement"
    ]).indexOf(k) === -1;
  });

  var propertyTypes = {
    // loops
    callProperties: { type: "loop", values: ["value"] },
    indexers: { type: "loop", values: ["key", "value"] },
    properties: { type: "loop", values: ["value"] },
    types: { type: "loop" },
    params: { type: "loop" },
    // single property
    argument: { type: "single" },
    elementType: { type: "single" },
    qualification: { type: "single" },
    rest: { type: "single" },
    returnType: { type: "single" },
    // others
    typeAnnotation: { type: "typeAnnotation" },
    typeParameters: { type: "typeParameters" },
    id: { type: "id" }
  };

  function visitTypeAnnotation(node) {
    // get property to check (params, id, etc...)
    var visitorValues = visitorKeysMap[node.type];
    if (!visitorValues) {
      return;
    }

    // can have multiple properties
    for (var i = 0; i < visitorValues.length; i++) {
      var visitorValue = visitorValues[i];
      var propertyType = propertyTypes[visitorValue];
      var nodeProperty = node[visitorValue];
      // check if property or type is defined
      if (propertyType == null || nodeProperty == null) {
        continue;
      }
      if (propertyType.type === "loop") {
        for (var j = 0; j < nodeProperty.length; j++) {
          if (Array.isArray(propertyType.values)) {
            for (var k = 0; k < propertyType.values.length; k++) {
              checkIdentifierOrVisit.call(this, nodeProperty[j][propertyType.values[k]]);
            }
          } else {
            checkIdentifierOrVisit.call(this, nodeProperty[j]);
          }
        }
      } else if (propertyType.type === "single") {
        checkIdentifierOrVisit.call(this, nodeProperty);
      } else if (propertyType.type === "typeAnnotation") {
        visitTypeAnnotation.call(this, node.typeAnnotation);
      } else if (propertyType.type === "typeParameters") {
        for (var l = 0; l < node.typeParameters.params.length; l++) {
          checkIdentifierOrVisit.call(this, node.typeParameters.params[l]);
        }
      } else if (propertyType.type === "id") {
        if (node.id.type === "Identifier") {
          checkIdentifierOrVisit.call(this, node.id);
        } else {
          visitTypeAnnotation.call(this, node.id);
        }
      }
    }
  }

  function checkIdentifierOrVisit(node) {
    if (node.typeAnnotation) {
      visitTypeAnnotation.call(this, node.typeAnnotation);
    } else if (node.type === "Identifier") {
      this.visit(node);
    } else {
      visitTypeAnnotation.call(this, node);
    }
  }

  function nestTypeParamScope(manager, node) {
    var parentScope = manager.__currentScope;
    var scope = new escope.Scope(manager, "type-parameters", parentScope, node, false);
    manager.__nestScope(scope);
    for (var j = 0; j < node.typeParameters.params.length; j++) {
      var name = node.typeParameters.params[j];
      scope.__define(name, new Definition("TypeParameter", name, name));
    }
    scope.__define = function() {
      return parentScope.__define.apply(parentScope, arguments);
    };
    return scope;
  }

  // visit decorators that are in: ClassDeclaration / ClassExpression
  var visitClass = referencer.prototype.visitClass;
  referencer.prototype.visitClass = function(node) {
    visitDecorators.call(this, node);
    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    // visit flow type: ClassImplements
    if (node.implements) {
      for (var i = 0; i < node.implements.length; i++) {
        checkIdentifierOrVisit.call(this, node.implements[i]);
      }
    }
    if (node.superTypeParameters) {
      for (var k = 0; k < node.superTypeParameters.params.length; k++) {
        checkIdentifierOrVisit.call(this, node.superTypeParameters.params[k]);
      }
    }
    visitClass.call(this, node);
    if (typeParamScope) {
      this.close(node);
    }
  };
    // visit decorators that are in: Property / MethodDefinition
  var visitProperty = referencer.prototype.visitProperty;
  referencer.prototype.visitProperty = function(node) {
    if (node.value && node.value.type === "TypeCastExpression") {
      visitTypeAnnotation.call(this, node.value);
    }
    visitDecorators.call(this, node);
    visitProperty.call(this, node);
  };

  // visit flow type in FunctionDeclaration, FunctionExpression, ArrowFunctionExpression
  var visitFunction = referencer.prototype.visitFunction;
  referencer.prototype.visitFunction = function(node) {
    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    if (node.returnType) {
      checkIdentifierOrVisit.call(this, node.returnType);
    }
    // only visit if function parameters have types
    if (node.params) {
      for (var i = 0; i < node.params.length; i++) {
        var param = node.params[i];
        if (param.typeAnnotation) {
          checkIdentifierOrVisit.call(this, param);
        } else if (t.isAssignmentPattern(param)) {
          if (param.left.typeAnnotation) {
            checkIdentifierOrVisit.call(this, param.left);
          }
        }
      }
    }
    visitFunction.call(this, node);
    if (typeParamScope) {
      this.close(node);
    }
  };

  if (patternVisitor) {
    patternVisitor.prototype.SpreadProperty = function (node) {
      this.visit(node.argument);
    };
  }

  // visit flow type in VariableDeclaration
  var variableDeclaration = referencer.prototype.VariableDeclaration;
  referencer.prototype.VariableDeclaration = function(node) {
    if (node.declarations) {
      for (var i = 0; i < node.declarations.length; i++) {
        var id = node.declarations[i].id;
        var typeAnnotation = id.typeAnnotation;
        if (typeAnnotation) {
          checkIdentifierOrVisit.call(this, typeAnnotation);
        }
        if (id.type === "ObjectPattern") {
          // check if object destructuring has a spread
          var hasSpread = id.properties.filter(function(p) {
            return p._babelType === "SpreadProperty" || p._babelType === "RestProperty";
          });
          // visit properties if so
          if (hasSpread.length > 0) {
            for (var j = 0; j < id.properties.length; j++) {
              this.visit(id.properties[j]);
            }
          }
        }
      }
    }
    variableDeclaration.call(this, node);
  };

  function createScopeVariable (node, name) {
    this.currentScope().variableScope.__define(name,
      new Definition(
        "Variable",
        name,
        node,
        null,
        null,
        null
      )
    );
  }

  referencer.prototype.TypeAlias = function(node) {
    createScopeVariable.call(this, node, node.id);
    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    if (node.right) {
      visitTypeAnnotation.call(this, node.right);
    }
    if (typeParamScope) {
      this.close(node);
    }
  };

  referencer.prototype.DeclareModule =
  referencer.prototype.DeclareFunction =
  referencer.prototype.DeclareVariable =
  referencer.prototype.DeclareClass = function(node) {
    if (node.id) {
      createScopeVariable.call(this, node, node.id);
    }

    var typeParamScope;
    if (node.typeParameters) {
      typeParamScope = nestTypeParamScope(this.scopeManager, node);
    }
    if (typeParamScope) {
      this.close(node);
    }
  };
}

exports.parse = function (code) {
  try {
    monkeypatch();
  } catch (err) {
    console.error(err.stack);
    process.exit(1);
  }

  return exports.parseNoPatch(code);
}

exports.parseNoPatch = function (code) {
  var opts = {
    sourceType: "module",
    strictMode: true,
    allowImportExportEverywhere: false, // consistent with espree
    allowReturnOutsideFunction: true,
    allowSuperOutsideMethod: true,
    plugins: [
        "flow",
        "jsx",
        "asyncFunctions",
        "asyncGenerators",
        "classConstructorCall",
        "classProperties",
        "decorators",
        "doExpressions",
        "exponentiationOperator",
        "exportExtensions",
        "functionBind",
        "functionSent",
        "objectRestSpread",
        "trailingFunctionCommas"
    ]
  };

  var ast;
  try {
    ast = parse(code, opts);
  } catch (err) {
    if (err instanceof SyntaxError) {
      err.lineNumber = err.loc.line;
      err.column = err.loc.column;

      // remove trailing "(LINE:COLUMN)" acorn message and add in esprima syntax error message start
      err.message = "Line " + err.lineNumber + ": " + err.message.replace(/ \((\d+):(\d+)\)$/, "");
    }

    throw err;
  }

  // remove EOF token, eslint doesn't use this for anything and it interferes with some rules
  // see https://github.com/babel/babel-eslint/issues/2 for more info
  // todo: find a more elegant way to do this
  ast.tokens.pop();

  // convert tokens
  ast.tokens = acornToEsprima.toTokens(ast.tokens, tt);

  // add comments
  acornToEsprima.convertComments(ast.comments);

  // transform esprima and acorn divergent nodes
  acornToEsprima.toAST(ast, traverse);

  // ast.program.tokens = ast.tokens;
  // ast.program.comments = ast.comments;
  // ast = ast.program;

  // remove File
  ast.type = 'Program';
  ast.sourceType = ast.program.sourceType;
  ast.directives = ast.program.directives;
  ast.body = ast.program.body;
  delete ast.program;
  delete ast._paths;

  acornToEsprima.attachComments(ast, ast.comments, ast.tokens);

  return ast;
}
<|endoftext|>


<commit_before>var fs = require( 'fs' );
var path = require( 'path' );
var shasum = require( 'shasum' );
var pathMapper = require( 'path-mapper' );
var _ = require( 'underscore' );

var kMetaDataFileName = 'metaData.json';
var kOldPackageMapName = 'package_map.json';

var kMetaDataFormatVersion = 2;

module.exports = CarteroNodeHook;

function CarteroNodeHook( outputDirPath, options ) {
	if( ! ( this instanceof CarteroNodeHook ) ) return new CarteroNodeHook( outputDirPath, options );

	if( outputDirPath === undefined )
		throw new Error( 'outputDirPath is required' );

	options = _.defaults( {}, options, {
		appRootDir : undefined,
		outputDirUrl : '/',
		cache : true
	} );

	this.appRootDir = options.appRootDir;
	this.outputDirPath = path.resolve( path.dirname( require.main.filename ), outputDirPath );
	this.outputDirUrl = options.outputDirUrl;
	this.cache = options.cache;

	this.metaData = this.getMetaData();
	this.parcelAssetsCache = {};
}

CarteroNodeHook.prototype.getTagsForEntryPoint = function( entryPointPath, cb ) {
	var _this = this;

	this.getAssetsForEntryPoint( entryPointPath, function( err, assetUrls ) {
		if( err ) return cb( err );

		var scriptTags = assetUrls.script.map( function( assetPath ) {
			return '<script type="text/javascript" src="' + path.join( _this.outputDirUrl, assetPath ) + '"></script>';
		} ).join( '\n' );

		var styleTags = assetUrls.style.map( function( assetPath ) {
			return '<link rel="stylesheet" href="' + path.join( _this.outputDirUrl, assetPath ) + '"></link>';
		} ).join( '\n' );

		cb( null, scriptTags, styleTags );
	} );
};

CarteroNodeHook.prototype.getAssetsForEntryPoint = function( entryPointPath, cb ) {
	var _this = this;

	if( ! _this.cache ) this.metaData = this.getMetaData();

	var parcelId = this.metaData.entryPointMap[ _this.getPackageMapKeyFromPath( entryPointPath ) ];
	if( ! parcelId ) return cb( new Error( 'Could not find assets for entry point with absolute path "' + entryPointPath + '"' ) );

	if( _this.cache && this.parcelAssetsCache[ parcelId ] )
		cb( null, this.parcelAssetsCache[ parcelId ] );
	else {
		fs.readFile( path.join( this.outputDirPath, parcelId, 'assets.json' ), function( err, contents ) {
			if( err ) return cb( err );

			var parcelAssets = JSON.parse( contents );

			if( _this.cache )
				_this.parcelAssetsCache[ parcelId ] = parcelAssets;

			cb( null, parcelAssets );
		} );
	}
};

CarteroNodeHook.prototype.getAssetUrl = function( assetSrcAbsPath ) {
	var _this = this;

	var url = pathMapper( assetSrcAbsPath, function( srcDir ) {
		srcDir = _this.getPackageMapKeyFromPath( srcDir );
		return _this.metaData.packageMap[ srcDir ] ? '/' + _this.metaData.packageMap[ srcDir ] : null; // return val of dstDir needs to be absolute path
	} );

	if( url === assetSrcAbsPath )
		throw new Error( 'Could not find url for that asset.' );

	if( _this.outputDirUrl )
		url = path.join( _this.outputDirUrl, url );

	return url;
};

CarteroNodeHook.prototype.getPackageMapKeyFromPath = function( packagePath ) {
	if( this.appRootDir ) return './' + path.relative( this.appRootDir, packagePath );
	else return packagePath;
};

CarteroNodeHook.prototype.getMetaData = function() {
	var metaData;

	try {
		var data = fs.readFileSync( path.join( this.outputDirPath, kMetaDataFileName ), 'utf8' );
		metaData = JSON.parse( data );
	} catch( err ) {
		if( fs.existsSync( path.join( this.outputDirPath, kOldPackageMapName ) ) )
			throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook.\n' + err );

		throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. (Have you run cartero yet?)\n' + err );
	}

	if( metaData.formatVersion < kMetaDataFormatVersion ) {
		throw new Error( 'It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook. Please update your version of cartero to the most recent release.' );
	}

	return metaData;
}
<commit_msg>Finish updating getAssetUrl and getAssetsForEntryPoint<commit_after>var fs = require( 'fs' );
var path = require( 'path' );
var shasum = require( 'shasum' );
var pathMapper = require( 'path-mapper' );
var _ = require( 'underscore' );

var kMetaDataFileName = 'metaData.json';
var kOldPackageMapName = 'package_map.json';

var kMetaDataFormatVersion = 2;

module.exports = CarteroNodeHook;

function CarteroNodeHook( outputDirPath, options ) {
	if( ! ( this instanceof CarteroNodeHook ) ) return new CarteroNodeHook( outputDirPath, options );

	if( outputDirPath === undefined )
		throw new Error( 'outputDirPath is required' );

	options = _.defaults( {}, options, {
		appRootDir : undefined,
		outputDirUrl : '/',
		cache : true
	} );

	this.appRootDir = options.appRootDir;
	this.outputDirPath = path.resolve( path.dirname( require.main.filename ), outputDirPath );
	this.outputDirUrl = options.outputDirUrl;
	this.cache = options.cache;

	this.metaData = this.getMetaData();
	this.parcelAssetsCache = {};
}

CarteroNodeHook.prototype.getTagsForEntryPoint = function( entryPointPath, cb ) {
	var _this = this;

	this.getAssetsForEntryPoint( entryPointPath, function( err, assetUrls ) {
		if( err ) return cb( err );

		var scriptTags = assetUrls.script.map( function( assetPath ) {
			return '<script type="text/javascript" src="' + path.join( _this.outputDirUrl, assetPath ) + '"></script>';
		} ).join( '\n' );

		var styleTags = assetUrls.style.map( function( assetPath ) {
			return '<link rel="stylesheet" href="' + path.join( _this.outputDirUrl, assetPath ) + '"></link>';
		} ).join( '\n' );

		cb( null, scriptTags, styleTags );
	} );
};

CarteroNodeHook.prototype.getAssetsForEntryPoint = function( entryPointDir, cb ) {
	var _this = this;

	if( ! _this.cache ) this.metaData = this.getMetaData();

  //TODO fix this.
  //var parcelId = this.metaData.entryPointMap[ _this.getPackageMapKeyFromPath( entryPointPath ) ] || this.metaData.packageMap[ _this.getPackageMapKeyFromPath( entryPointDir ) ]; //fallback to packageMap if not in entryPointMap, there are some duped info TODO
  var parcelId = this.metaData.packageMap[ _this.getPackageMapKeyFromPath( entryPointDir ) ]; //why not??
	if( ! parcelId ) return cb( new Error( 'Could not find assets for entry point with absolute path "' + entryPointPath + '"' ) );

	if( _this.cache && this.parcelAssetsCache[ parcelId ] )
		cb( null, this.parcelAssetsCache[ parcelId ] );
	else {
		fs.readFile( path.join( this.outputDirPath, parcelId, 'assets.json' ), function( err, contents ) {
			if( err ) return cb( err );

			var parcelAssets = JSON.parse( contents );

			if( _this.cache )
				_this.parcelAssetsCache[ parcelId ] = parcelAssets;

			cb( null, parcelAssets );
		} );
	}
};

CarteroNodeHook.prototype.getAssetUrl = function( assetSrcPath ) {
	var _this = this;

  var assetPath = _this.metaData.assetMap && _this.metaData.assetMap[assetSrcPath];
  if (!assetPath) throw new Error('asset not found in metaData.assetMap');
  //var assetDir = path.dirname(assetSrcAbsPath); //not right--still need to find fingerprint dir and replace first dir with it

  //var assetDir = pathMapper( assetSrcAbsPath, function( srcDir ) {
    //debugger;

    ////srcDir = _this.getPackageMapKeyFromPath( srcDir );
    ////return _this.metaData.assetMap[ srcDir ] ? '/' + _this.metaData.assetMap[ srcDir ] : null; // return val of dstDir needs to be absolute path
    //return _this.metaData.packageMap[srcDir]; // return val of dstDir needs to be absolute path
  //} );

  //if( assetDir === assetSrcAbsPath ) throw new Error( 'Could not find url for that asset.' );

  //var assetUrl = path.join('/', assetDir, assetFileName);

  if( _this.outputDirUrl ) assetPath = path.join( _this.outputDirUrl, assetPath );

	return assetPath;
};

CarteroNodeHook.prototype.getPackageMapKeyFromPath = function( packagePath ) {
	if( this.appRootDir ) return './' + path.relative( this.appRootDir, packagePath );
	else return packagePath;
};

CarteroNodeHook.prototype.getMetaData = function() {
	var metaData;

	try {
		var data = fs.readFileSync( path.join( this.outputDirPath, kMetaDataFileName ), 'utf8' );
		metaData = JSON.parse( data );
	} catch( err ) {
		if( fs.existsSync( path.join( this.outputDirPath, kOldPackageMapName ) ) )
			throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook.\n' + err );

		throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. (Have you run cartero yet?)\n' + err );
	}

	if( metaData.formatVersion < kMetaDataFormatVersion ) {
		throw new Error( 'It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook. Please update your version of cartero to the most recent release.' );
	}

	return metaData;
};
<|endoftext|>


<commit_before>'use strict';

// Node.js built-ins

const childProcess = require('child_process');

// foreign modules

const parseArgs = require('minimist');

// this module

const args = process.argv.slice(2);
const cmd = process.argv[1];

const parsedArgs = parseArgs(args);

function showHelp () {
  console.log(`usage:\n  ${cmd} <command> ...\n`);
  console.log(`example:\n  ${cmd} list-commands`);
}

if (!parsedArgs._.length) {
  showHelp();
  return;
}

const command = parsedArgs._[0];

if (command === 'list-commands') {
  require('./commands/list-commands');
  return;
}

childProcess.spawn(`blinkmobile-${command}`, process.argv.slice(3), {
  cwd: process.cwd(),
  detached: false,
  env: process.env,
  stdio: 'inherit'
})
  .on('error', (err) => {
    if (err && err.code === 'ENOENT') {
      console.error(`Error: "${command}" is not an available ${cmd} command\n`);
      showHelp();
      process.exit(1);
    }
  });
<commit_msg>just show the basename for the executable<commit_after>'use strict';

// Node.js built-ins

const childProcess = require('child_process');
const path = require('path');

// foreign modules

const parseArgs = require('minimist');

// this module

const args = process.argv.slice(2);
const cmd = path.basename(process.argv[1]);

const parsedArgs = parseArgs(args);

function showHelp () {
  console.log(`usage:\n  ${cmd} <command> ...\n`);
  console.log(`example:\n  ${cmd} list-commands`);
}

if (!parsedArgs._.length) {
  showHelp();
  return;
}

const command = parsedArgs._[0];

if (command === 'list-commands') {
  require('./commands/list-commands');
  return;
}

childProcess.spawn(`blinkmobile-${command}`, process.argv.slice(3), {
  cwd: process.cwd(),
  detached: false,
  env: process.env,
  stdio: 'inherit'
})
  .on('error', (err) => {
    if (err && err.code === 'ENOENT') {
      console.error(`Error: "${command}" is not an available ${cmd} command\n`);
      showHelp();
      process.exit(1);
    }
  });
<|endoftext|>


<commit_before>'use strict'

const util = require('util')
const assert = require('assert')
const Duplex = require('stream').Duplex

const ChangesResponse = module.exports = function(options) {
  const self = this

  Duplex.call(self, { objectMode: true })

  self._type = options.type || 'normal'
  assert(
    ['continuous', 'normal'].indexOf(self._type) !== -1,
    'only normal and continuous feed type are supported'
  )

  // CouchDB doesn't throw when passed a heartbeat with normal feed type, so
  // we don't either.
  self._heartbeat = options.heartbeat || 60000
  self._lastSeq = options.since || 0
  self._isFirstSeq = true

  if (self._type === 'normal') self.push('{"results":[\n');

  if (self._heartbeat) {
    self._heartbeatInterval = setInterval(self._writeHeartbeat.bind(self), self._heartbeat)
    self.once('finish', function() {
      clearInterval(self._heartbeatInterval)
    })
  }

  if (this._type === 'normal') this.end = ChangesResponse.prototype._normalEnd
}
util.inherits(ChangesResponse, Duplex)

ChangesResponse.prototype._write = function(chunk, encoding, cb) {
  var stringified = JSON.stringify(chunk)

  this._lastSeq = chunk.seq

  if (this._type === 'continuous')
    this.push(stringified + '\n')
  else if (this._type === 'normal') {
    if (!this._isFirstSeq) this.push(',\n')
    this.push(stringified)
  }

  this._isFirstSeq = false

  cb()
}

ChangesResponse.prototype._read = function () {}

ChangesResponse.prototype._writeHeartbeat = function() {
  this.push('\n')
}

ChangesResponse.prototype._normalEnd = function (chunk, encoding, cb) {
  var self = this

  self._write(chunk, encoding, () => {
    self.push('\n],\n"last_seq":' + self._lastSeq + '}')
    Duplex.prototype.end.call(self, cb)
  })
}
<commit_msg>Expose supported feed types<commit_after>'use strict'

const util = require('util')
const assert = require('assert')
const Duplex = require('stream').Duplex

const ChangesResponse = module.exports = function(options) {
  const self = this

  Duplex.call(self, { objectMode: true })

  self._type = options.type || 'normal'
  assert(
    ChangesResponse.SUPPORTED_TYPES.indexOf(self._type) !== -1,
    'only normal and continuous feed type are supported'
  )

  // CouchDB doesn't throw when passed a heartbeat with normal feed type, so
  // we don't either.
  self._heartbeat = options.heartbeat || 60000
  self._lastSeq = options.since || 0
  self._isFirstSeq = true

  if (self._type === 'normal') self.push('{"results":[\n');

  if (self._heartbeat) {
    self._heartbeatInterval = setInterval(self._writeHeartbeat.bind(self), self._heartbeat)
    self.once('finish', function() {
      clearInterval(self._heartbeatInterval)
    })
  }

  if (this._type === 'normal') this.end = ChangesResponse.prototype._normalEnd
}
util.inherits(ChangesResponse, Duplex)

ChangesResponse.SUPPORTED_TYPES = ['continuous', 'normal']

ChangesResponse.prototype._write = function(chunk, encoding, cb) {
  var stringified = JSON.stringify(chunk)

  this._lastSeq = chunk.seq

  if (this._type === 'continuous')
    this.push(stringified + '\n')
  else if (this._type === 'normal') {
    if (!this._isFirstSeq) this.push(',\n')
    this.push(stringified)
  }

  this._isFirstSeq = false

  cb()
}

ChangesResponse.prototype._read = function () {}

ChangesResponse.prototype._writeHeartbeat = function() {
  this.push('\n')
}

ChangesResponse.prototype._normalEnd = function (chunk, encoding, cb) {
  var self = this

  self._write(chunk, encoding, () => {
    self.push('\n],\n"last_seq":' + self._lastSeq + '}')
    Duplex.prototype.end.call(self, cb)
  })
}
<|endoftext|>


<commit_before>'use strict';

const BbPromise = require('bluebird');

class PrunePlugin {
  constructor(serverless, options) {
    this.serverless = serverless;
    this.options = options || {};
    this.provider = this.serverless.getProvider('aws');

    this.commands = {
      prune: {
        usage: 'Cleans up previously deployed function versions',
        lifecycleEvents: ['prune'],
        options: {
          number: {
            usage: 'Specify the number of previous versions to keep',
            shortcut: 'n',
            required: true
          },
          function: {
            usage: 'Only prune the specified function")',
            shortcut: 'f',
            required: false
          }
        }
      },
    };

    this.hooks = {
      'prune:prune': this.prune.bind(this)
    };
  }

  prune() {

    const selectedFunctions = this.options.function ? [this.options.function] : this.serverless.service.getAllFunctions();
    const functionNames = selectedFunctions.map(key => this.serverless.service.getFunction(key).name);

    BbPromise.map(functionNames, functionName => {

      const params = {
        FunctionName: functionName,
        MaxItems: 200
      };

      return BbPromise.all([
        BbPromise.resolve(functionName),
        this.provider.request('Lambda', 'listVersionsByFunction', params),
        this.provider.request('Lambda', 'listAliases', params)
      ]);

    }, {concurrency: 1}).each(([name, versions, aliases]) => {

      const deletionVersions = this.selectPruneVersionsForFunction(name, versions.Versions, aliases.Aliases);
      return this.deleteVersionsForFunction(name, deletionVersions);

    }).then(() => {
      this.serverless.cli.log('Cleanup complete');
    });
  }

  deleteVersionsForFunction(functionName, versions) {

    return BbPromise.each(versions, version => {

      this.serverless.cli.log(`Deleting ${functionName} v${version}...`);

      const params = {
        FunctionName: functionName,
        Qualifier: version
      };

      return this.provider.request('Lambda', 'deleteFunction', params);
    });
  }

  selectPruneVersionsForFunction(functionName, versions, aliases) {

    const aliasedVersion = aliases.map(a => a.FunctionVersion);

    const deletionCandidates = versions
      .map(f => f.Version)
      .filter(v => v !== '$LATEST')
      .filter(v => !aliasedVersion.includes(v))
      .sort((a, b) => {
        return parseInt(b) - parseInt(a);
      })
      .slice(this.options.number);

    const puralized = (count, single, plural) => `${count} ${count != 1 ? plural : single}`;
    this.serverless.cli.log(`${functionName} has ${puralized(versions.length - 1, 'version', 'versions')} published and ${puralized(aliases.length, 'alias', 'aliases')}, ${puralized(deletionCandidates.length, 'version', 'versions')} selected for deletion`);

    return deletionCandidates;
  }

}

module.exports = PrunePlugin;<commit_msg>Silently skip functions not deployed; previously produced an error<commit_after>'use strict';

const BbPromise = require('bluebird');

class PrunePlugin {
  constructor(serverless, options) {
    this.serverless = serverless;
    this.options = options || {};
    this.provider = this.serverless.getProvider('aws');

    this.commands = {
      prune: {
        usage: 'Cleans up previously deployed function versions',
        lifecycleEvents: ['prune'],
        options: {
          number: {
            usage: 'Specify the number of previous versions to keep',
            shortcut: 'n',
            required: true
          },
          function: {
            usage: 'Only prune the specified function")',
            shortcut: 'f',
            required: false
          }
        }
      },
    };

    this.hooks = {
      'prune:prune': this.prune.bind(this)
    };
  }

  prune() {

    const selectedFunctions = this.options.function ? [this.options.function] : this.serverless.service.getAllFunctions();
    const functionNames = selectedFunctions.map(key => this.serverless.service.getFunction(key).name);

    BbPromise.mapSeries(functionNames, functionName => {

      const params = {
        FunctionName: functionName,
        MaxItems: 200
      };

      return BbPromise.all([
        BbPromise.resolve(functionName),
        this.provider.request('Lambda', 'listVersionsByFunction', params),
        this.provider.request('Lambda', 'listAliases', params)
      ]).catch(e => {
        //ignore if function not deployed
        if (e.statusCode === 404) return [];
        else throw e;
      });

    }).each(([name, versions, aliases]) => {

      if (!versions && !aliases)
        return BbPromise.resolve();

      const deletionVersions = this.selectPruneVersionsForFunction(name, versions.Versions, aliases.Aliases);
      return this.deleteVersionsForFunction(name, deletionVersions);

    }).then(() => {
      this.serverless.cli.log('Pruning complete');
    });
  }

  deleteVersionsForFunction(functionName, versions) {

    return BbPromise.each(versions, version => {

      this.serverless.cli.log(`Deleting ${functionName} v${version}...`);

      const params = {
        FunctionName: functionName,
        Qualifier: version
      };

      return this.provider.request('Lambda', 'deleteFunction', params);
    });
  }

  selectPruneVersionsForFunction(functionName, versions, aliases) {

    const aliasedVersion = aliases.map(a => a.FunctionVersion);

    const deletionCandidates = versions
      .map(f => f.Version)
      .filter(v => v !== '$LATEST')
      .filter(v => !aliasedVersion.includes(v))
      .sort((a, b) => {
        return parseInt(b) - parseInt(a);
      })
      .slice(this.options.number);

    const puralized = (count, single, plural) => `${count} ${count != 1 ? plural : single}`;
    this.serverless.cli.log(`${functionName} has ${puralized(versions.length - 1, 'version', 'versions')} published and ${puralized(aliases.length, 'alias', 'aliases')}, ${puralized(deletionCandidates.length, 'version', 'versions')} selected for deletion`);

    return deletionCandidates;
  }

}

module.exports = PrunePlugin;<|endoftext|>


<commit_before>'use strict';

var raml2obj = require('raml2obj');
var pjson = require('./package.json');
var Q = require('q');
var path = require('path');

/**
 * Render the source RAML object using the config's processOutput function
 *
 * The config object should contain at least the following property:
 * processRamlObj: function that takes the raw RAML object and returns a promise with the rendered HTML
 *
 * @param {(String|Object)} source - The source RAML file. Can be a filename, url, contents of the RAML file,
 * or an already-parsed RAML object.
 * @param {Object} config
 * @param {Function} config.processRamlObj
 * @returns a promise
 */
function render(source, config) {
  config = config || {};
  config.raml2HtmlVersion = pjson.version;

  return raml2obj.parse(source).then(function(ramlObj) {
    ramlObj.config = config;

    if (config.processRamlObj) {
      return config.processRamlObj(ramlObj).then(function(html) {
        if (config.postProcessHtml) {
          return config.postProcessHtml(html);
        }

        return html;
      });
    }

    return ramlObj;
  });
}

/**
 * @param {String} [mainTemplate] - The filename of the main template, leave empty to use default templates
 * @param {String} [templatesPath] - Optional, by default it uses the current working directory
 * @returns {{processRamlObj: Function, postProcessHtml: Function}}
 */
function getDefaultConfig(mainTemplate, templatesPath) {
  if (!mainTemplate) {
    // When using the default templates, using raml2html's lib folder as the templates path
    mainTemplate = 'template.nunjucks';
    templatesPath = path.join(__dirname, 'lib');
  }

  return {
    processRamlObj: function(ramlObj) {
      var nunjucks = require('nunjucks');
      var markdown = require('nunjucks-markdown');
      var marked = require('marked');
      var renderer = new marked.Renderer();
      renderer.table = function(thead, tbody) {
        // Render Bootstrap style tables
        return '

' + thead + '

' + tbody + '

';
      };

      // Setup the Nunjucks environment with the markdown parser
      var env = nunjucks.configure(templatesPath, {watch: false});
      markdown.register(env, marked);

      // Render the main template using the raml object and fix the double quotes
      var html = nunjucks.render(mainTemplate, ramlObj);
      html = html.replace(/"/g, '"');

      // Return the promise with the html
      return Q.fcall(function() {
        return html;
      });
    },

    postProcessHtml: function(html) {
      // Minimize the generated html and return the promise with the result
      var Minimize = require('minimize');
      var minimize = new Minimize({quotes: true});

      var deferred = Q.defer();

      minimize.parse(html, function(error, result) {
        if (error) {
          deferred.reject(new Error(error));
        } else {
          deferred.resolve(result);
        }
      });

      return deferred.promise;
    }
  };
}

module.exports = {
  getDefaultConfig: getDefaultConfig,
  render: render
};
<commit_msg>Added a warning for if you're trying to run index.js on the command line.<commit_after>'use strict';

var raml2obj = require('raml2obj');
var pjson = require('./package.json');
var Q = require('q');
var path = require('path');

exports = module.exports = {
  getDefaultConfig: getDefaultConfig,
  render: render
};

/**
 * Render the source RAML object using the config's processOutput function
 *
 * The config object should contain at least the following property:
 * processRamlObj: function that takes the raw RAML object and returns a promise with the rendered HTML
 *
 * @param {(String|Object)} source - The source RAML file. Can be a filename, url, contents of the RAML file,
 * or an already-parsed RAML object.
 * @param {Object} config
 * @param {Function} config.processRamlObj
 * @returns a promise
 */
function render(source, config) {
  config = config || {};
  config.raml2HtmlVersion = pjson.version;

  return raml2obj.parse(source).then(function(ramlObj) {
    ramlObj.config = config;

    if (config.processRamlObj) {
      return config.processRamlObj(ramlObj).then(function(html) {
        if (config.postProcessHtml) {
          return config.postProcessHtml(html);
        }

        return html;
      });
    }

    return ramlObj;
  });
}

/**
 * @param {String} [mainTemplate] - The filename of the main template, leave empty to use default templates
 * @param {String} [templatesPath] - Optional, by default it uses the current working directory
 * @returns {{processRamlObj: Function, postProcessHtml: Function}}
 */
function getDefaultConfig(mainTemplate, templatesPath) {
  if (!mainTemplate) {
    // When using the default templates, using raml2html's lib folder as the templates path
    mainTemplate = 'template.nunjucks';
    templatesPath = path.join(__dirname, 'lib');
  }

  return {
    processRamlObj: function(ramlObj) {
      var nunjucks = require('nunjucks');
      var markdown = require('nunjucks-markdown');
      var marked = require('marked');
      var renderer = new marked.Renderer();
      renderer.table = function(thead, tbody) {
        // Render Bootstrap style tables
        return '

' + thead + '

' + tbody + '

';
      };

      // Setup the Nunjucks environment with the markdown parser
      var env = nunjucks.configure(templatesPath, {watch: false});
      markdown.register(env, marked);

      // Render the main template using the raml object and fix the double quotes
      var html = nunjucks.render(mainTemplate, ramlObj);
      html = html.replace(/"/g, '"');

      // Return the promise with the html
      return Q.fcall(function() {
        return html;
      });
    },

    postProcessHtml: function(html) {
      // Minimize the generated html and return the promise with the result
      var Minimize = require('minimize');
      var minimize = new Minimize({quotes: true});

      var deferred = Q.defer();

      minimize.parse(html, function(error, result) {
        if (error) {
          deferred.reject(new Error(error));
        } else {
          deferred.resolve(result);
        }
      });

      return deferred.promise;
    }
  };
}

if (require.main === module) {
  console.log('This script is meant to be used as a library. You probably want to run bin/raml2html if you\'re looking for a CLI.');
  process.exit(1);
}
<|endoftext|>


<commit_before>var es = require('event-stream');
var ngDep = require('ng-dependencies');
var toposort = require('toposort');

var ANGULAR_MODULE = 'ng';

module.exports = function angularFilesort () {
  var files = [];
  var angmods = {};
  var toSort = [];

  return es.through(function collectFilesToSort (file) {
      var deps = ngDep(file.contents);

      if (deps.modules) {
        // Store references to each file with a declaration:
        Object.keys(deps.modules).forEach(function (name) {
          angmods[name] = file;
        });
      }

      if (deps.dependencies) {
        // Add each file with dependencies to the array to sort:
        deps.dependencies.forEach(function (dep) {
          if (isDependecyUsedInAnyDeclaration(dep, deps)) {
            return;
          }
          if (dep === ANGULAR_MODULE) {
            return;
          }
          toSort.push([file, dep]);
        });
      }

      // Collect all files:
      files.push(file);

    }, function afterFileCollection () {
      // Convert all module names to actual files with declarations:
      for (var i = 0; i < toSort.length; i++) {
        var moduleName = toSort[i][1];
        var declarationFile = angmods[moduleName];
        if (declarationFile) {
          toSort[i][1] = declarationFile;
        } else {
          // Depending on module outside stream (possibly a 3rd party one),
          // don't care when sorting:
          toSort.splice(i--, 1);
        }
      }

      // Sort `files` with `toSort` as dependency tree:
      toposort.array(files, toSort)
        .reverse()
        .forEach(function (file) {
          this.emit('data', file);
        }.bind(this));

      this.emit('end');
    });
};

function isDependecyUsedInAnyDeclaration (dependency, ngDeps) {
  if (!ngDeps.modules) {
    return false;
  }
  if (dependency in ngDeps.modules) {
    return true;
  }
  return Object.keys(ngDeps.modules).any(function (module) {
    return ngDeps.modules[module].indexOf(dependency) > -1;
  });
}
<commit_msg>Properly Handle ng-dependencies Errors<commit_after>var es = require('event-stream');
var ngDep = require('ng-dependencies');
var toposort = require('toposort');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;

var ANGULAR_MODULE = 'ng';
const PLUGIN_NAME = 'gulp-angular-filesort';

module.exports = function angularFilesort () {
  var files = [];
  var angmods = {};
  var toSort = [];

  return es.through(function collectFilesToSort (file) {
      var deps;
      try {
        deps = ngDep(file.contents);
      } catch (err) {
        return this.emit('error', new PluginError(PLUGIN_NAME, "Error in compiling: " + file.relative + ": " + err.message));
      }

      if (deps.modules) {
        // Store references to each file with a declaration:
        Object.keys(deps.modules).forEach(function (name) {
          angmods[name] = file;
        });
      }

      if (deps.dependencies) {
        // Add each file with dependencies to the array to sort:
        deps.dependencies.forEach(function (dep) {
          if (isDependecyUsedInAnyDeclaration(dep, deps)) {
            return;
          }
          if (dep === ANGULAR_MODULE) {
            return;
          }
          toSort.push([file, dep]);
        });
      }

      // Collect all files:
      files.push(file);

    }, function afterFileCollection () {
      // Convert all module names to actual files with declarations:
      for (var i = 0; i < toSort.length; i++) {
        var moduleName = toSort[i][1];
        var declarationFile = angmods[moduleName];
        if (declarationFile) {
          toSort[i][1] = declarationFile;
        } else {
          // Depending on module outside stream (possibly a 3rd party one),
          // don't care when sorting:
          toSort.splice(i--, 1);
        }
      }

      // Sort `files` with `toSort` as dependency tree:
      toposort.array(files, toSort)
        .reverse()
        .forEach(function (file) {
          this.emit('data', file);
        }.bind(this));

      this.emit('end');
    });
};

function isDependecyUsedInAnyDeclaration (dependency, ngDeps) {
  if (!ngDeps.modules) {
    return false;
  }
  if (dependency in ngDeps.modules) {
    return true;
  }
  return Object.keys(ngDeps.modules).any(function (module) {
    return ngDeps.modules[module].indexOf(dependency) > -1;
  });
}
<|endoftext|>


<commit_before>"use strict"

var fs = require('fs');

RegExp.quote = function(str) {
  return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
};

module.exports = function (name, cb) {
	// /Users/alessandrominoccheri/Sites/klikkahotel.com/css/backend/_style.css
	var path_explode = name.split('/');
	var last_value = path_explode[path_explode.length-1];
	if(last_value.indexOf('.css') > 0){
		fs.readFile(name, 'utf8', function (err,data) {
			if (err)
			    return console.log(err);

			var class_to_find = 'label-blu';
			var reg = new RegExp('\\.' + RegExp.quote(class_to_find) + '([,:\\s\\.][^\\{]*)?\\{', 'gmi');
			var found = data.match(reg);

			if((found != '') && (found != null))
				found = found.length;
			else
				found = 0;

			console.log('found in ' + name + ': ' + found + ' match of ' + class_to_find);
		});
	}
	else{
		if(last_value.indexOf('.') == -1){
			fs.readdir(name, function(err,files){
			    if (err)
			    	return console.log(err);

			    var c=0;
			    files.forEach(function(file){
			    	var path_explode = file.split('/');
					var last_value = path_explode[path_explode.length-1];
					if(last_value.indexOf('.css') > 0){
				        fs.readFile(name+file,'utf-8',function(err, data){
				            if (err)
				            	return console.log(err);

				            var class_to_find = 'label-blu';
							var reg = new RegExp('\\.' + RegExp.quote(class_to_find) + '([,:\\s\\.][^\\{]*)?\\{', 'gmi');
							var found = data.match(reg);

							if((found != '') && (found != null))
								found = found.length;
							else
								found = 0;

							console.log('found in ' + name + file + ': ' + found + ' match of ' + class_to_find);
				        });
				    }
			    });
			});
		}
	}
};
<commit_msg>create recursive search file inside a directory<commit_after>"use strict"

var fs = require('fs');

RegExp.quote = function(str) {
  return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
};

function getDirectoryFiles(directory, callback) {
    fs.readdir(directory, function(err, files) {
        files.forEach(function(file){
            fs.stat(directory + '/' + file, function(err, stats) {
                if(stats.isFile()) {
                  callback(directory + '/' + file);
                }
                if(stats.isDirectory()) {
                  getDirectoryFiles(directory + '/' + file, callback);
                }
            });
        });
    });
}

module.exports = function (name, cb) {
	// /Users/alessandrominoccheri/Sites/klikkahotel.com/css/backend/_style.css
	var path_explode = name.split('/');
	var last_value = path_explode[path_explode.length-1];
	if(last_value.indexOf('.css') > 0){
		fs.readFile(name, 'utf8', function (err,data) {
			if (err)
			    return console.log(err);

			var class_to_find = 'label-blu';
			var reg = new RegExp('\\.' + RegExp.quote(class_to_find) + '([,:\\s\\.][^\\{]*)?\\{', 'gmi');
			var found = data.match(reg);

			if((found != '') && (found != null))
				found = found.length;
			else
				found = 0;

			console.log('found in ' + name + ': ' + found + ' match of ' + class_to_find);
		});
	}
	else{
		if(last_value.indexOf('.') == -1){
			getDirectoryFiles(name, function(file) {
			    var path_explode = file.split('/');
				var last_value = path_explode[path_explode.length-1];
				if(last_value.indexOf('.css') > 0){
				    fs.readFile(file,'utf-8',function(err, data){
				        if (err)
				        	return console.log(err);

				        var class_to_find = 'label-blu';
						var reg = new RegExp('\\.' + RegExp.quote(class_to_find) + '([,:\\s\\.][^\\{]*)?\\{', 'gmi');
						var found = data.match(reg);

						if((found != '') && (found != null))
							found = found.length;
						else
							found = 0;

						console.log('found in ' + file + ': ' + found + ' match of ' + class_to_find);
				    });
				}
			});
		}
	}
};
<|endoftext|>


<commit_before> /**
 * react-native-check-box
 * Checkbox component for react native, it works on iOS and Android
 * https://github.com/crazycodeboy/react-native-check-box
 * Email:crazycodeboy@gmail.com
 * Blog:http://jiapenghui.com
 * @flow
 */

import React, {Component} from 'react';
import {
    StyleSheet,
    View,
    Image,
    Text,
    TouchableHighlight
} from 'react-native';

export default class CheckBox extends Component {
    static propTypes = {
        ...View.propTypes,
        leftText: React.PropTypes.string,
        leftTextView: React.PropTypes.element,
        rightText: React.PropTypes.string,
        leftTextStyle: Text.propTypes.style,
        rightTextView: React.PropTypes.element,
        rightTextStyle: Text.propTypes.style,
        checkedImage: React.PropTypes.element,
        unCheckedImage: React.PropTypes.element,
        onClick: React.PropTypes.func.isRequired,
        isChecked: React.PropTypes.bool.isRequired,
	checkBoxColor: React.PropTypes.string,
    }
    static defaultProps = {
        isChecked: false,
        leftTextStyle: {},
        rightTextStyle: {}
    }

    _renderLeft() {
        if (this.props.leftTextView)return this.props.leftTextView;
        if (!this.props.leftText)return null;
        return (
            <Text style={[styles.leftText, this.props.leftTextStyle]}>{this.props.leftText}</Text>
        );
    }
    _renderRight() {
        if (this.props.rightTextView)return this.props.rightTextView;
        if (!this.props.rightText)return null;
        return (
            <Text style={[styles.rightText, this.props.rightTextStyle]}>{this.props.rightText}</Text>
        );
    }

    _renderImage() {
        if (this.props.isChecked) {
            return this.props.checkedImage ? this.props.checkedImage : this.genCheckedImage();
        } else {
            return this.props.unCheckedImage ? this.props.unCheckedImage : this.genCheckedImage();
        }
    }

    genCheckedImage() {
        var source = this.props.isChecked ? require('./img/ic_check_box.png') : require('./img/ic_check_box_outline_blank.png');

        return (
            <Image source={source} tintColor={this.props.checkBoxColor}/>
        );
    }

    render() {
        return (
            <TouchableHighlight
                style={this.props.style}
                onPress={this.props.onClick}
                underlayColor='transparent'
            >
                <View style={styles.container}>
                    {this._renderLeft()}
                    {this._renderImage()}
                    {this._renderRight()}
                </View>
            </TouchableHighlight>
        );
    }
}
const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        alignItems: 'center'
    },
    leftText: {
        flex: 1,
    },
    rightText: {
        flex: 1,
        marginLeft: 10
    }
});
<commit_msg>Fixed applying tintColor.<commit_after> /**
 * react-native-check-box
 * Checkbox component for react native, it works on iOS and Android
 * https://github.com/crazycodeboy/react-native-check-box
 * Email:crazycodeboy@gmail.com
 * Blog:http://jiapenghui.com
 * @flow
 */

import React, {Component} from 'react';
import {
    StyleSheet,
    View,
    Image,
    Text,
    TouchableHighlight
} from 'react-native';

export default class CheckBox extends Component {
    static propTypes = {
        ...View.propTypes,
        leftText: React.PropTypes.string,
        leftTextView: React.PropTypes.element,
        rightText: React.PropTypes.string,
        leftTextStyle: Text.propTypes.style,
        rightTextView: React.PropTypes.element,
        rightTextStyle: Text.propTypes.style,
        checkedImage: React.PropTypes.element,
        unCheckedImage: React.PropTypes.element,
        onClick: React.PropTypes.func.isRequired,
        isChecked: React.PropTypes.bool.isRequired,
        checkBoxColor: React.PropTypes.string,
    }
    static defaultProps = {
        isChecked: false,
        leftTextStyle: {},
        rightTextStyle: {}
    }

    _renderLeft() {
        if (this.props.leftTextView)return this.props.leftTextView;
        if (!this.props.leftText)return null;
        return (
            <Text style={[styles.leftText, this.props.leftTextStyle]}>{this.props.leftText}</Text>
        );
    }
    _renderRight() {
        if (this.props.rightTextView)return this.props.rightTextView;
        if (!this.props.rightText)return null;
        return (
            <Text style={[styles.rightText, this.props.rightTextStyle]}>{this.props.rightText}</Text>
        );
    }

    _renderImage() {
        if (this.props.isChecked) {
            return this.props.checkedImage ? this.props.checkedImage : this.genCheckedImage();
        } else {
            return this.props.unCheckedImage ? this.props.unCheckedImage : this.genCheckedImage();
        }
    }

    genCheckedImage() {
        var source = this.props.isChecked ? require('./img/ic_check_box.png') : require('./img/ic_check_box_outline_blank.png');

        return (
            <Image source={source} style={{tintColor: this.props.checkBoxColor}} />
        );
    }

    render() {
        return (
            <TouchableHighlight
                style={this.props.style}
                onPress={this.props.onClick}
                underlayColor='transparent'
            >
                <View style={styles.container}>
                    {this._renderLeft()}
                    {this._renderImage()}
                    {this._renderRight()}
                </View>
            </TouchableHighlight>
        );
    }
}
const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        alignItems: 'center'
    },
    leftText: {
        flex: 1,
    },
    rightText: {
        flex: 1,
        marginLeft: 10
    }
});
<|endoftext|>


<commit_before>var Feedly = require('feedly');
var util = require('util');
var q = require('q');
var request = require('request');
var read = require('node-read');

var f = new Feedly({
  client_id: 'sandbox',
  port: 8080
});

var blessed = require('blessed')
, fs = require('fs');

var screen = blessed.screen({
  smartCSR: true,
  dockBorders: true
});

var listCategories = blessed.list({
  parent: screen,
  label: ' {bold}{cyan-fg}Categories',
  tags: true,
  draggable: true,
  top: 0,
  left: 0,
  width: '20%',
  height: '50%',
  keys: true,
  vi: true,
  mouse: true,
  border: 'line',
  scrollbar: {
    ch: ' ',
    track: {
      bg: 'cyan'
    },
    style: {
      inverse: true
    }
  },
  style: {
    item: {
      hover: {
        bg: 'blue'
      }
    },
    selected: {
      bg: 'blue',
      bold: true
    }
  },
  search: function(callback) {
    prompt.input('Search:', '', function(err, value) {
      if (err) return;
      return callback(null, value);
    });
  }
});

var listEntries = blessed.list({
  parent: screen,
  label: ' {bold}{cyan-fg}Feed Entries',
  tags: true,
  draggable: true,
  top: 0,
  right: 0,
  width: '80%',
  height: '50%',
  keys: true,
  vi: true,
  mouse: true,
  border: 'line',
  scrollbar: {
    ch: ' ',
    track: {
      bg: 'cyan'
    },
    style: {
      inverse: true
    }
  },
  style: {
    item: {
      hover: {
        bg: 'blue'
      }
    },
    selected: {
      bg: 'blue',
      bold: true
    }
  },
  search: function(callback) {
    prompt.input('Search:', '', function(err, value) {
      if (err) return;
      return callback(null, value);
    });
  }
});

var categoriesMap = null;

f.categories().then(function(results) {
  categoriesMap = new Object();
  var userId = results[0].id.substring(0, results[0].id.lastIndexOf('/'));
  results.unshift({ id: userId + '/global.saved', label: 'Saved'});
  results.unshift({ id: userId + '/global.all', label: 'All'});
  results.forEach(function(obj) {
    categoriesMap[obj.label] = obj;
    });
  listCategories.setItems(Object.keys(categoriesMap));
},
function (error) {
	console.log(error);
});

var content = blessed.box({
  parent: screen,
  label: ' {bold}{cyan-fg}Feed Content',
  tags: true,
  draggable: true,
  bottom: 1,
  right: 0,
  width: '100%',
  height: '50%',
  keys: true,
  vi: true,
  mouse: true,
  scrollable: true,
  border: 'line',
  scrollbar: {
    ch: ' ',
    track: {
      bg: 'cyan'
    },
    style: {
      inverse: true
    }
  },
  style: {
    item: {
      hover: {
        bg: 'blue'
      }
    }
  },
});

var status = blessed.box({
  parent: screen,
  bottom: 0,
  right: 0,
  height: 1,
  width: 'shrink',
  style: {
    bg: 'blue'
  },
  content: 'Select your piece of ANSI art (`/` to search).'
});

var loader = blessed.loading({
  parent: screen,
  top: 'center',
  left: 'center',
  height: 5,
  align: 'center',
  width: '50%',
  tags: true,
  hidden: true,
  border: 'line'
});

var msg = blessed.message({
  parent: screen,
  top: 'center',
  left: 'center',
  height: 'shrink',
  width: '50%',
  align: 'center',
  tags: true,
  hidden: true,
  border: 'line'
});

var prompt = blessed.prompt({
  parent: screen,
  top: 'center',
  left: 'center',
  height: 'shrink',
  width: 'shrink',
  keys: true,
  vi: true,
  mouse: true,
  tags: true,
  border: 'line',
  hidden: true
});

var entriesMap = null;

listCategories.on('select', function(el, selected) {
  if (listCategories._.rendering) return;

  var name = el.getText();
  var id = categoriesMap[name].id;
  status.setContent(id);

  listCategories._.rendering = true;
  loader.load('Loading...');

  var promise = f.contents(id, 500, 'oldest', true);

  q.all(promise).then(function(result) {
    listCategories._.rendering = false;
    loader.stop();

    entriesMap = new Object();
    result.items.forEach(function(obj) {
      entriesMap[obj.title] = obj;
      });

    listEntries.setItems(Object.keys(entriesMap));
    listEntries.focus();
  },
  function (error) {
    console.log(error);
  });
  screen.render();
});

listEntries.on('select', function(el, selected) {
  if (listEntries._.rendering) return;

  var name = el.getText();
  var url = entriesMap[name].alternate[0].href;

  //console.log(url);
  listEntries._.rendering = true;
  loader.load('Loading...');

  read(url, function(err, article, res) {
    listEntries._.rendering = false;
    loader.stop();
    var formattedContent = beautifyArticleString(article);
    content.setContent(formattedContent);
    content.focus();
    screen.render();
  });

});

function beautifyArticleString(article)
{
  var content = article.title;

  return content += article.content.split("/
]*>/g").join("\n\n\n").split("
").join("")
    .replace(/<(?:.|\n)*?>/gm, '');
}

listEntries.key('j', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

listEntries.key('down', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

listEntries.key('k', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

listEntries.key('up', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

function listEntriesScrollDown(ch, key) {
  if(listEntries.focused)
  {
    var index = listEntries.getScroll();
    switch (key.name) {
      case 'j':
      case 'down':
          if(index >= Object.keys(entriesMap).length - 1)
            return;
          //markAsRead(index);
          listEntriesScroll(index + 1);
        break;
      case 'k':
      case 'up':
          if(index == 0)
            return;
          listEntriesScroll(index - 1);
          break;
      default:
    }
  }
}

function markAsRead(index) {
  var item = listEntries.getItem(index);
  var name = item.getText();
  item = entriesMap[name];
  f.markEntryRead(item.id).then(function(results){
      updateStatus('success marked as read');
  },
  function (error) {
      updateStatus(error);
  });
}

function markAsSaved(index) {
  var item = listEntries.getItem(index);
  var name = item.getText();
  item = entriesMap[name];
  f.markEntrySaved(item.id).then(function(results){
      updateStatus('success marked as saved');
  },
  function (error) {
      updateStatus(error);
  });
}

function listEntriesScroll(index) {
  var item = listEntries.getItem(index);
  var text = "";
  if(item == null)
  {
    //console.log(index + " not found. Length:" + Object.keys(entriesMap).length);
  }
  else
  {
    var name = item.getText();
    if(entriesMap[name].summary != null) {
      text = entriesMap[name].summary.content;
    }
    else {
      //console.log(name + " not found in entriesmap");
    }
  }

  content.setContent(text);
  screen.render();
}

function updateStatus(content) {
  status.setContent(content);
  screen.render();
}

listCategories.items.forEach(function(item, i) {
  var text = item.label;
  item.setHover(categoriesMap[text]);
});

listEntries.items.forEach(function(item, i) {
  var text = item.id;
  item.setHover(entriesMap[text]);
});

listCategories.focus();
//list.enterSelected(0);

screen.key('i', function() {
  content.resetScroll();
  listCategories.focus();
});

screen.key('o', function() {
  content.resetScroll();
  listEntries.focus();
});

screen.key('p', function() {
  listCategories.focus();
});

screen.key('q', function() {
  return process.exit(0);
});

screen.key('s', function() {
  var index = listEntries.getScroll();
  markAsSaved(index);
});

screen.key('m', function() {
  var index = listEntries.getScroll();
  var values = Object.keys(entriesMap);
  var result = [];
  for(i = 0; i<= index; i++)
  {
    result.push(entriesMap[values[i]].id);
  }
  f.markEntryRead(result).then(function(results){
      updateStatus('marked ' + i + ' items as read');
  },
  function (error) {
      updateStatus(error);
  });
});

screen.render();

// https://github.com/chjj/blessed/issues/127
// https://github.com/Mithgol/node-singlebyte

function cp437ToUtf8(buf, callback) {
  try {
    return callback(null, singlebyte.bufToStr(buf, 'cp437'));
  } catch (e) {
    return callback(e);
  }
}

// Animating ANSI art doesn't work for screenshots.
var ANIMATING = [
  'bbs/void3',
  'holiday/xmasfwks',
  'unsorted/diver',
  'unsorted/mash-chp',
  'unsorted/ryans47',
  'unsorted/xmasfwks'
];
<commit_msg>bugfixes and enhancments<commit_after>var Feedly = require('feedly');
var util = require('util');
var q = require('q');
var request = require('request');
var read = require('node-read');

var f = new Feedly({
  client_id: 'sandbox',
  port: 8080
});

var blessed = require('blessed')
, fs = require('fs');

var screen = blessed.screen({
  smartCSR: true,
  dockBorders: true
});

var listCategories = blessed.list({
  parent: screen,
  label: ' {bold}{cyan-fg}Categories',
  tags: true,
  draggable: true,
  top: 0,
  left: 0,
  width: '20%',
  height: '50%',
  keys: true,
  vi: true,
  mouse: true,
  border: 'line',
  scrollbar: {
    ch: ' ',
    track: {
      bg: 'cyan'
    },
    style: {
      inverse: true
    }
  },
  style: {
    item: {
      hover: {
        bg: 'blue'
      }
    },
    selected: {
      bg: 'blue',
      bold: true
    }
  },
  search: function(callback) {
    prompt.input('Search:', '', function(err, value) {
      if (err) return;
      return callback(null, value);
    });
  }
});

var listEntries = blessed.list({
  parent: screen,
  label: ' {bold}{cyan-fg}Feed Entries',
  tags: true,
  draggable: true,
  top: 0,
  right: 0,
  width: '80%',
  height: '50%',
  keys: true,
  vi: true,
  mouse: true,
  border: 'line',
  scrollbar: {
    ch: ' ',
    track: {
      bg: 'cyan'
    },
    style: {
      inverse: true
    }
  },
  style: {
    item: {
      hover: {
        bg: 'blue'
      }
    },
    selected: {
      bg: 'blue',
      bold: true
    }
  },
  search: function(callback) {
    prompt.input('Search:', '', function(err, value) {
      if (err) return;
      return callback(null, value);
    });
  }
});

function setlistEntrieslabel(string) {
  listEntries.setLabel({text:'{bold}{cyan-fg}Feed Entries (' + string +')',side:'center'});
}

function setContentLabel(string) {
  content.setLabel({text:'{bold}{cyan-fg}Feed Name: ' + string,side:'center'});
}

var categoriesMap = null;

f.categories().then(function(results) {
  categoriesMap = new Object();
  var userId = results[0].id.substring(0, results[0].id.lastIndexOf('/'));
  results.unshift({ id: userId + '/global.saved', label: 'Saved'});
  results.unshift({ id: userId + '/global.all', label: 'All'});
  results.forEach(function(obj) {
    categoriesMap[obj.label] = obj;
    });
  listCategories.setItems(Object.keys(categoriesMap));
},
function (error) {
	updateStatus(error);
});

var content = blessed.box({
  parent: screen,
  label: ' {bold}{cyan-fg}Feed Source:',
  tags: true,
  draggable: true,
  bottom: 1,
  right: 0,
  width: '100%',
  height: '50%',
  keys: true,
  vi: true,
  mouse: true,
  scrollable: true,
  border: 'line',
  scrollbar: {
    ch: ' ',
    track: {
      bg: 'cyan'
    },
    style: {
      inverse: true
    }
  },
  style: {
    item: {
      hover: {
        bg: 'blue'
      }
    }
  },
});

var status = blessed.box({
  parent: screen,
  bottom: 0,
  right: 0,
  height: 1,
  width: 'shrink',
  style: {
    bg: 'blue'
  },
  content: 'Select your piece of ANSI art (`/` to search).'
});

var loader = blessed.loading({
  parent: screen,
  top: 'center',
  left: 'center',
  height: 5,
  align: 'center',
  width: '50%',
  tags: true,
  hidden: true,
  border: 'line'
});

var msg = blessed.message({
  parent: screen,
  top: 'center',
  left: 'center',
  height: 'shrink',
  width: '50%',
  align: 'center',
  tags: true,
  hidden: true,
  border: 'line'
});

var prompt = blessed.prompt({
  parent: screen,
  top: 'center',
  left: 'center',
  height: 'shrink',
  width: 'shrink',
  keys: true,
  vi: true,
  mouse: true,
  tags: true,
  border: 'line',
  hidden: true
});

var entriesMap = null;

listCategories.on('select', function(el, selected) {
  if (listCategories._.rendering) return;

  var name = el.getText();
  var id = categoriesMap[name].id;
  status.setContent(id);

  listCategories._.rendering = true;
  loader.load('Loading...');

  var promise = f.contents(id, 500, 'oldest', true);

  q.all(promise).then(function(result) {
    listCategories._.rendering = false;
    loader.stop();

    entriesMap = new Object();
    result.items.forEach(function(obj) {
      entriesMap[obj.title] = obj;
      });

    listEntries.setItems(Object.keys(entriesMap));
    setlistEntrieslabel(Object.keys(entriesMap).length);
    listEntries.focus();
  },
  function (error) {
    updateStatus(error);
  });
  screen.render();
});

listEntries.on('select', function(el, selected) {
  if (listEntries._.rendering) return;

  var name = el.getText();
  var url = entriesMap[name].alternate[0].href;

  listEntries._.rendering = true;
  loader.load('Loading...');

  read(url, function(err, article, res) {
    listEntries._.rendering = false;
    loader.stop();
    if(article == null) {
        updateStatus('Error fetching article');
        return;
    }

    var formattedContent = beautifyString(article.title + ' ' + article.content);
    try {
      content.setContent(formattedContent);
      content.focus();
      screen.render();
    }
    catch(ex) {
      content.setContent('');
      updateStatus(ex);
    }
    finally {
      screen.render();
    }
  });

});

function beautifyString(string)
{
  return string.split("/
]*>/g").join("\n\n\n").split("
").join("")
    .replace(/<(?:.|\n)*?>/gm, '');
}

listEntries.key('j', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

listEntries.key('down', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

listEntries.key('k', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

listEntries.key('up', function(ch, key) {
  listEntriesScrollDown(ch, key);
});

function listEntriesScrollDown(ch, key) {
  if(listEntries.focused)
  {
    var index = listEntries.getScroll();
    switch (key.name) {
      case 'j':
      case 'down':
          if(index >= Object.keys(entriesMap).length - 1)
            return;
          //markAsRead(index);
          listEntriesScroll(index + 1);
        break;
      case 'k':
      case 'up':
          if(index == 0)
            return;
          listEntriesScroll(index - 1);
          break;
      default:
    }
  }
}

function markAsRead(index) {
  var item = listEntries.getItem(index);
  var name = item.getText();
  item = entriesMap[name];
  f.markEntryRead(item.id).then(function(results){
      updateStatus('success marked as read');
  },
  function (error) {
      updateStatus(error);
  });
}

function markAsSaved(index) {
  var item = listEntries.getItem(index);
  var name = item.getText();
  item = entriesMap[name];
  f.markEntrySaved(item.id).then(function(results){
      updateStatus('success marked as saved');
  },
  function (error) {
      updateStatus(error);
  });
}

function listEntriesScroll(index) {
  var item = listEntries.getItem(index);
  var text = "";
  var count = Object.keys(entriesMap).length;
  if(item == null)
  {
    updateStatus(index + " not found. Length:" + count);
  }
  else
  {
    var name = item.getText();
    if(entriesMap[name].summary != null) {
      text = entriesMap[name].summary.content;
      setContentLabel(entriesMap[name].origin.title);
    }
    else {
      updateStatus(name + " not found in entriesmap");
    }
  }
  setlistEntrieslabel(index + '/' + count);
  text = beautifyString(text);
  content.setContent(text);
  try {
    screen.render();
  } catch (e) {
    updateStatus(e);
  } finally {
  }
}

function updateStatus(content) {
  try {
    status.setContent(JSON.stringify(content));
  }catch(error) {
  }
  finally {
    screen.render();
  }
}

listCategories.items.forEach(function(item, i) {
  var text = item.label;
  item.setHover(categoriesMap[text]);
});

listEntries.items.forEach(function(item, i) {
  var text = item.id;
  item.setHover(entriesMap[text]);
});

listCategories.focus();

screen.key('i', function() {
  content.resetScroll();
  listCategories.focus();
});

screen.key('o', function() {
  content.resetScroll();
  listEntries.focus();
});

screen.key('p', function() {
  listCategories.focus();
});

screen.key('q', function() {
  return process.exit(0);
});

screen.key('s', function() {
  var index = listEntries.getScroll();
  markAsSaved(index);
});

screen.key('m', function() {
  var index = listEntries.getScroll();
  var values = Object.keys(entriesMap);
  var result = [];
  for(i = 0; i<= index; i++)
  {
    result.push(entriesMap[values[i]].id);
  }
  f.markEntryRead(result).then(function(results){
      updateStatus('marked ' + i + ' items as read');
  },
  function (error) {
      updateStatus(error);
  });
});

screen.render();

// https://github.com/chjj/blessed/issues/127
// https://github.com/Mithgol/node-singlebyte

function cp437ToUtf8(buf, callback) {
  try {
    return callback(null, singlebyte.bufToStr(buf, 'cp437'));
  } catch (e) {
    return callback(e);
  }
}
<|endoftext|>


<commit_before>'use strict';
module.exports = function (data_array, opts) {

	var barChar = require('figures').square;
	var Stats = require('fast-stats').Stats;
	var width = require('window-size').width;
	var maxBarWidth = width - 20;
	var total_sum = 0.;
	var percentage = [];
	var barWidths = [];

	for(var i in data_array){
		total_sum += data_array[i];
	}

	for(var i in data_array){
		percentage.push((data_array[i] / total_sum) * 100);
	}

	var max_percentage = (new Stats().push(percentage)).range()[1];

	var fixedLabels = new Array();
	var labelsTrue = opts ? opts.labels : false;
	var maxLabelLength = 0;

	if (labelsTrue) {
		for (var i in data_array) {
			maxLabelLength = (i.toString().length > maxLabelLength)
			? i.toString().length : maxLabelLength;
		}

		for (var i in data_array) {
			var padLength = maxLabelLength - i.toString().length + 1;
			fixedLabels.push(i + (padLength > 0
				? new Array(padLength).join(' ') : ''));
		}
	}

	maxBarWidth = labelsTrue ? (maxBarWidth - maxLabelLength) : maxBarWidth;

	for(var i in percentage){
		barWidths.push(Math.ceil(percentage[i] / max_percentage * maxBarWidth))
	}

	for(var i in percentage){
		console.log((labelsTrue ? fixedLabels[i] : '') + ' : '
		+ new Array(barWidths[i]).join(barChar) + ' '
		+ percentage[i].toFixed() + '%');
	}

};
<commit_msg>Fix coding style issues.<commit_after>'use strict';
module.exports = function (data_array, opts) {

	var barChar = require('figures').square;
	var Stats = require('fast-stats').Stats;
	var width = require('window-size').width;
	var maxBarWidth = width - 20;
	var total_sum = 0.;
	var percentage = [];
	var barWidths = [];

	for (var i in data_array) {
		total_sum += data_array[i];
	}

	for (var i in data_array) {
		percentage.push((data_array[i] / total_sum) * 100);
	}

	var max_percentage = (new Stats().push(percentage)).range()[1];

	var fixedLabels = new Array();
	var labelsTrue = opts ? opts.labels : false;
	var maxLabelLength = 0;

	if (labelsTrue) {
		for (var i in data_array) {
			maxLabelLength = (i.toString().length > maxLabelLength)
			? i.toString().length : maxLabelLength;
		}

		for (var i in data_array) {
			var padLength = maxLabelLength - i.toString().length + 1;
			fixedLabels.push(i + (padLength > 0
				? new Array(padLength).join(' ') : ''));
		}
	}

	maxBarWidth = labelsTrue ? (maxBarWidth - maxLabelLength) : maxBarWidth;

	for (var i in percentage) {
		barWidths.push(Math.ceil(percentage[i] / max_percentage * maxBarWidth))
	}

	for (var i in percentage) {
		console.log((labelsTrue ? fixedLabels[i] : '') + ' : '
		+ new Array(barWidths[i]).join(barChar) + ' '
		+ percentage[i].toFixed() + '%');
	}

};
<|endoftext|>