<commit_before>const {Disposable} = require('atom')

module.exports =
class GrammarStatusView {
  constructor (statusBar) {
    this.statusBar = statusBar
    this.element = document.createElement('grammar-selector-status')
    this.element.classList.add('grammar-status', 'inline-block')
    this.grammarLink = document.createElement('a')
    this.grammarLink.classList.add('inline-block')
    this.element.appendChild(this.grammarLink)

    this.activeItemSubscription = atom.workspace.observeActiveTextEditor(this.subscribeToActiveTextEditor.bind(this))

    this.configSubscription = atom.config.observe('grammar-selector.showOnRightSideOfStatusBar', this.attach.bind(this))
    const clickHandler = (event) => {
      event.preventDefault()
      atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'grammar-selector:show')
    }
    this.element.addEventListener('click', clickHandler)
    this.clickSubscription = new Disposable(() => { this.element.removeEventListener('click', clickHandler) })
  }

  attach () {
    if (this.tile) {
      this.tile.destroy()
    }

    this.tile = atom.config.get('grammar-selector.showOnRightSideOfStatusBar')
      ? this.statusBar.addRightTile({item: this.element, priority: 10})
      : this.statusBar.addLeftTile({item: this.element, priority: 10})
  }

  destroy () {
    if (this.activeItemSubscription) {
      this.activeItemSubscription.dispose()
    }

    if (this.grammarSubscription) {
      this.grammarSubscription.dispose()
    }

    if (this.clickSubscription) {
      this.clickSubscription.dispose()
    }

    if (this.configSubscription) {
      this.configSubscription.dispose()
    }

    if (this.tile) {
      this.tile.destroy()
    }

    if (this.tooltip) {
      this.tooltip.destroy()
    }
  }

  subscribeToActiveTextEditor () {
    if (this.grammarSubscription) {
      this.grammarSubscription.dispose()
      this.grammarSubscription = null
    }

    const editor = atom.workspace.getActiveTextEditor()
    if (editor) {
      this.grammarSubscription = editor.onDidChangeGrammar(this.updateGrammarText.bind(this))
    }
    this.updateGrammarText()
  }

  updateGrammarText () {
    atom.views.updateDocument(() => {
      const editor = atom.workspace.getActiveTextEditor()
      const grammar = editor ? editor.getGrammar() : null

      if (this.tooltip) {
        this.tooltip.dispose()
        this.tooltip = null
      }

      if (grammar) {
        let grammarName = null
        if (grammar === atom.grammars.nullGrammar) {
          grammarName = 'Plain Text'
        } else {
          grammarName = grammar.name || grammar.scopeName
        }

        this.grammarLink.textContent = grammarName
        this.grammarLink.dataset.grammar = grammarName
        this.element.style.display = ''

        this.tooltip = atom.tooltips.add(this.element, {title: `File uses the ${grammarName} grammar`})
      } else {
        this.element.style.display = 'none'
      }
    })
  }
}
<commit_msg>fix tooltip distroy error<commit_after>const {Disposable} = require('atom')

module.exports =
class GrammarStatusView {
  constructor (statusBar) {
    this.statusBar = statusBar
    this.element = document.createElement('grammar-selector-status')
    this.element.classList.add('grammar-status', 'inline-block')
    this.grammarLink = document.createElement('a')
    this.grammarLink.classList.add('inline-block')
    this.element.appendChild(this.grammarLink)

    this.activeItemSubscription = atom.workspace.observeActiveTextEditor(this.subscribeToActiveTextEditor.bind(this))

    this.configSubscription = atom.config.observe('grammar-selector.showOnRightSideOfStatusBar', this.attach.bind(this))
    const clickHandler = (event) => {
      event.preventDefault()
      atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'grammar-selector:show')
    }
    this.element.addEventListener('click', clickHandler)
    this.clickSubscription = new Disposable(() => { this.element.removeEventListener('click', clickHandler) })
  }

  attach () {
    if (this.tile) {
      this.tile.destroy()
    }

    this.tile = atom.config.get('grammar-selector.showOnRightSideOfStatusBar')
      ? this.statusBar.addRightTile({item: this.element, priority: 10})
      : this.statusBar.addLeftTile({item: this.element, priority: 10})
  }

  destroy () {
    if (this.activeItemSubscription) {
      this.activeItemSubscription.dispose()
    }

    if (this.grammarSubscription) {
      this.grammarSubscription.dispose()
    }

    if (this.clickSubscription) {
      this.clickSubscription.dispose()
    }

    if (this.configSubscription) {
      this.configSubscription.dispose()
    }

    if (this.tile) {
      this.tile.destroy()
    }

    if (this.tooltip) {
      this.tooltip.dispose()
    }
  }

  subscribeToActiveTextEditor () {
    if (this.grammarSubscription) {
      this.grammarSubscription.dispose()
      this.grammarSubscription = null
    }

    const editor = atom.workspace.getActiveTextEditor()
    if (editor) {
      this.grammarSubscription = editor.onDidChangeGrammar(this.updateGrammarText.bind(this))
    }
    this.updateGrammarText()
  }

  updateGrammarText () {
    atom.views.updateDocument(() => {
      const editor = atom.workspace.getActiveTextEditor()
      const grammar = editor ? editor.getGrammar() : null

      if (this.tooltip) {
        this.tooltip.dispose()
        this.tooltip = null
      }

      if (grammar) {
        let grammarName = null
        if (grammar === atom.grammars.nullGrammar) {
          grammarName = 'Plain Text'
        } else {
          grammarName = grammar.name || grammar.scopeName
        }

        this.grammarLink.textContent = grammarName
        this.grammarLink.dataset.grammar = grammarName
        this.element.style.display = ''

        this.tooltip = atom.tooltips.add(this.element, {title: `File uses the ${grammarName} grammar`})
      } else {
        this.element.style.display = 'none'
      }
    })
  }
}
<|endoftext|>


<commit_before>
/*!
 * CSS - Lexer
 * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Token = require('./token')
  , nodes = require('./nodes');

/**
 * Operator aliases.
 */

var alias = {
    and: '&&'
  , or: '||'
};

/**
 * Numeric strings used for exceptions.
 */

var numberString = [, 'one', 'two'];

/**
 * Units.
 */

var units = [
    'em'
  , 'ex'
  , 'px'
  , 'mm'
  , 'cm'
  , 'in'
  , 'pt'
  , 'pc'
  , 'deg'
  , 'rad'
  , 'grad'
  , 'ms'
  , 's'
  , 'Hz'
  , 'kHz'
  , '%'].join('|');

/**
 * Unit RegExp.
 */

var unit = new RegExp('^(-)?(\\d+\\.\\d+|\\d+|\\.\\d+)(' + units + ')? *');

/**
 * Initialize a new `Lexer` with the given `str` and `options`.
 *
 * @param {String} str
 * @param {Object} options
 * @api private
 */

var Lexer = module.exports = function Lexer(str, options) {
  options = options || {};
  this.str = str.replace(/\r\n?/g, '\n').replace(/\t/g, '  ');
  this.stash = [];
  this.prevIndents = 0;
  this.lineno = 0;
};

/**
 * Lexer prototype.
 */

Lexer.prototype = {

  /**
   * Custom inspect.
   */

  inspect: function(){
    var tok
      , tmp = this.str
      , buf = [];
    while ('eos' != (tok = this.next).type) {
      buf.push(tok.inspect());
    }
    this.str = tmp;
    this.prevIndents = 0;
    return buf.concat(tok.inspect()).join('\n');
  },

  /**
   * Lookahead `n` tokens.
   *
   * @param {Number} n
   * @return {Object}
   * @api private
   */

  lookahead: function(n){
    var fetch = n - this.stash.length;
    while (fetch-- > 0) this.stash.push(this.advance);
    return this.stash[--n];
  },

  /**
   * Consume the given `len`.
   *
   * @param {Number|Array} len
   * @api private
   */

  skip: function(len){
    this.str = this.str.substr(Array.isArray(len)
      ? len[0].length
      : len);
  },

  /**
   * Fetch next token including those stashed by peek.
   *
   * @return {Token}
   * @api private
   */

  get next() {
    var tok = this.stashed || this.advance;
    switch (tok.type) {
      case 'newline':
      case 'selector':
      case 'indent':
        ++this.lineno;
    }
    tok.lineno = this.lineno;
    return tok;
  },

  /**
   * Fetch next token.
   *
   * @return {Token}
   * @api private
   */

  get advance() {
    return this.eos
      || this.null
      || this.keyword
      || this.atrule
      || this.media
      || this.comment
      || this.newline
      || this.escaped
      || this.important
      || this.literal
      || this.function
      || this.brace
      || this.paren
      || this.color
      || this.string
      || this.unit
      || this.namedop
      || this.boolean
      || this.ident
      || this.op
      || this.space
      || this.selector;
  },

  /**
   * Lookahead a single token.
   *
   * @return {Token}
   * @api private
   */

  get peek() {
    return this.lookahead(1);
  },

  /**
   * Return the next possibly stashed token.
   *
   * @return {Token}
   * @api private
   */

  get stashed() {
    return this.stash.shift();
  },

  /**
   * EOS | trailing outdents.
   */

  get eos() {
    if (this.str.length) return;
    return --this.prevIndents < 0
      ? new Token('eos')
      : new Token('outdent');
  },

  /**
   * ' '+
   */

  get space() {
    var captures;
    if (captures = /^( +)/.exec(this.str)) {
      this.skip(captures);
      return new Token('space');
    }
  },

  /**
   * '\\' . ' '*
   */

  get escaped() {
    var captures;
    if (captures = /^\\(.) */.exec(this.str)) {
      var c = captures[1];
      this.skip(captures);
      return new Token('ident', new nodes.Literal(c));
    }
  },

  /**
   * '@css' ' '* '{' .* '}' ' '*
   */

  get literal() {
    // HACK attack !!!
    var captures;
    if (captures = /^@css *\{/.exec(this.str)) {
      this.skip(captures);
      var c
        , braces = 1
        , css = '';
      while (c = this.str[0]) {
        this.str = this.str.substr(1);
        switch (c) {
          case '{': ++braces; break;
          case '}': --braces; break;
        }
        css += c;
        if (!braces) break;
      }
      css = css.replace(/\s*}$/, '');
      return new Token('literal', new nodes.Literal(css));
    }
  },

  /**
   * '!important' ' '*
   */

  get important() {
    var captures;
    if (captures = /^!important */.exec(this.str)) {
      this.skip(captures);
      return new Token('ident', new nodes.Literal('!important'));
    }
  },

  /**
   * '{' | '}'
   */

  get brace() {
    var captures;
    if (captures = /^([{}])/.exec(this.str)) {
      this.skip(1);
      var brace = captures[1];
      return new Token(brace, brace);
    }
  },

  /**
   * '(' | ')' ' '*
   */

  get paren() {
    var captures;
    if (captures = /^([()]) */.exec(this.str)) {
      var paren = captures[1];
      this.skip(captures);
      if (')' == paren) this.isURL = false;
      return new Token(paren, paren);
    }
  },

  /**
   * 'null'
   */

  get null() {
    var captures;
    if (captures = /^(null)\b */.exec(this.str)) {
      this.skip(captures);
      return new Token('null', nodes.null);
    }
  },

  /**
   *   'if'
   * | 'else'
   * | 'unless'
   * | 'return'
   * | 'for'
   * | 'in'
   */

  get keyword() {
    var captures;
    if (captures = /^(return|if|else|unless|for|in)\b */.exec(this.str)) {
      var keyword = captures[1];
      this.skip(captures);
      return new Token(keyword, keyword);
    }
  },

  /**
   *   'not'
   * | 'and'
   * | 'or'
   * | 'is a'
   * | 'is defined'
   */

  get namedop() {
    var captures;
    if (captures = /^(not|and|or|is a|is defined)\b( *)/.exec(this.str)) {
      var op = captures[1];
      this.skip(captures);
      op = alias[op] || op;
      var tok = new Token(op, op);
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   *   ','
   * | '+'
   * | '-'
   * | '*'
   * | '/'
   * | '%'
   * | '**'
   * | '!'
   * | '&'
   * | '&&'
   * | '||'
   * | '>'
   * | '>='
   * | '<'
   * | '<='
   * | '='
   * | '=='
   * | '!='
   * | '!'
   * | '~'
   * | '?='
   * | '?'
   * | ':'
   * | '['
   * | ']'
   * | '..'
   * | '...'
   */

  get op() {
    var captures;
    if (captures = /^([.]{2,3}|&&|\|\||[!<>=?]=|\*\*|[-,=?:!~+<>*\/%&\[\]])( *)/.exec(this.str)) {
      var op = captures[1];
      this.skip(captures);
      op = alias[op] || op;
      var tok = new Token(op, op);
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   * '@media' ([^\n]+)
   */

  get media() {
    var captures;
    if (captures = /^@media *([^\n]+)/.exec(this.str)) {
      this.skip(captures);
      return new Token('media', captures[1]);
    }
  },

  /**
   * '@' ('import' | 'keyframes' | 'charset' | 'page')
   */

  get atrule() {
    var captures;
    if (captures = /^@(import|keyframes|charset|page) */.exec(this.str)) {
      this.skip(captures);
      return new Token(captures[1]);
    }
  },

  /**
   * '//' *
   */

  get comment() {
    // Single line
    if ('/' == this.str[0] && '/' == this.str[1]) {
      var end = this.str.indexOf('\n');
      if (-1 == end) end = this.str.length;
      this.skip(end);
      return this.advance;
    }

    // Multi-line
    if ('/' == this.str[0] && '*' == this.str[1]) {
      var end = this.str.indexOf('*/');
      if (-1 == end) end = this.str.length;
      var str = this.str.substr(0, end + 2)
        , lines = str.split('\n').length - 1;
      this.lineno += lines;
      this.skip(end + 2);
      return this.allowComments
        ? new Token('comment', str)
        : this.advance;
    }
  },

  /**
   * 'true' | 'false'
   */

  get boolean() {
    var captures;
    if (captures = /^(true|false)\b( *)/.exec(this.str)) {
      var val = 'true' == captures[1]
        ? nodes.true
        : nodes.false;
      this.skip(captures);
      var tok = new Token('boolean', val);
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   * -?[a-zA-Z] [-\w\d]* '('
   */

  get function() {
    var captures;
    if (captures = /^(-?[a-zA-Z][-\w\d]*)\(( *)/.exec(this.str)) {
      var name = captures[1];
      this.skip(captures);
      this.isURL = 'url' == name;
      var tok = new Token('function', new nodes.Ident(name));
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   * -?[a-zA-Z] [-\w\d]*
   */

  get ident() {
    var captures;
    if (captures = /^(-?[a-zA-Z][-\w\d]*)/.exec(this.str)) {
      var name = captures[1];
      this.skip(captures);
      return new Token('ident', new nodes.Ident(name));
    }
  },

  /**
   * '\n' ' '+
   */

  get newline() {
    var captures;
    if (captures = /^\n( *)/.exec(this.str)) {
      var tok
        , spaces = captures[1].length
        , indents = spaces / 2;

      this.skip(captures);

      // Reset state
      this.isVariable = false;

      // Blank line
      if ('\n' == this.str[0]) {
        ++this.lineno;
        return this.advance;
      }

      // To few spaces
      if (0 != spaces % 2) {
        var str = 1 == spaces ? 'space' : 'spaces'
          , spaces = numberString[spaces] || spaces;
        throw new Error('Invalid indentation, got ' + spaces + ' ' + str + ' and expected multiple of two');
      // To many spaces
      } else if (indents > this.prevIndents + 1) {
        var str = 1 == spaces ? 'space' : 'spaces'
          , expected = 2 * (this.prevIndents * 2) || 2
          , expected = numberString[expected] || expected
          , spaces = numberString[spaces] || spaces;
        throw new Error('Invalid indentation, got ' + spaces + ' ' + str + ' and expected ' + expected);
      // Outdent
      } else if (indents < this.prevIndents) {
        var n = this.prevIndents - indents;
        while (--n) this.stash.push(new Token('outdent'));
        this.prevIndents = indents;
        tok = new Token('outdent');
      // Indent
      } else if (indents != this.prevIndents) {
        this.prevIndents = indents;
        tok = new Token('indent');
      // Newline
      } else {
        tok = new Token('newline');
      }

      return tok;
    }
  },

  /**
   * '-'? (digit+ | digit* '.' digit+) unit
   */

  get unit() {
    var captures;
    if (captures = unit.exec(this.str)) {
      this.skip(captures);
      var n = parseFloat(captures[2]);
      if ('-' == captures[1]) n = -n;
      var node = new nodes.Unit(n, captures[3]);
      return new Token('unit', node);
    }
  },

  /**
   * '"' [^"]+ '"' | "'"" [^']+ "'"
   */

  get string() {
    var captures;

    // url() special case
    if (this.isURL && (captures = /^([^'"][^)]+) */.exec(this.str))) {
      this.skip(captures);
      return new Token('string', new nodes.String(captures[1]));
    }

    // Regular string
    if (captures = /^("[^"]*"|'[^']*') */.exec(this.str)) {
      var str = captures[1];
      this.skip(captures);
      return new Token('string', new nodes.String(str.slice(1,-1)));
    }
  },

  /**
   * #nnnnnn | #nnn
   */

  get color() {
    return this.hex6 || this.hex3;
  },

  /**
   * #nnn
   */

  get hex3() {
    var captures;
    if (captures = /^#([a-f-A-F0-9]{3}) */.exec(this.str)) {
      this.skip(captures);
      var rgb = captures[1]
        , r = parseInt(rgb[0] + rgb[0], 16)
        , g = parseInt(rgb[1] + rgb[1], 16)
        , b = parseInt(rgb[2] + rgb[2], 16);
      return new Token('color', new nodes.Color(r, g, b, 1));
    }
  },

  /**
   * #nnnnnn
   */

  get hex6() {
    var captures;
    if (captures = /^#([a-f-A-F0-9]{6}) */.exec(this.str)) {
      this.skip(captures);
      var rgb = captures[1]
        , r = parseInt(rgb.substr(0, 2), 16)
        , g = parseInt(rgb.substr(2, 2), 16)
        , b = parseInt(rgb.substr(4, 2), 16);
      return new Token('color', new nodes.Color(r, g, b, 1));
    }
  },

  /**
   * [^\n,;]+
   */

  get selector() {
    var captures;
    if (captures = /^[^\n,]+/.exec(this.str)) {
      var selector = captures[0];
      this.skip(captures);
      return new Token('selector', selector);
    }
  }
};
<commit_msg>Scanning assignment ops<commit_after>
/*!
 * CSS - Lexer
 * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Token = require('./token')
  , nodes = require('./nodes');

/**
 * Operator aliases.
 */

var alias = {
    and: '&&'
  , or: '||'
};

/**
 * Numeric strings used for exceptions.
 */

var numberString = [, 'one', 'two'];

/**
 * Units.
 */

var units = [
    'em'
  , 'ex'
  , 'px'
  , 'mm'
  , 'cm'
  , 'in'
  , 'pt'
  , 'pc'
  , 'deg'
  , 'rad'
  , 'grad'
  , 'ms'
  , 's'
  , 'Hz'
  , 'kHz'
  , '%'].join('|');

/**
 * Unit RegExp.
 */

var unit = new RegExp('^(-)?(\\d+\\.\\d+|\\d+|\\.\\d+)(' + units + ')? *');

/**
 * Initialize a new `Lexer` with the given `str` and `options`.
 *
 * @param {String} str
 * @param {Object} options
 * @api private
 */

var Lexer = module.exports = function Lexer(str, options) {
  options = options || {};
  this.str = str.replace(/\r\n?/g, '\n').replace(/\t/g, '  ');
  this.stash = [];
  this.prevIndents = 0;
  this.lineno = 0;
};

/**
 * Lexer prototype.
 */

Lexer.prototype = {

  /**
   * Custom inspect.
   */

  inspect: function(){
    var tok
      , tmp = this.str
      , buf = [];
    while ('eos' != (tok = this.next).type) {
      buf.push(tok.inspect());
    }
    this.str = tmp;
    this.prevIndents = 0;
    return buf.concat(tok.inspect()).join('\n');
  },

  /**
   * Lookahead `n` tokens.
   *
   * @param {Number} n
   * @return {Object}
   * @api private
   */

  lookahead: function(n){
    var fetch = n - this.stash.length;
    while (fetch-- > 0) this.stash.push(this.advance);
    return this.stash[--n];
  },

  /**
   * Consume the given `len`.
   *
   * @param {Number|Array} len
   * @api private
   */

  skip: function(len){
    this.str = this.str.substr(Array.isArray(len)
      ? len[0].length
      : len);
  },

  /**
   * Fetch next token including those stashed by peek.
   *
   * @return {Token}
   * @api private
   */

  get next() {
    var tok = this.stashed || this.advance;
    switch (tok.type) {
      case 'newline':
      case 'selector':
      case 'indent':
        ++this.lineno;
    }
    tok.lineno = this.lineno;
    return tok;
  },

  /**
   * Fetch next token.
   *
   * @return {Token}
   * @api private
   */

  get advance() {
    return this.eos
      || this.null
      || this.keyword
      || this.atrule
      || this.media
      || this.comment
      || this.newline
      || this.escaped
      || this.important
      || this.literal
      || this.function
      || this.brace
      || this.paren
      || this.color
      || this.string
      || this.unit
      || this.namedop
      || this.boolean
      || this.ident
      || this.op
      || this.space
      || this.selector;
  },

  /**
   * Lookahead a single token.
   *
   * @return {Token}
   * @api private
   */

  get peek() {
    return this.lookahead(1);
  },

  /**
   * Return the next possibly stashed token.
   *
   * @return {Token}
   * @api private
   */

  get stashed() {
    return this.stash.shift();
  },

  /**
   * EOS | trailing outdents.
   */

  get eos() {
    if (this.str.length) return;
    return --this.prevIndents < 0
      ? new Token('eos')
      : new Token('outdent');
  },

  /**
   * ' '+
   */

  get space() {
    var captures;
    if (captures = /^( +)/.exec(this.str)) {
      this.skip(captures);
      return new Token('space');
    }
  },

  /**
   * '\\' . ' '*
   */

  get escaped() {
    var captures;
    if (captures = /^\\(.) */.exec(this.str)) {
      var c = captures[1];
      this.skip(captures);
      return new Token('ident', new nodes.Literal(c));
    }
  },

  /**
   * '@css' ' '* '{' .* '}' ' '*
   */

  get literal() {
    // HACK attack !!!
    var captures;
    if (captures = /^@css *\{/.exec(this.str)) {
      this.skip(captures);
      var c
        , braces = 1
        , css = '';
      while (c = this.str[0]) {
        this.str = this.str.substr(1);
        switch (c) {
          case '{': ++braces; break;
          case '}': --braces; break;
        }
        css += c;
        if (!braces) break;
      }
      css = css.replace(/\s*}$/, '');
      return new Token('literal', new nodes.Literal(css));
    }
  },

  /**
   * '!important' ' '*
   */

  get important() {
    var captures;
    if (captures = /^!important */.exec(this.str)) {
      this.skip(captures);
      return new Token('ident', new nodes.Literal('!important'));
    }
  },

  /**
   * '{' | '}'
   */

  get brace() {
    var captures;
    if (captures = /^([{}])/.exec(this.str)) {
      this.skip(1);
      var brace = captures[1];
      return new Token(brace, brace);
    }
  },

  /**
   * '(' | ')' ' '*
   */

  get paren() {
    var captures;
    if (captures = /^([()]) */.exec(this.str)) {
      var paren = captures[1];
      this.skip(captures);
      if (')' == paren) this.isURL = false;
      return new Token(paren, paren);
    }
  },

  /**
   * 'null'
   */

  get null() {
    var captures;
    if (captures = /^(null)\b */.exec(this.str)) {
      this.skip(captures);
      return new Token('null', nodes.null);
    }
  },

  /**
   *   'if'
   * | 'else'
   * | 'unless'
   * | 'return'
   * | 'for'
   * | 'in'
   */

  get keyword() {
    var captures;
    if (captures = /^(return|if|else|unless|for|in)\b */.exec(this.str)) {
      var keyword = captures[1];
      this.skip(captures);
      return new Token(keyword, keyword);
    }
  },

  /**
   *   'not'
   * | 'and'
   * | 'or'
   * | 'is a'
   * | 'is defined'
   */

  get namedop() {
    var captures;
    if (captures = /^(not|and|or|is a|is defined)\b( *)/.exec(this.str)) {
      var op = captures[1];
      this.skip(captures);
      op = alias[op] || op;
      var tok = new Token(op, op);
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   *   ','
   * | '+'
   * | '+='
   * | '-'
   * | '-='
   * | '*'
   * | '*='
   * | '/'
   * | '/='
   * | '%'
   * | '%='
   * | '**'
   * | '!'
   * | '&&'
   * | '||'
   * | '>'
   * | '>='
   * | '<'
   * | '<='
   * | '='
   * | '=='
   * | '!='
   * | '!'
   * | '~'
   * | '?='
   * | '?'
   * | ':'
   * | '['
   * | ']'
   * | '..'
   * | '...'
   */

  get op() {
    var captures;
    if (captures = /^([.]{2,3}|&&|\|\||[!<>=?]=|\*\*|[-+*\/%]=?|[,=?:!~<>\[\]])( *)/.exec(this.str)) {
      var op = captures[1];
      this.skip(captures);
      op = alias[op] || op;
      var tok = new Token(op, op);
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   * '@media' ([^\n]+)
   */

  get media() {
    var captures;
    if (captures = /^@media *([^\n]+)/.exec(this.str)) {
      this.skip(captures);
      return new Token('media', captures[1]);
    }
  },

  /**
   * '@' ('import' | 'keyframes' | 'charset' | 'page')
   */

  get atrule() {
    var captures;
    if (captures = /^@(import|keyframes|charset|page) */.exec(this.str)) {
      this.skip(captures);
      return new Token(captures[1]);
    }
  },

  /**
   * '//' *
   */

  get comment() {
    // Single line
    if ('/' == this.str[0] && '/' == this.str[1]) {
      var end = this.str.indexOf('\n');
      if (-1 == end) end = this.str.length;
      this.skip(end);
      return this.advance;
    }

    // Multi-line
    if ('/' == this.str[0] && '*' == this.str[1]) {
      var end = this.str.indexOf('*/');
      if (-1 == end) end = this.str.length;
      var str = this.str.substr(0, end + 2)
        , lines = str.split('\n').length - 1;
      this.lineno += lines;
      this.skip(end + 2);
      return this.allowComments
        ? new Token('comment', str)
        : this.advance;
    }
  },

  /**
   * 'true' | 'false'
   */

  get boolean() {
    var captures;
    if (captures = /^(true|false)\b( *)/.exec(this.str)) {
      var val = 'true' == captures[1]
        ? nodes.true
        : nodes.false;
      this.skip(captures);
      var tok = new Token('boolean', val);
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   * -?[a-zA-Z] [-\w\d]* '('
   */

  get function() {
    var captures;
    if (captures = /^(-?[a-zA-Z][-\w\d]*)\(( *)/.exec(this.str)) {
      var name = captures[1];
      this.skip(captures);
      this.isURL = 'url' == name;
      var tok = new Token('function', new nodes.Ident(name));
      tok.space = captures[2];
      return tok;
    }
  },

  /**
   * -?[a-zA-Z] [-\w\d]*
   */

  get ident() {
    var captures;
    if (captures = /^(-?[a-zA-Z][-\w\d]*)/.exec(this.str)) {
      var name = captures[1];
      this.skip(captures);
      return new Token('ident', new nodes.Ident(name));
    }
  },

  /**
   * '\n' ' '+
   */

  get newline() {
    var captures;
    if (captures = /^\n( *)/.exec(this.str)) {
      var tok
        , spaces = captures[1].length
        , indents = spaces / 2;

      this.skip(captures);

      // Reset state
      this.isVariable = false;

      // Blank line
      if ('\n' == this.str[0]) {
        ++this.lineno;
        return this.advance;
      }

      // To few spaces
      if (0 != spaces % 2) {
        var str = 1 == spaces ? 'space' : 'spaces'
          , spaces = numberString[spaces] || spaces;
        throw new Error('Invalid indentation, got ' + spaces + ' ' + str + ' and expected multiple of two');
      // To many spaces
      } else if (indents > this.prevIndents + 1) {
        var str = 1 == spaces ? 'space' : 'spaces'
          , expected = 2 * (this.prevIndents * 2) || 2
          , expected = numberString[expected] || expected
          , spaces = numberString[spaces] || spaces;
        throw new Error('Invalid indentation, got ' + spaces + ' ' + str + ' and expected ' + expected);
      // Outdent
      } else if (indents < this.prevIndents) {
        var n = this.prevIndents - indents;
        while (--n) this.stash.push(new Token('outdent'));
        this.prevIndents = indents;
        tok = new Token('outdent');
      // Indent
      } else if (indents != this.prevIndents) {
        this.prevIndents = indents;
        tok = new Token('indent');
      // Newline
      } else {
        tok = new Token('newline');
      }

      return tok;
    }
  },

  /**
   * '-'? (digit+ | digit* '.' digit+) unit
   */

  get unit() {
    var captures;
    if (captures = unit.exec(this.str)) {
      this.skip(captures);
      var n = parseFloat(captures[2]);
      if ('-' == captures[1]) n = -n;
      var node = new nodes.Unit(n, captures[3]);
      return new Token('unit', node);
    }
  },

  /**
   * '"' [^"]+ '"' | "'"" [^']+ "'"
   */

  get string() {
    var captures;

    // url() special case
    if (this.isURL && (captures = /^([^'"][^)]+) */.exec(this.str))) {
      this.skip(captures);
      return new Token('string', new nodes.String(captures[1]));
    }

    // Regular string
    if (captures = /^("[^"]*"|'[^']*') */.exec(this.str)) {
      var str = captures[1];
      this.skip(captures);
      return new Token('string', new nodes.String(str.slice(1,-1)));
    }
  },

  /**
   * #nnnnnn | #nnn
   */

  get color() {
    return this.hex6 || this.hex3;
  },

  /**
   * #nnn
   */

  get hex3() {
    var captures;
    if (captures = /^#([a-f-A-F0-9]{3}) */.exec(this.str)) {
      this.skip(captures);
      var rgb = captures[1]
        , r = parseInt(rgb[0] + rgb[0], 16)
        , g = parseInt(rgb[1] + rgb[1], 16)
        , b = parseInt(rgb[2] + rgb[2], 16);
      return new Token('color', new nodes.Color(r, g, b, 1));
    }
  },

  /**
   * #nnnnnn
   */

  get hex6() {
    var captures;
    if (captures = /^#([a-f-A-F0-9]{6}) */.exec(this.str)) {
      this.skip(captures);
      var rgb = captures[1]
        , r = parseInt(rgb.substr(0, 2), 16)
        , g = parseInt(rgb.substr(2, 2), 16)
        , b = parseInt(rgb.substr(4, 2), 16);
      return new Token('color', new nodes.Color(r, g, b, 1));
    }
  },

  /**
   * [^\n,;]+
   */

  get selector() {
    var captures;
    if (captures = /^[^\n,]+/.exec(this.str)) {
      var selector = captures[0];
      this.skip(captures);
      return new Token('selector', selector);
    }
  }
};
<|endoftext|>


<commit_before>$(document).ready(function() {
    // Remove the last updated
    $('p').last().detach();

    // Hide the search. CSS wouldn't do it...
    $('.navbar-form').hide();
    $('.navbar-toggle').detach();

    // Turn the first header section into a hero
    var first_section = $('.section').first();
    first_section.addClass('jumbotron');

    // Add a link to the PDF by abusing the Back to Top link
    var pdf_link = $('.footer .pull-right a');
    // Set the new text for the link
    pdf_link.empty();
    pdf_link.append($(''));
    pdf_link.append(' Download PDF');
    // Set the link and open in a new window
    pdf_link.attr('href', 'resume.pdf');
    pdf_link.attr('target', '_blank');

    // Make Employment section sexy
    $('#employment > ul').children('li').each(function (i_job, job) {
      job = $(job);
      // E.g. ( YYYY-YYYY ) | Job Title | Company
      var job_text_array = job.text().split('\n');
      var btn_name = '';
      var job_banner = [];
      $(job_text_array[0].split('|')).each(function (i_job_info, job_info) {
        switch ( i_job_info ) {
          // Years
          case 0:
            // Cleanup the parens
            job_info = job_info.replace(/[\(\)]/g, '');
            if ( i_job === 0 ) {
              // Highlight the current job
              btn_name = 'danger';
            } else {
              btn_name = 'primary';
            }
            break;
          // Job Title
          case 1:
            btn_name = 'default';
            break;
          // Company
          case 2:
            btn_name = 'success';
            break;
          default:
            btn_name = '';
            console.error('Unknown case. i: ' + i + ' job_info: ' + job_info);
        }
        // Now create the element and add it to the list
        btn = $('');
        btn.text(job_info.trim());
        job_banner.push(btn);
      });
      // Get rid of the line we just turned into a header
      job.find('p.first').detach();
      // Create a new element to attach
      var pretty_job = $('
');
      // Add the stylized job header info
      pretty_job.append($('
').append(job_banner));
      pretty_job.append($('
').append(job.contents()));
      // Add to the section and remove li
      $('#employment').append(pretty_job);
      job.detach();
    });

});
<commit_msg>make current orange. red for past.<commit_after>$(document).ready(function() {
    // Remove the last updated
    $('p').last().detach();

    // Hide the search. CSS wouldn't do it...
    $('.navbar-form').hide();
    $('.navbar-toggle').detach();

    // Turn the first header section into a hero
    var first_section = $('.section').first();
    first_section.addClass('jumbotron');

    // Add a link to the PDF by abusing the Back to Top link
    var pdf_link = $('.footer .pull-right a');
    // Set the new text for the link
    pdf_link.empty();
    pdf_link.append($(''));
    pdf_link.append(' Download PDF');
    // Set the link and open in a new window
    pdf_link.attr('href', 'resume.pdf');
    pdf_link.attr('target', '_blank');

    // Make Employment section sexy
    $('#employment > ul').children('li').each(function (i_job, job) {
      job = $(job);
      // E.g. ( YYYY-YYYY ) | Job Title | Company
      var job_text_array = job.text().split('\n');
      var btn_name = '';
      var job_banner = [];
      $(job_text_array[0].split('|')).each(function (i_job_info, job_info) {
        switch ( i_job_info ) {
          // Years
          case 0:
            // Cleanup the parens
            job_info = job_info.replace(/[\(\)]/g, '');
            if ( i_job === 0 ) {
              // Highlight the current job
              btn_name = 'primary';
            } else {
              btn_name = 'danger';
            }
            break;
          // Job Title
          case 1:
            btn_name = 'default';
            break;
          // Company
          case 2:
            btn_name = 'success';
            break;
          default:
            btn_name = '';
            console.error('Unknown case. i: ' + i + ' job_info: ' + job_info);
        }
        // Now create the element and add it to the list
        btn = $('');
        btn.text(job_info.trim());
        job_banner.push(btn);
      });
      // Get rid of the line we just turned into a header
      job.find('p.first').detach();
      // Create a new element to attach
      var pretty_job = $('
');
      // Add the stylized job header info
      pretty_job.append($('
').append(job_banner));
      pretty_job.append($('
').append(job.contents()));
      // Add to the section and remove li
      $('#employment').append(pretty_job);
      job.detach();
    });

});
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var passport = require('passport');
var envs = require('envs');
var OAuthStrategy = require('passport-oauth2').Strategy;

/**
 * Expose the simple auth methods
 */

module.exports = SimpleAuth;

function SimpleAuth(opts) {
  if (!(this instanceof SimpleAuth)) return new SimpleAuth(opts);
  this.opts = opts || {};
  this.name = this.opts.name || 'random name';
  this.register(this.opts);
};

SimpleAuth.prototype.register = function(opts) {
  var AUTH_URL = opts.authURL || envs('AUTH_URL');
  var AUTHORIZATION_URL = AUTH_URL + (opts.authorizationPath || '/authorize');
  var TOKEN_URL = AUTH_URL + (opts.tokenPath || '/token');

  var strategy = new OAuthStrategy({
    clientID: envs('OAUTH_CLIENT_ID'),
    clientSecret: envs('OAUTH_CLIENT_SECRET'),
    authorizationURL: AUTHORIZATION_URL,
    tokenURL: TOKEN_URL,
    skipUserProfile: true
  },
  function(accessToken, refreshToken, profile, done) {
    profile = profile || {};
    profile.accessToken = accessToken;
    profile.refreshToken = refreshToken;
    done(null, profile);
  });

  strategy.name = this.name;
  strategy._host = opts.host;

  var _authenticate = strategy.authenticate;
  strategy.authenticate = function(req, options) {
    options = options || {};

    this._oauth2._baseSite = options.host || this._host;
    _authenticate.apply(this, arguments);
  };

  passport.use(strategy);
};

SimpleAuth.prototype.login = function(options) {
  var self = this;
  options = options || {};

  return function (req, res, next) {
    // If they're already signed in, don't do anything
    if (req.cookies._access_token) return next();

    // Setup the options for passport
    options.callbackURL = req.base + '/auth/callback';
    options.state = (req.get('referrer') || '/');
    options.host = req.get('x-auth-url');

    // Profile the call
    var done = req.metric.profile('login');

    return passport.authenticate(self.name, options, function(err, profile) {
      // End profiling
      done();

      // We've got an error
      if (err) return next(err);

      // TODO handle oauth errors - like access denied
      if (!profile.accessToken) return res.redirect(req.query.state);

      // Expose the profile
      req.user = profile;

      // Expose the access token
      // TODO set the expiration based on what the auth app told us
      res.cookie('_access_token', profile.accessToken, {
        secure: ~req.base.indexOf('https://')
      });

      res.redirect(req.query.state);
    })(req, res, next);
  };
};

SimpleAuth.prototype.logout = function() {
  return function(req, res, next) {
    // Clear the access token
    res.clearCookie('_access_token', {
      secure: ~req.base.indexOf('https://')
    });

    res.redirect((req.get('x-auth-url') || AUTH_URL) + '/logout');
  }
};

SimpleAuth.prototype.authenticate = function(restricted) {
  return restricted
    ? this.login()
    : noop;
};

function noop(req, res, next) {
  next();
};
<commit_msg>fix auth url<commit_after>/**
 * Module dependencies
 */

var passport = require('passport');
var envs = require('envs');
var OAuthStrategy = require('passport-oauth2').Strategy;

/**
 * Expose the simple auth methods
 */

module.exports = SimpleAuth;

function SimpleAuth(opts) {
  if (!(this instanceof SimpleAuth)) return new SimpleAuth(opts);
  this.opts = opts || {};
  this.name = this.opts.name || 'random name';
  this.register(this.opts);
};

SimpleAuth.prototype.register = function(opts) {
  var AUTH_URL = opts.authURL || envs('AUTH_URL');
  var AUTHORIZATION_URL = opts.authorizationPath || '/authorize';
  var TOKEN_URL = opts.tokenPath || '/token';

  var strategy = new OAuthStrategy({
    clientID: envs('OAUTH_CLIENT_ID'),
    clientSecret: envs('OAUTH_CLIENT_SECRET'),
    authorizationURL: AUTHORIZATION_URL,
    tokenURL: TOKEN_URL,
    skipUserProfile: true
  },
  function(accessToken, refreshToken, profile, done) {
    profile = profile || {};
    profile.accessToken = accessToken;
    profile.refreshToken = refreshToken;
    done(null, profile);
  });

  strategy.name = this.name;
  strategy._host = AUTH_URL;

  var _authenticate = strategy.authenticate;
  strategy.authenticate = function(req, options) {
    options = options || {};

    this._oauth2._baseSite = options.host || this._host;
    _authenticate.apply(this, arguments);
  };

  passport.use(strategy);
};

SimpleAuth.prototype.login = function(options) {
  var self = this;
  options = options || {};

  return function (req, res, next) {
    // If they're already signed in, don't do anything
    if (req.cookies._access_token) return next();

    // Setup the options for passport
    options.callbackURL = req.base + '/auth/callback';
    options.state = (req.get('referrer') || '/');
    options.host = req.get('x-auth-url');

    // Profile the call
    var done = req.metric.profile('login');

    return passport.authenticate(self.name, options, function(err, profile) {
      // End profiling
      done();

      // We've got an error
      if (err) return next(err);

      // TODO handle oauth errors - like access denied
      if (!profile.accessToken) return res.redirect(req.query.state);

      // Expose the profile
      req.user = profile;

      // Expose the access token
      // TODO set the expiration based on what the auth app told us
      res.cookie('_access_token', profile.accessToken, {
        secure: ~req.base.indexOf('https://')
      });

      res.redirect(req.query.state);
    })(req, res, next);
  };
};

SimpleAuth.prototype.logout = function() {
  return function(req, res, next) {
    // Clear the access token
    res.clearCookie('_access_token', {
      secure: ~req.base.indexOf('https://')
    });

    res.redirect((req.get('x-auth-url') || AUTH_URL) + '/logout');
  }
};

SimpleAuth.prototype.authenticate = function(restricted) {
  return restricted
    ? this.login()
    : noop;
};

function noop(req, res, next) {
  next();
};
<|endoftext|>


<commit_before>// Load JS Library in JS
function getScript(url,success) {
  var script=document.createElement('script');
  script.src=url;
  var head=document.getElementsByTagName('head')[0],
  done=false;script.onload=script.onreadystatechange=function(){
    if(!done&&(!this.readyState||this.readyState=='loaded'||this.readyState=='complete')){
    done=true;success();script.onload=script.onreadystatechange=null;head.removeChild(script);
    }
  };
  head.appendChild(script);
}

// Load Latest, Compressed jQuery
getScript('http://code.jquery.com/jquery-latest.min.js',function(){
  return win();
});

// Rek Scrubz
function win() {
  console.log($('div.nonHideableWords').text());
  chars = text.length;
  arrText = text.split(' ');
  arrLength = arrText.length;
  timeRemaining = (((chars/5)*60)/190)*1000;
  delay = timeRemaining/arrLength;
  for (var i = 0; i < arrLength; i++) {
    sleep(delay);
    $('.txtInput').val(arrText[i]).trigger({type : 'keypress', which : 32});
  }
}

function sleep(milliseconds) {
  var start = new Date().getTime();
}
<commit_msg>loop till break<commit_after>// Load JS Library in JS
function getScript(url,success) {
  var script=document.createElement('script');
  script.src=url;
  var head=document.getElementsByTagName('head')[0],
  done=false;script.onload=script.onreadystatechange=function(){
    if(!done&&(!this.readyState||this.readyState=='loaded'||this.readyState=='complete')){
    done=true;success();script.onload=script.onreadystatechange=null;head.removeChild(script);
    }
  };
  head.appendChild(script);
}

// Load Latest, Compressed jQuery
getScript('http://code.jquery.com/jquery-latest.min.js',function(){
  return win();
});

// Rek Scrubz
function win() {
  console.log($('div.nonHideableWords').text());
  chars = text.length;
  arrText = text.split(' ');
  arrLength = arrText.length;
  timeRemaining = (((chars/5)*60)/190)*1000;
  delay = timeRemaining/arrLength;
  for (var i = 0; i < arrLength; i++) {
    sleep(delay);
    $('.txtInput').val(arrText[i]).trigger({type : 'keypress', which : 32});
  }
}

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
<|endoftext|>


<commit_before>/**
 * @module
 * @name Errors
 * @description module containing all the errors specified by XTENS
 */
/* jshint esnext: true */
/* jshint node: true */
"use strict";

/**
 * @class
 * @name InvalidFormatError
 * @description Invalid Format error
 */
class InvalidFormatError extends Error {

    constructor(message) {
        super();
        this.name = "InvalidFormatError";
        this.message = (message || "");
    }

}

/**
 * @class
 * @name TransactionError
 * @description Transaction error
 */
class TransactionError extends Error {

    constructor(message) {
        super();
        this.name = "TransactionError";
        this.message = (message || "");
    }

}

/**
 * @class
 * @name ValidationError
 * @description Validation error
 */
class ValidationError extends Error {

    constructor(message) {
        super();
        this.name = "ValidationError";
        this.message = message || "";
    }

}

/**
 * @class
 * @name PrivilegesError
 * @description Error for data type privileges
 */
 class PrivilegesError extends Error {
     constructor(message) {
         super();
         this.name = "PrivilegesError";
         this.message = message || "";
     }
 }

module.exports.InvalidFormatError = InvalidFormatError;
module.exports.TransactionError = TransactionError;
module.exports.ValidationError = ValidationError;
module.exports.PrivilegesError = PrivilegesError;
<commit_msg>added non existent resource error<commit_after>/**
 * @module
 * @name Errors
 * @description module containing all the errors specified by XTENS
 */
/* jshint esnext: true */
/* jshint node: true */
"use strict";

/**
 * @class
 * @name InvalidFormatError
 * @description Invalid Format error
 */
class InvalidFormatError extends Error {

    constructor(message) {
        super();
        this.name = "InvalidFormatError";
        this.message = (message || "");
    }

}

/**
 * @class
 * @name TransactionError
 * @description Transaction error
 */
class TransactionError extends Error {

    constructor(message) {
        super();
        this.name = "TransactionError";
        this.message = (message || "");
    }

}

/**
 * @class
 * @name ValidationError
 * @description Validation error
 */
class ValidationError extends Error {

    constructor(message) {
        super();
        this.name = "ValidationError";
        this.message = message || "";
    }

}

/**
 * @class
 * @name PrivilegesError
 * @description Error for data type privileges
 */
 class PrivilegesError extends Error {
     constructor(message) {
         super();
         this.name = "PrivilegesError";
         this.message = message || "";
     }
 }

 /**
  * @class
  * @name PrivilegesError
  * @description Error for data type privileges
  */
  class NonexistentResourceError extends Error {
      constructor(message) {
          super();
          this.name = "NonexistentResourceError";
          this.message = message || "";
      }
  }

module.exports.InvalidFormatError = InvalidFormatError;
module.exports.TransactionError = TransactionError;
module.exports.ValidationError = ValidationError;
module.exports.PrivilegesError = PrivilegesError;
module.exports.NonexistentResourceError = NonexistentResourceError;
<|endoftext|>


<commit_before>'use strict';

/**
  * Module depedencies.
  */

var mongoose = require('mongoose'),
  Project = mongoose.model('Project');

exports.all = function (req, res) {
	Project.find().exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});
};

exports.show = function (req, res) {
	var project_id = req.params.project_id;
	console.log('project_id ' + project_id);
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	}); //MONGODB

};

exports.edit = function (req, res) {
	var project_id = req.params.project_id;
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result, 'Successfully edited phase');
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});

};

exports.addProject = function (req, res) {
  var project = new Project();
  project.name = req.body.name;
  if (req.body.startDate) project.startDate = req.body.startDate;
  project.endDate = req.body.endDate;
  project.phases = [];
  project.owner = req.body.owner;
  project.members = req.body.members;
  project.messages = [];
  project.save();
  return res.status(201).json(project);
};

exports.remove = function (req, res) {
    var project = Project.findOne({'id': req.params.project_id});
    var owner = Project.owner
    	if (req.user.id === owner)
	  project.remove()
	  .exec(function(err) {
	  	if (err) return res.status(400).send(err);
	  	else return res.status(200).send('Test database cleared.');
	  });
};

<commit_msg>had an error, fixed<commit_after>'use strict';

/**
  * Module depedencies.
  */

var mongoose = require('mongoose'),
  Project = mongoose.model('Project');

exports.all = function (req, res) {
	Project.find().exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});
};

exports.show = function (req, res) {
	var project_id = req.params.project_id;
	console.log('project_id ' + project_id);
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result);
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	}); //MONGODB

};

exports.edit = function (req, res) {
	var project_id = req.params.project_id;
	Project.findOne( {'_id': project_id} ).exec(function(err, result) {
		if (!err) {
			return res.json(200, result, 'Successfully edited phase');
		}
		else {
			return res.json('Get real bro');
		}
		console.log('project ' + result);
	});

};

exports.addProject = function (req, res) {
  var project = new Project();
  project.name = req.body.name;
  if (req.body.startDate) project.startDate = req.body.startDate;
  project.endDate = req.body.endDate;
  project.phases = [];
  project.owner = req.body.owner;
  project.members = req.body.members;
  project.messages = [];
  project.save();
  return res.status(201).json(project);
};

exports.remove = function (req, res) {
    var project = Project.findOne({'id': req.params.project_id});
    var owner = project.owner;
    	if (req.user.id === owner)
	  project.remove()
	  .exec(function(err) {
	  	if (err) return res.status(400).send(err);
	  	else return res.status(200).send('Test database cleared.');
	  });
};

<|endoftext|>


<commit_before>'use strict';

var src = [
    '*.json',
    '.jshintrc',
    '.jslintrc',
    '.jsbeautifyrc',
    '.bithoundrc',
    'project/**/*.json',
    '<%=buildConfig.testDirectory%>/**/*.json'
];

/*istanbul ignore else*/
if (global.build.options.buildConfig.nodeProject) {
    src.push('<%=buildConfig.libDirectory%>/**/*.json');
}

/**
 * JSONLint task definition.
 *
 * @author Sagie Gur-Ari
 * @namespace GruntJSONLint
 * @private
 */
module.exports.tasks = {
    jsonlint: {
        full: {
            src: src
        },
        format: {
            src: src,
            options: {
                format: true,
                indent: 2
            }
        }
    }
};
<commit_msg>cleanups<commit_after>'use strict';

var src = [
    '*.json',
    '.jshintrc',
    '.jslintrc',
    '.jsbeautifyrc',
    'project/**/*.json',
    '<%=buildConfig.testDirectory%>/**/*.json'
];

/*istanbul ignore else*/
if (global.build.options.buildConfig.nodeProject) {
    src.push('<%=buildConfig.libDirectory%>/**/*.json');
}

/**
 * JSONLint task definition.
 *
 * @author Sagie Gur-Ari
 * @namespace GruntJSONLint
 * @private
 */
module.exports.tasks = {
    jsonlint: {
        full: {
            src: src
        },
        format: {
            src: src,
            options: {
                format: true,
                indent: 2
            }
        }
    }
};
<|endoftext|>


<commit_before>import { E2EGlobal } from './helpers/E2EGlobal'
import { E2EApp } from './helpers/E2EApp'
import { E2EMeetingSeries } from './helpers/E2EMeetingSeries'
import { E2EMinutes } from './helpers/E2EMinutes'
import { E2ETopics } from './helpers/E2ETopics'

describe('MeetingSeries complete Topic list', function () {
    const aProjectName = "MeetingSeries Topic List";
    let aMeetingCounter = 0;
    let aMeetingNameBase = "Meeting Name #";
    let aMeetingName;

    beforeEach("goto start page and make sure test user is logged in", function () {
        E2EApp.gotoStartPage();
        expect(browser.getTitle()).to.equal('4minitz!');
        expect(E2EApp.isLoggedIn()).to.be.true;

        aMeetingCounter++;
        aMeetingName = aMeetingNameBase + aMeetingCounter;

        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
    });

    after("clear database", function () {
        if (E2EGlobal.browserIsPhantomJS()) {
            E2EApp.resetMyApp(true);
        }
    });

    it("copies all topics of the first minute to the parent series including both all info- and actionItems.", function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.countTopicsForMinute(), "Meeting Series should have one topic").to.equal(1);

        expect(E2ETopics.countItemsForTopic(1), "Topic should have two items").to.equal(2);

        let items = E2ETopics.getItemsForTopic(1);
        let firstItemElement = items[0].ELEMENT;
        expect(browser.elementIdText(firstItemElement).value, "fist element should be the action item").to.have.string('some action item');

        let sndElement = items[1].ELEMENT;
        expect(browser.elementIdText(sndElement).value, "2nd element should be the info item").to.have.string('some information');
    });

    it('closes the topic if it were discussed and has no open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2ETopics.toggleActionItem(1, 1);
        E2ETopics.toggleTopic(1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should be closed").to.be.true;
    });

    it('remains the topic open if it were neither discussed nor has open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
    });

    it('remains the topic open if it were not discussed but has no open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2ETopics.toggleTopic(1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
    });

    it('remains the topic open if it were discussed but has open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2ETopics.toggleActionItem(1, 1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
    });

    describe('merge topics', function () {

        beforeEach('Create and finalize a first minute', function() {
            E2ETopics.addTopicToMinutes('some topic');
            E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
            E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();
        });

        it('clears the topic list if the first minute will be un-finalized.', function() {
            E2EMinutes.gotoLatestMinutes();

            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute()).to.equal(0);
        });

        it("adds new topics and AIs/IIs to the topic list of the meeting series", function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            // add new items (AI and II) to existing topic
            E2ETopics.addInfoItemToTopic({subject: 'some other information'}, 1);
            E2ETopics.addInfoItemToTopic({subject: 'some other action item', itemType: "actionItem"}, 1);

            // add a new topic
            E2ETopics.addTopicToMinutes('some other topic');
            E2ETopics.addInfoItemToTopic({subject: 'with information'}, 1);
            E2ETopics.addInfoItemToTopic({subject: 'with an action item', itemType: "actionItem"}, 1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute(), "Meeting Series should have now two topics").to.equal(2);

            // check the first topic (this should be the new one)
            expect(E2ETopics.countItemsForTopic(1), "New Topic should have two items").to.equal(2);
            let itemsOfNewTopic = E2ETopics.getItemsForTopic(1);
            let firstItemOfNewTopic = itemsOfNewTopic[0].ELEMENT;
            expect(browser.elementIdText(firstItemOfNewTopic).value, "first item of new topic should be the action item")
                .to.have.string('with an action item');
            let sndItemOfNewTopic = itemsOfNewTopic[1].ELEMENT;
            expect(browser.elementIdText(sndItemOfNewTopic).value, "2nd item of new topic should be the info item")
                .to.have.string('with information');

            // check the 2nd topic (the merged one)
            expect(E2ETopics.countItemsForTopic(2), "Merged Topic should now have four items").to.equal(4);
        });

        it('closes an existing open AI but remains the topic open if it were not discussed', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.toggleActionItem(1, 1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute(), "Meeting Series should still have only one topic").to.equal(1);

            expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
            expect(E2ETopics.isActionItemClosed(1, 1), "AI should be closed").to.be.true;

        });

        it('closes an existing open AI and closes the topic if it were discussed', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.toggleActionItem(1, 1);
            E2ETopics.toggleTopic(1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute(), "Meeting Series should still have only one topic").to.equal(1);

            expect(E2ETopics.isTopicClosed(1), "Topic should be closed").to.be.true;
            expect(E2ETopics.isActionItemClosed(1, 1), "AI should be closed").to.be.true;
        });

        it('changes the properties (subject/responsible) of an existing Topic', function () {
            const newTopicSubject = "changed topic subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editTopicForMinutes(1, newTopicSubject, newResponsible);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let topicItems = E2ETopics.getTopicsForMinute();
            let topicEl = topicItems[0].ELEMENT;
            expect(browser.elementIdText(topicEl).value, "the topic subject should have changed").to.have.string(newTopicSubject);
            expect(browser.elementIdText(topicEl).value, "the topic responsible should have changed").to.have.string(newResponsible);
        });

        it('reverts property changes (subject/responsible) of a Topic if the minute will be un-finalized', function () {
            const newTopicSubject = "changed topic subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editTopicForMinutes(1, newTopicSubject, newResponsible);

            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let topicItems = E2ETopics.getTopicsForMinute();
            let topicEl = topicItems[0].ELEMENT;
            expect(browser.elementIdText(topicEl).value, "the topic subject should have changed").to.not.have.string(newTopicSubject);
            expect(browser.elementIdText(topicEl).value, "the topic responsible should have changed").to.not.have.string(newResponsible);
        });

        it('changes the properties (subject/responsible) of an existing AI @watch', function () {
            const newSubject = "changed action item subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editInfoItemForTopic(1, 1, { subject: newSubject, responsible: newResponsible });

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value, "the action item subject should have changed").to.have.string(newSubject);
            expect(browser.elementIdText(firstItemElement).value, "the action item responsible should have changed").to.have.string("Resp: " + newResponsible);
        });

        it('reverts property changes (subject/responsible) of an AI if the minute will be un-finalized', function () {
            const newSubject = "changed action item subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editInfoItemForTopic(1, 1, { subject: newSubject, responsible: newResponsible });

            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value, "the action item subject should have changed").to.not.have.string(newSubject);
            expect(browser.elementIdText(firstItemElement).value, "the action item responsible should have changed").to.not.have.string("Resp: " + newResponsible);
        });

        it('removes the is-New-Flag of an existing topic after finalizing the 2nd minute', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value).to.not.have.string("New");
        });

        it('restores the is-New-Flag of an existing topic after un-finalizing the 2nd minute', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value).to.have.string("New");
        });

    });

});<commit_msg>E2E-Tests: Removed watch-flag.<commit_after>import { E2EGlobal } from './helpers/E2EGlobal'
import { E2EApp } from './helpers/E2EApp'
import { E2EMeetingSeries } from './helpers/E2EMeetingSeries'
import { E2EMinutes } from './helpers/E2EMinutes'
import { E2ETopics } from './helpers/E2ETopics'

describe('MeetingSeries complete Topic list', function () {
    const aProjectName = "MeetingSeries Topic List";
    let aMeetingCounter = 0;
    let aMeetingNameBase = "Meeting Name #";
    let aMeetingName;

    beforeEach("goto start page and make sure test user is logged in", function () {
        E2EApp.gotoStartPage();
        expect(browser.getTitle()).to.equal('4minitz!');
        expect(E2EApp.isLoggedIn()).to.be.true;

        aMeetingCounter++;
        aMeetingName = aMeetingNameBase + aMeetingCounter;

        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
    });

    after("clear database", function () {
        if (E2EGlobal.browserIsPhantomJS()) {
            E2EApp.resetMyApp(true);
        }
    });

    it("copies all topics of the first minute to the parent series including both all info- and actionItems.", function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.countTopicsForMinute(), "Meeting Series should have one topic").to.equal(1);

        expect(E2ETopics.countItemsForTopic(1), "Topic should have two items").to.equal(2);

        let items = E2ETopics.getItemsForTopic(1);
        let firstItemElement = items[0].ELEMENT;
        expect(browser.elementIdText(firstItemElement).value, "fist element should be the action item").to.have.string('some action item');

        let sndElement = items[1].ELEMENT;
        expect(browser.elementIdText(sndElement).value, "2nd element should be the info item").to.have.string('some information');
    });

    it('closes the topic if it were discussed and has no open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2ETopics.toggleActionItem(1, 1);
        E2ETopics.toggleTopic(1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should be closed").to.be.true;
    });

    it('remains the topic open if it were neither discussed nor has open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
    });

    it('remains the topic open if it were not discussed but has no open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2ETopics.toggleTopic(1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
    });

    it('remains the topic open if it were discussed but has open AI', function () {
        E2ETopics.addTopicToMinutes('some topic');
        E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
        E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

        E2ETopics.toggleActionItem(1, 1);

        E2EMinutes.finalizeCurrentMinutes();

        E2EMinutes.gotoParentMeetingSeries();

        E2EMeetingSeries.gotoTabTopics();

        expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
    });

    describe('merge topics', function () {

        beforeEach('Create and finalize a first minute', function() {
            E2ETopics.addTopicToMinutes('some topic');
            E2ETopics.addInfoItemToTopic({subject: 'some information'}, 1);
            E2ETopics.addInfoItemToTopic({subject: 'some action item', itemType: "actionItem"}, 1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();
        });

        it('clears the topic list if the first minute will be un-finalized.', function() {
            E2EMinutes.gotoLatestMinutes();

            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute()).to.equal(0);
        });

        it("adds new topics and AIs/IIs to the topic list of the meeting series", function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            // add new items (AI and II) to existing topic
            E2ETopics.addInfoItemToTopic({subject: 'some other information'}, 1);
            E2ETopics.addInfoItemToTopic({subject: 'some other action item', itemType: "actionItem"}, 1);

            // add a new topic
            E2ETopics.addTopicToMinutes('some other topic');
            E2ETopics.addInfoItemToTopic({subject: 'with information'}, 1);
            E2ETopics.addInfoItemToTopic({subject: 'with an action item', itemType: "actionItem"}, 1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute(), "Meeting Series should have now two topics").to.equal(2);

            // check the first topic (this should be the new one)
            expect(E2ETopics.countItemsForTopic(1), "New Topic should have two items").to.equal(2);
            let itemsOfNewTopic = E2ETopics.getItemsForTopic(1);
            let firstItemOfNewTopic = itemsOfNewTopic[0].ELEMENT;
            expect(browser.elementIdText(firstItemOfNewTopic).value, "first item of new topic should be the action item")
                .to.have.string('with an action item');
            let sndItemOfNewTopic = itemsOfNewTopic[1].ELEMENT;
            expect(browser.elementIdText(sndItemOfNewTopic).value, "2nd item of new topic should be the info item")
                .to.have.string('with information');

            // check the 2nd topic (the merged one)
            expect(E2ETopics.countItemsForTopic(2), "Merged Topic should now have four items").to.equal(4);
        });

        it('closes an existing open AI but remains the topic open if it were not discussed', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.toggleActionItem(1, 1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute(), "Meeting Series should still have only one topic").to.equal(1);

            expect(E2ETopics.isTopicClosed(1), "Topic should remain open").to.be.false;
            expect(E2ETopics.isActionItemClosed(1, 1), "AI should be closed").to.be.true;

        });

        it('closes an existing open AI and closes the topic if it were discussed', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.toggleActionItem(1, 1);
            E2ETopics.toggleTopic(1);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            expect(E2ETopics.countTopicsForMinute(), "Meeting Series should still have only one topic").to.equal(1);

            expect(E2ETopics.isTopicClosed(1), "Topic should be closed").to.be.true;
            expect(E2ETopics.isActionItemClosed(1, 1), "AI should be closed").to.be.true;
        });

        it('changes the properties (subject/responsible) of an existing Topic', function () {
            const newTopicSubject = "changed topic subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editTopicForMinutes(1, newTopicSubject, newResponsible);

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let topicItems = E2ETopics.getTopicsForMinute();
            let topicEl = topicItems[0].ELEMENT;
            expect(browser.elementIdText(topicEl).value, "the topic subject should have changed").to.have.string(newTopicSubject);
            expect(browser.elementIdText(topicEl).value, "the topic responsible should have changed").to.have.string(newResponsible);
        });

        it('reverts property changes (subject/responsible) of a Topic if the minute will be un-finalized', function () {
            const newTopicSubject = "changed topic subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editTopicForMinutes(1, newTopicSubject, newResponsible);

            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let topicItems = E2ETopics.getTopicsForMinute();
            let topicEl = topicItems[0].ELEMENT;
            expect(browser.elementIdText(topicEl).value, "the topic subject should have changed").to.not.have.string(newTopicSubject);
            expect(browser.elementIdText(topicEl).value, "the topic responsible should have changed").to.not.have.string(newResponsible);
        });

        it('changes the properties (subject/responsible) of an existing AI', function () {
            const newSubject = "changed action item subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editInfoItemForTopic(1, 1, { subject: newSubject, responsible: newResponsible });

            E2EMinutes.finalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value, "the action item subject should have changed").to.have.string(newSubject);
            expect(browser.elementIdText(firstItemElement).value, "the action item responsible should have changed").to.have.string("Resp: " + newResponsible);
        });

        it('reverts property changes (subject/responsible) of an AI if the minute will be un-finalized', function () {
            const newSubject = "changed action item subject";
            const newResponsible = "changed responsible";

            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);

            E2ETopics.editInfoItemForTopic(1, 1, { subject: newSubject, responsible: newResponsible });

            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value, "the action item subject should have changed").to.not.have.string(newSubject);
            expect(browser.elementIdText(firstItemElement).value, "the action item responsible should have changed").to.not.have.string("Resp: " + newResponsible);
        });

        it('removes the is-New-Flag of an existing topic after finalizing the 2nd minute', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value).to.not.have.string("New");
        });

        it('restores the is-New-Flag of an existing topic after un-finalizing the 2nd minute', function () {
            // add a second minute
            E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
            E2EMinutes.finalizeCurrentMinutes();
            E2EMinutes.unfinalizeCurrentMinutes();

            E2EMinutes.gotoParentMeetingSeries();

            E2EMeetingSeries.gotoTabTopics();

            let items = E2ETopics.getItemsForTopic(1);
            let firstItemElement = items[0].ELEMENT;
            expect(browser.elementIdText(firstItemElement).value).to.have.string("New");
        });

    });

});<|endoftext|>


<commit_before>module("View - Graph");

test('basics', function () {
  var dataset = Fixture.getDataset();
  var view = new recline.View.Graph({
    model: dataset
  });
  $('.fixtures').append(view.el);
  equal(view.state.get('graphType'), 'lines-and-points');
  // view will auto render ...
  assertPresent('.editor', view.elSidebar);
  view.remove();
});

test('initialize', function () {
  var dataset = Fixture.getDataset();
  var view = new recline.View.Graph({
    model: dataset,
    state: {
      'graphType': 'lines',
      'group': 'x',
      'series': ['y', 'z']
    }
  });
  $('.fixtures').append(view.el);
  equal(view.state.get('graphType'), 'lines');
  deepEqual(view.state.get('series'), ['y', 'z']);

  // check we have updated editor with state info
  equal(view.elSidebar.find('.editor-type select').val(), 'lines');
  equal(view.elSidebar.find('.editor-group select').val(), 'x');
  var out = _.map(view.elSidebar.find('.editor-series select'), function($el) {
    return $($el).val();
  });
  deepEqual(out, ['y', 'z']);

  view.remove();
});

test('dates in graph view', function () {
  expect(0);
  var dataset = Fixture.getDataset();
  var view = new recline.View.Graph({
    model: dataset,
    state: {
      'graphType': 'lines',
      'group': 'date',
      'series': ['y', 'z']
    }
  });
  $('.fixtures').append(view.el);

  view.remove();
});

test('GraphControls basics', function () {
  var dataset = Fixture.getDataset();
  var view = new recline.View.GraphControls({
    model: dataset,
    state: {
      graphType: 'bars',
      series: []
    }
  });
  $('.fixtures').append(view.el);
  equal(view.state.get('graphType'), 'bars');
  // view will auto render ...
  assertPresent('.editor', view.el);
  view.remove();
});

<commit_msg>Added test case for 'graphOptions'<commit_after>module("View - Graph");

test('basics', function () {
  var dataset = Fixture.getDataset();
  var view = new recline.View.Graph({
    model: dataset
  });
  $('.fixtures').append(view.el);
  equal(view.state.get('graphType'), 'lines-and-points');
  // view will auto render ...
  assertPresent('.editor', view.elSidebar);
  view.remove();
});

test('initialize', function () {
  var dataset = Fixture.getDataset();
  var view = new recline.View.Graph({
    model: dataset,
    state: {
      'graphType': 'lines',
      'group': 'x',
      'series': ['y', 'z']
    }
  });
  $('.fixtures').append(view.el);
  equal(view.state.get('graphType'), 'lines');
  deepEqual(view.state.get('series'), ['y', 'z']);

  // check we have updated editor with state info
  equal(view.elSidebar.find('.editor-type select').val(), 'lines');
  equal(view.elSidebar.find('.editor-group select').val(), 'x');
  var out = _.map(view.elSidebar.find('.editor-series select'), function($el) {
    return $($el).val();
  });
  deepEqual(out, ['y', 'z']);

  view.remove();
});

test('dates in graph view', function () {
  expect(0);
  var dataset = Fixture.getDataset();
  var view = new recline.View.Graph({
    model: dataset,
    state: {
      'graphType': 'lines',
      'group': 'date',
      'series': ['y', 'z']
    }
  });
  $('.fixtures').append(view.el);

  view.remove();
});

test('GraphControls basics', function () {
  var dataset = Fixture.getDataset();
  var view = new recline.View.GraphControls({
    model: dataset,
    state: {
      graphType: 'bars',
      series: []
    }
  });
  $('.fixtures').append(view.el);
  equal(view.state.get('graphType'), 'bars');
  // view will auto render ...
  assertPresent('.editor', view.el);
  view.remove();
});

test('Overriding graph options', function () {
  var dataset = Fixture.getDataset();
  var randomWidth = Math.random();
  var view = new recline.View.Graph({
    model: dataset,
    state: {
      'graphType': 'bars',
      'group': 'date',
      'series': ['y', 'z'],
      'graphOptions': { bars: {barWidth: randomWidth}}
    }
  });
  equal(view.getGraphOptions('bars').bars.barWidth, randomWidth)
  view.remove();
});<|endoftext|>


<commit_before>beforeEach(function () {
    if (!Array.isArray) {
        Array.isArray = function (arg) {
            return Object.prototype.toString.call(arg) === '[object Array]';
        };
    }

    this.addMatchers({
        toMatchStackFrame: function (expected) {
            var actual = this.actual;
            var message = '';
            if (actual.getFunctionName() !== expected[0]) {
                message += 'expected functionName: ' + actual.getFunctionName() + ' to equal ' + expected[0] + '\n';
            }
            if (Array.isArray(actual.getArgs()) && Array.isArray(expected[1])) {
                if (actual.getArgs().join() !== expected[1].join()) {
                    message += 'expected args: ' + actual.getArgs() + ' to equal ' + expected[1] + '\n';
                }
            } else if (actual.getArgs() !== expected[1]) {
                message += 'expected args: ' + actual.getArgs() + ' to equal ' + expected[1] + '\n';
            }
            if (actual.getFileName() !== expected[2]) {
                message += 'expected fileName: ' + actual.getFileName() + ' to equal ' + expected[2] + '\n';
            }
            if (actual.getLineNumber() !== expected[3]) {
                message += 'expected lineNumber: ' + actual.getLineNumber() + ' to equal ' + expected[3] + '\n';
            }
            if (actual.getColumnNumber() !== expected[4]) {
                message += 'expected columnNumber: ' + actual.getColumnNumber() + ' to equal ' + expected[4] + '\n';
            }
            this.message = function () {
                return message
            };
            return message === '';
        }
    });
});

<commit_msg>Fix Array matching in spec-helper.<commit_after>// Polyfill for old browsers
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if (!Array.isArray) {
    Array.isArray = function(arg) {
        return Object.prototype.toString.call(arg) === '[object Array]';
    };
}

beforeEach(function() {
    this.addMatchers({
        toMatchStackFrame: function(expected) {
            var actual = this.actual;
            var message = '';
            if (actual.getFunctionName() !== expected[0]) {
                message += 'expected functionName: ' + actual.getFunctionName() + ' to equal ' + expected[0] + '\n';
            }
            if (Array.isArray(actual.getArgs()) && Array.isArray(expected[1])) {
                if (actual.getArgs().join() !== expected[1].join()) {
                    message += 'expected args: ' + actual.getArgs() + ' to equal ' + expected[1] + '\n';
                }
            } else if (actual.getArgs() !== expected[1]) {
                message += 'expected args: ' + actual.getArgs() + ' to equal ' + expected[1] + '\n';
            }
            if (actual.getFileName() !== expected[2]) {
                message += 'expected fileName: ' + actual.getFileName() + ' to equal ' + expected[2] + '\n';
            }
            if (actual.getLineNumber() !== expected[3]) {
                message += 'expected lineNumber: ' + actual.getLineNumber() + ' to equal ' + expected[3] + '\n';
            }
            if (actual.getColumnNumber() !== expected[4]) {
                message += 'expected columnNumber: ' + actual.getColumnNumber() + ' to equal ' + expected[4] + '\n';
            }
            this.message = function() { return message };
            return message === '';
        }
    });
});

<|endoftext|>


<commit_before>import chalk from 'chalk';
import fetch from 'node-fetch';
import * as cfg from './cfg';
import { stringify as stringifyQuery } from 'querystring';
import { validate } from 'email-validator';
import readEmail from 'email-prompt';

async function getVerificationToken (url, email) {
  const data = JSON.stringify({ email });
  const res = await fetch(`${url}/now/registration`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': Buffer.byteLength(data)
    },
    body: data
  });

  if (200 !== res.status) {
    throw new Error('Verification error');
  }

  const body = await res.json();
  return body.token;
}

async function verify (url, email, verificationToken) {
  const query = {
    email,
    token: verificationToken
  };

  const res = await fetch(`${url}/now/registration/verify?${stringifyQuery(query)}`);
  const body = await res.json();
  return body.token;
}

function sleep (ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms);
  });
}

async function register (url, { retryEmail = false } = {}) {
  const email = await readEmail({ invalid: retryEmail });
  process.stdout.write('\n');

  if (!validate(email)) return register(url, { retryEmail: true });

  const verificationToken = await getVerificationToken(url, email);

  console.log(`> Please follow the link sent to ${chalk.bold(email)} to log in.`);
  process.stdout.write('> Waiting for confirmation..');

  let final;
  do {
    await sleep(2500);
    try {
      final = await verify(url, email, verificationToken);
    } catch (e) {}
    process.stdout.write('.');
  } while (!final);

  process.stdout.write('\n');

  return { email, token: final };
}

export default async function (url) {
  const loginData = await register(url);
  cfg.merge(loginData);
  return loginData.token;
}
<commit_msg>login: post tokenName<commit_after>import os from 'os';
import chalk from 'chalk';
import fetch from 'node-fetch';
import * as cfg from './cfg';
import { stringify as stringifyQuery } from 'querystring';
import { validate } from 'email-validator';
import readEmail from 'email-prompt';

async function getVerificationToken (url, email) {
  const tokenName = `Now CLI (${os.hostname()})`;
  const data = JSON.stringify({ email, tokenName });
  const res = await fetch(`${url}/now/registration`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': Buffer.byteLength(data)
    },
    body: data
  });

  if (200 !== res.status) {
    throw new Error('Verification error');
  }

  const body = await res.json();
  return body.token;
}

async function verify (url, email, verificationToken) {
  const query = {
    email,
    token: verificationToken
  };

  const res = await fetch(`${url}/now/registration/verify?${stringifyQuery(query)}`);
  const body = await res.json();
  return body.token;
}

function sleep (ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms);
  });
}

async function register (url, { retryEmail = false } = {}) {
  const email = await readEmail({ invalid: retryEmail });
  process.stdout.write('\n');

  if (!validate(email)) return register(url, { retryEmail: true });

  const verificationToken = await getVerificationToken(url, email);

  console.log(`> Please follow the link sent to ${chalk.bold(email)} to log in.`);
  process.stdout.write('> Waiting for confirmation..');

  let final;
  do {
    await sleep(2500);
    try {
      final = await verify(url, email, verificationToken);
    } catch (e) {}
    process.stdout.write('.');
  } while (!final);

  process.stdout.write('\n');

  return { email, token: final };
}

export default async function (url) {
  const loginData = await register(url);
  cfg.merge(loginData);
  return loginData.token;
}
<|endoftext|>


<commit_before>/* jshint unused:true, node:true */
"use strict";

var debug         = require('debug')('irc-client');
var util          = require('util');
var EventEmitter  = require('eventemitter3');
var carrier       = require('carrier');
var ircMessage    = require('irc-message');
var uuid          = require('uuid');

// The Client handles a single socket client,
// parses each line and emits an event when an
// IRC command is received.
function Client(socket) {
  EventEmitter.call(this);

  this.uuid = uuid.v1();

  this.socket = socket;
  this.socket.on('end',     this.disconnect.bind(this));
  this.socket.on('error',   this.disconnect.bind(this));
  this.socket.on('timeout', this.disconnect.bind(this));

  this.carry = carrier.carry(socket);
  this.carry.on('line', this.parse.bind(this));

  // TODO Get network and hostname from a config file
  this.hostname = 'irc.gitter.im';
  this.host     = ':' + this.hostname;

  this.nick = null;

  // By default the Client is not authenticated
  // and received commands are queued
  this.authenticated = false;
  this.queue = [];

  this.keepAlive();
}

util.inherits(Client, EventEmitter);

// https://tools.ietf.org/html/rfc2812#section-3.7.2
Client.prototype.keepAlive = function() {
  var pingInterval = 30 * 1000;
  var connectionTimeout = pingInterval * 2;

  function ping() {
    this.send('PING', this.hostname);
  }

  function refreshConnectionTimeout() {
    clearTimeout(this.connectionTimeout);
    this.connectionTimeout = setTimeout(this.disconnect.bind(this), connectionTimeout);
  }

  this.pingInterval = setInterval(ping.bind(this), pingInterval);
  this.connectionTimeout = setTimeout(this.disconnect.bind(this), connectionTimeout);

  this.on('PONG', refreshConnectionTimeout);
};

Client.prototype.parse = function(line) {
  debug('Rx: ' + line);
  var msg = ircMessage.parseMessage(line);
  if (this.authenticated || msg.command.match(/pass/i)) {
    this.emit.apply(this, [msg.command.toUpperCase()].concat(msg.params));
  } else {
    this.queue.push(msg);
  }
};

Client.prototype.authenticate = function(user) {
  this.nick = user.username;
  this.authenticated = true;
  this.queue.forEach(function(msg) {
    this.emit.apply(this, [msg.command.toUpperCase()].concat(msg.params));
  }.bind(this));
};

// https://tools.ietf.org/html/rfc1459#section-2.3
Client.prototype.send = function() {
  var args = Array.prototype.slice.call(arguments);
  var message = args.join(' ');

  // Respect IRC line length limit of 512 chars
  // https://tools.ietf.org/html/rfc2812#section-2.3
  if (message.length > 512) {
    var parts   = message.split(':');
    var command = parts[1];
    var payload = parts[2];

    var chunks = payload.split(' ');
    var chunk = [];
    var _chunk;
    while (chunks.length) {
      chunk.push(chunks.shift());
       _chunk = ':' + command + ':' + chunk.join(' ') + '\r\n';
      if (_chunk.length > 450 || !chunks.length) {
        debug('Tx: ' + _chunk);
        this.socket.write(_chunk);
        chunk = []; // start another chunk
      }
    }
  } else {
    debug('Tx: ' + message);
    this.socket.write(message + '\r\n');
  }
};

Client.prototype.mask = function() {
  return ':' + this.nick + '!' + this.nick + '@' + this.hostname;
};

Client.prototype.disconnect = function(opts) {
  opts = opts || {};

  if (opts.notify) {
    var mask = ':gitter!gitter@irc.gitter.im';
    this.send(mask, 'PRIVMSG', this.nick, ': Server restarting...');
  }

  this.socket.end();
  clearInterval(this.pingInterval);
  clearTimeout(this.connectionTimeout);
  this.emit('disconnected');
};

module.exports = Client;
<commit_msg>Reply to PINGs. Fixes #9<commit_after>/* jshint unused:true, node:true */
"use strict";

var debug         = require('debug')('irc-client');
var util          = require('util');
var EventEmitter  = require('eventemitter3');
var carrier       = require('carrier');
var ircMessage    = require('irc-message');
var uuid          = require('uuid');

// The Client handles a single socket client,
// parses each line and emits an event when an
// IRC command is received.
function Client(socket) {
  EventEmitter.call(this);

  this.uuid = uuid.v1();

  this.socket = socket;
  this.socket.on('end',     this.disconnect.bind(this));
  this.socket.on('error',   this.disconnect.bind(this));
  this.socket.on('timeout', this.disconnect.bind(this));

  this.carry = carrier.carry(socket);
  this.carry.on('line', this.parse.bind(this));

  // TODO Get network and hostname from a config file
  this.hostname = 'irc.gitter.im';
  this.host     = ':' + this.hostname;

  this.nick = null;

  // By default the Client is not authenticated
  // and received commands are queued
  this.authenticated = false;
  this.queue = [];

  this.keepAlive();
}

util.inherits(Client, EventEmitter);

// https://tools.ietf.org/html/rfc2812#section-3.7.2
Client.prototype.keepAlive = function() {
  var pingInterval = 30 * 1000;
  var connectionTimeout = pingInterval * 2;

  var ping = function() {
    this.send('PING', this.hostname);
  };

  var pong = function() {
    this.send('PONG', this.hostname);
  };

  var refreshConnectionTimeout = function() {
    clearTimeout(this.connectionTimeout);
    this.connectionTimeout = setTimeout(this.disconnect.bind(this), connectionTimeout);
  };

  this.pingInterval = setInterval(ping.bind(this), pingInterval);
  this.connectionTimeout = setTimeout(this.disconnect.bind(this), connectionTimeout);

  this.on('PONG', refreshConnectionTimeout.bind(this));
  this.on('PING', pong.bind(this));
};

Client.prototype.parse = function(line) {
  debug('Rx: ' + line);
  var msg = ircMessage.parseMessage(line);
  if (this.authenticated || msg.command.match(/pass/i)) {
    this.emit.apply(this, [msg.command.toUpperCase()].concat(msg.params));
  } else {
    this.queue.push(msg);
  }
};

Client.prototype.authenticate = function(user) {
  this.nick = user.username;
  this.authenticated = true;
  this.queue.forEach(function(msg) {
    this.emit.apply(this, [msg.command.toUpperCase()].concat(msg.params));
  }.bind(this));
};

// https://tools.ietf.org/html/rfc1459#section-2.3
Client.prototype.send = function() {
  var args = Array.prototype.slice.call(arguments);
  var message = args.join(' ');

  // Respect IRC line length limit of 512 chars
  // https://tools.ietf.org/html/rfc2812#section-2.3
  if (message.length > 512) {
    var parts   = message.split(':');
    var command = parts[1];
    var payload = parts[2];

    var chunks = payload.split(' ');
    var chunk = [];
    var _chunk;
    while (chunks.length) {
      chunk.push(chunks.shift());
       _chunk = ':' + command + ':' + chunk.join(' ') + '\r\n';
      if (_chunk.length > 450 || !chunks.length) {
        debug('Tx: ' + _chunk);
        this.socket.write(_chunk);
        chunk = []; // start another chunk
      }
    }
  } else {
    debug('Tx: ' + message);
    this.socket.write(message + '\r\n');
  }
};

Client.prototype.mask = function() {
  return ':' + this.nick + '!' + this.nick + '@' + this.hostname;
};

Client.prototype.disconnect = function(opts) {
  opts = opts || {};

  if (opts.notify) {
    var mask = ':gitter!gitter@irc.gitter.im';
    this.send(mask, 'PRIVMSG', this.nick, ': Server restarting...');
  }

  this.socket.end();
  clearInterval(this.pingInterval);
  clearTimeout(this.connectionTimeout);
  this.emit('disconnected');
};

module.exports = Client;
<|endoftext|>