<commit_before>'use strict';

var helpers = require('../helpers');

var operators = ['+', '-', '/', '*', '%', '<', '>', '==', '!=', '<=', '>='];

/**
 * Determine a relational operator based on the operator node
 *
 * @param {Object} node - The operator node
 * @returns {string} Returns a relational operator
 */
var getRelationalOperator = function (node) {
  if (node.content === '<') {
    return '<=';
  }

  if (node.content === '>') {
    return '>=';
  }
  return false;
};

/**
 * Determine if operator is negative number
 *
 * @param {string} operator - The operator
 * @param {Object} next - The next node
 * @param {Object} previous - The previous node
 * @param {Object} doublePrevious - The double previous node (back two)
 * @returns {bool} true / false
 */
var isNegativeNumber = function (operator, next, previous, doublePrevious) {
  if (operator === '-') {

    // Catch the following:
    // $foo: -20;
    if (!previous && !next.is('space')) {
      return true;
    }

    // Catch the following:
    // .foo {
    //   property: -16px;
    // }
    if (next.is('dimension') || next.is('percentage')) {
      return true;
    }

    // Catch the following:
    // .foo {
    //   propery: 2 / -16;
    // }
    if (doublePrevious && doublePrevious.is('operator')) {
      return true;
    }

    // Catch the following:
    // .foo {
    //   property: 2 /-16px;
    // }
    if (previous && previous.is('operator')) {
      return true;
    }
  }

  return false;
};

/**
 * Determine if operator is divider
 *
 * @param {string} operator - The operator
 * @param {Object} next - The next node
 * @param {Object} previous - The previous node
 * @returns {bool} true / false
 */
var isDivider = function (operator, next, previous) {
  if (operator === '/') {

    // Catch the following:
    // .foo {
    //   property: calc(100% / 2);
    // }
    if (previous && next) {
      if (previous.is('dimension') && (next.is('dimension') || next.is('number'))) {
        return true;
      }
    }
  }

  return false;
};

/**
 * Determine if operator is part of unicode
 *
 * @param {string} operator - The operator
 * @param {Object} previous - The previous node
 * @returns {bool} true / false
 */
var isUnicode = function (operator, previous) {
  if (operator === '+') {

    // Catch the following:
    // @font-face {
    //   unicode-range: U+26;
    // }
    if (previous.is('ident') && previous.content === 'U') {
      return true;
    }
  }

  return false;
};

/**
 * Determine if operator is part of import path
 *
 * @param {string} operator - The operator
 * @param {Object} parent - The parent node
 * @returns {bool} true / false
 */
var isImport = function (operator, parent) {
  if (operator === '/') {

    if (parent.is('atrule') && parent.contains('atkeyword')) {
      var keyword = parent.first('atkeyword');

      if (keyword.contains('ident')) {
        var ident = keyword.first('ident');

        if (ident.content === 'import') {
          return true;
        }
      }
    }
  }

  return false;
};

/**
 * Determine if operator is exception
 *
 * @param {string} operator - The operator
 * @param {Object} parent - The parent node
 * @param {Object} i - The node index
 * @returns {bool} true / false
 */
var isException = function (operator, parent, i) {
  var previous = parent.content[i - 1] || false,
      doublePrevious = parent.content[i - 2] || false,
      next = parent.content[i + 1] || false;

  if (isNegativeNumber(operator, next, previous, doublePrevious)) {
    return true;
  }

  if (isDivider(operator, next, previous)) {
    return true;
  }

  if (isUnicode(operator, previous)) {
    return true;
  }

  if (isImport(operator, parent)) {
    return true;
  }

  return false;
};

/**
 * Check the spacing around an operator
 *
 * @param {Object} node - The node to check the spacing around
 * @param {int} i - The node's child index of it's parent
 * @param {Object} parent - The parent node
 * @param {Object} parser - The parser object
 * @param {Object} result - The result object
 * @returns {bool|null} false if exception
 */
var checkSpacing = function (node, i, parent, parser, result) {
  if (node.is('operator') || node.is('unaryOperator')) {
    var previous = parent.content[i - 1] || false,
        next = parent.content[i + 1] || false,
        operator = node.content;

    //////////////////////////
    // Multi-part operators
    //////////////////////////

    // If second part of relational operator move on
    if (node.content === '=' && previous) {
      if (previous.content === '<' || previous.content === '>') {
        return false;
      }
    }

    // If first part of relational operator, carry on and build it
    if ((node.content === '<' || node.content === '>') && next) {
      if (next.content === '=') {
        operator = getRelationalOperator(node);
        next = parent.content[i + 2] || false;
      }
    }

    //////////////////////////
    // Exceptions
    //////////////////////////

    if (isException(operator, parent, i)) {
      return false;
    }

    // If the operator checks out in our valid operator list
    if (operators.indexOf(operator) !== -1) {

      if (parser.options.include) {
        if (
          (previous && !previous.is('space'))
          || (next && !next.is('space'))
        ) {
          result = helpers.addUnique(result, {
            'ruleId': parser.rule.name,
            'line': node.start.line,
            'column': node.start.column,
            'message': 'Space expected around operator',
            'severity': parser.severity
          });
        }
        else {
          if (
              (previous && (previous.end.line >= previous.start.line) && (previous.end.column > previous.start.column))
              || (next && (next.end.line >= next.start.line) && (next.end.column > next.start.column))
            ) {
            result = helpers.addUnique(result, {
              'ruleId': parser.rule.name,
              'line': node.start.line,
              'column': node.start.column,
              'message': 'Multiple spaces not allowed around operator',
              'severity': parser.severity
            });
          }
        }
      }
      else {
        if (
          (previous && previous.is('space'))
          || (next && next.is('space'))
        ) {
          result = helpers.addUnique(result, {
            'ruleId': parser.rule.name,
            'line': node.start.line,
            'column': node.start.column,
            'message': 'No spaces allowed around operator',
            'severity': parser.severity
          });
        }
      }
    }
  }
  return result;
};

module.exports = {
  'name': 'space-around-operator',
  'defaults': {
    'include': true
  },
  'detect': function (ast, parser) {
    var result = [];

    ast.traverseByTypes(['condition', 'atrule', 'value'], function (node) {
      node.forEach(function (item, i, parent) {
        // Perform another loop of the children if we come across a parenthesis
        // parent node
        if (item.is('parentheses')) {
          item.forEach(function (child, j, childParent) {
            // Do the spacing checks
            checkSpacing(child, j, childParent, parser, result);
          });
        }
        else {
          // Do the spacing checks
          checkSpacing(item, i, parent, parser, result);
        }
      });
    });

    return result;
  }
};
<commit_msg>:bug: Add ident exception for space-around-operator rule<commit_after>'use strict';

var helpers = require('../helpers');

var operators = ['+', '-', '/', '*', '%', '<', '>', '==', '!=', '<=', '>='];

/**
 * Determine a relational operator based on the operator node
 *
 * @param {Object} node - The operator node
 * @returns {string} Returns a relational operator
 */
var getRelationalOperator = function (node) {
  if (node.content === '<') {
    return '<=';
  }

  if (node.content === '>') {
    return '>=';
  }
  return false;
};

/**
 * Determine if operator is negative number
 *
 * @param {string} operator - The operator
 * @param {Object} next - The next node
 * @param {Object} previous - The previous node
 * @param {Object} doublePrevious - The double previous node (back two)
 * @returns {bool} true / false
 */
var isNegativeNumber = function (operator, next, previous, doublePrevious) {
  if (operator === '-') {

    // Catch the following:
    // $foo: -20;
    if (!previous && !next.is('space')) {
      return true;
    }

    // Catch the following:
    // .foo {
    //   property: -16px;
    // }
    if (next.is('dimension') || next.is('percentage')) {
      return true;
    }

    // Catch the following:
    // .foo {
    //   propery: 2 / -16;
    // }
    if (doublePrevious && doublePrevious.is('operator')) {
      return true;
    }

    // Catch the following:
    // .foo {
    //   property: 2 /-16px;
    // }
    if (previous && previous.is('operator')) {
      return true;
    }
  }

  return false;
};

/**
 * Determine if operator is divider
 *
 * @param {string} operator - The operator
 * @param {Object} next - The next node
 * @param {Object} previous - The previous node
 * @returns {bool} true / false
 */
var isDivider = function (operator, next, previous) {
  if (operator === '/') {

    // Catch the following:
    // .foo {
    //   property: calc(100% / 2);
    // }
    if (previous && next) {
      if (previous.is('dimension') && (next.is('dimension') || next.is('number'))) {
        return true;
      }
    }
  }

  return false;
};

/**
 * Determine if operator is part of unicode
 *
 * @param {string} operator - The operator
 * @param {Object} previous - The previous node
 * @returns {bool} true / false
 */
var isUnicode = function (operator, previous) {
  if (operator === '+') {

    // Catch the following:
    // @font-face {
    //   unicode-range: U+26;
    // }
    if (previous.is('ident') && previous.content === 'U') {
      return true;
    }
  }

  return false;
};

/**
 * Determine if operator is part of import path
 *
 * @param {string} operator - The operator
 * @param {Object} parent - The parent node
 * @returns {bool} true / false
 */
var isImport = function (operator, parent) {
  if (operator === '/') {

    if (parent.is('atrule') && parent.contains('atkeyword')) {
      var keyword = parent.first('atkeyword');

      if (keyword.contains('ident')) {
        var ident = keyword.first('ident');

        if (ident.content === 'import') {
          return true;
        }
      }
    }
  }

  return false;
};

/**
 * Determine if operator is part an ident
 *
 * @param {string} operator - The operator
 * @param {Object} next - The next node
 * @param {Object} previous - The previous node
 * @returns {bool} true / false
 */
var isPartialIdent = function (operator, next, previous) {
  return next.is('interpolation') && previous.is('interpolation');
};

/**
 * Determine if operator is exception
 *
 * @param {string} operator - The operator
 * @param {Object} parent - The parent node
 * @param {Object} i - The node index
 * @returns {bool} true / false
 */
var isException = function (operator, parent, i) {
  var previous = parent.content[i - 1] || false,
      doublePrevious = parent.content[i - 2] || false,
      next = parent.content[i + 1] || false;

  if (isNegativeNumber(operator, next, previous, doublePrevious)) {
    return true;
  }

  if (isDivider(operator, next, previous)) {
    return true;
  }

  if (isUnicode(operator, previous)) {
    return true;
  }

  if (isImport(operator, parent)) {
    return true;
  }

  if (isPartialIdent(operator, next, previous)) {
    return true;
  }

  return false;
};

/**
 * Check the spacing around an operator
 *
 * @param {Object} node - The node to check the spacing around
 * @param {int} i - The node's child index of it's parent
 * @param {Object} parent - The parent node
 * @param {Object} parser - The parser object
 * @param {Object} result - The result object
 * @returns {bool|null} false if exception
 */
var checkSpacing = function (node, i, parent, parser, result) {
  if (node.is('operator') || node.is('unaryOperator')) {
    var previous = parent.content[i - 1] || false,
        next = parent.content[i + 1] || false,
        operator = node.content;

    //////////////////////////
    // Multi-part operators
    //////////////////////////

    // If second part of relational operator move on
    if (node.content === '=' && previous) {
      if (previous.content === '<' || previous.content === '>') {
        return false;
      }
    }

    // If first part of relational operator, carry on and build it
    if ((node.content === '<' || node.content === '>') && next) {
      if (next.content === '=') {
        operator = getRelationalOperator(node);
        next = parent.content[i + 2] || false;
      }
    }

    //////////////////////////
    // Exceptions
    //////////////////////////

    if (isException(operator, parent, i)) {
      return false;
    }

    // If the operator checks out in our valid operator list
    if (operators.indexOf(operator) !== -1) {

      if (parser.options.include) {
        if (
          (previous && !previous.is('space'))
          || (next && !next.is('space'))
        ) {
          result = helpers.addUnique(result, {
            'ruleId': parser.rule.name,
            'line': node.start.line,
            'column': node.start.column,
            'message': 'Space expected around operator',
            'severity': parser.severity
          });
        }
        else {
          if (
              (previous && (previous.end.line >= previous.start.line) && (previous.end.column > previous.start.column))
              || (next && (next.end.line >= next.start.line) && (next.end.column > next.start.column))
            ) {
            result = helpers.addUnique(result, {
              'ruleId': parser.rule.name,
              'line': node.start.line,
              'column': node.start.column,
              'message': 'Multiple spaces not allowed around operator',
              'severity': parser.severity
            });
          }
        }
      }
      else {
        if (
          (previous && previous.is('space'))
          || (next && next.is('space'))
        ) {
          result = helpers.addUnique(result, {
            'ruleId': parser.rule.name,
            'line': node.start.line,
            'column': node.start.column,
            'message': 'No spaces allowed around operator',
            'severity': parser.severity
          });
        }
      }
    }
  }
  return result;
};

module.exports = {
  'name': 'space-around-operator',
  'defaults': {
    'include': true
  },
  'detect': function (ast, parser) {
    var result = [];

    ast.traverseByTypes(['condition', 'atrule', 'value'], function (node) {
      node.forEach(function (item, i, parent) {
        // Perform another loop of the children if we come across a parenthesis
        // parent node
        if (item.is('parentheses')) {
          item.forEach(function (child, j, childParent) {
            // Do the spacing checks
            checkSpacing(child, j, childParent, parser, result);
          });
        }
        else {
          // Do the spacing checks
          checkSpacing(item, i, parent, parser, result);
        }
      });
    });

    return result;
  }
};
<|endoftext|>


<commit_before>import Service, { inject as service } from '@ember/service';
import Util from 'shared/utils/util';
import { get, set } from '@ember/object';

export default Service.extend({
  access: service(),
  cookies  : service(),
  session  : service(),
  globalStore: service(),
  app: service(),

  generateState() {
    var state = Math.random()+'';
    get(this, 'session').set('githubState', state);
    return state;
  },

  stateMatches(actual) {
    var expected = get(this, 'session.githubState');
    return actual && expected === actual;
  },

  testConfig(config) {
    return config.doAction('configureTest', config);
  },

  saveConfig(config, opt) {
    return config.doAction('testAndApply', opt);
  },

  authorize(auth, state) {
    var url = Util.addQueryParams(get(auth, 'redirectUrl'), {
      scope: 'read:org',
      redirect_uri: `${window.location.origin}/verify-auth`,
      authProvider: 'github',
      state: state,
    });

    return window.location.href = url;
  },

  login() {
    const provider = get(this, 'access.providers').findBy('id', 'github');
    const authRedirect = get(provider, 'redirectUrl');
    const redirect = Util.addQueryParams(`${window.location.origin}/verify-auth`, {
      login: true,
      state: this.generateState(),
    });

    const url = Util.addQueryParams(authRedirect, {
      scope: 'read:org',
      redirect_uri: redirect,
    });

    window.location.href = url;
  },

  test(config, cb) {
    var responded = false;
    window.onGithubTest = (err,code) => {
      if ( !responded ) {
        var ghConfig = config;
        responded = true;
        this.finishTest(ghConfig, code, cb);
        // cb(err,code);
      }
    };

    set(this, 'state', this.generateState());

    let url = Util.addQueryParams(`${window.location.origin}/verify-auth`, {
        config: 'github',
    });

    var popup = window.open(url, 'rancherAuth', Util.popupWindowOptions());
    var timer = setInterval(function() {
      if ( !popup || popup.closed ) {
        clearInterval(timer);
        if( !responded ) {
          responded = true;
          cb({type: 'error', message: 'Github access was not authorized'});
        }
      }
    }, 500);
  },

  finishTest(config, code, cb) {
    let ghConfig = config.clone();
    let out = {
      code: code,
      enabled: true,
      githubConfig: ghConfig,
    };

    set(ghConfig, 'allowedPrincipalIds', [get(this, 'access.me.principalIds.firstObject')]);

    return this.saveConfig(config, out).then(() => {
      get(this, 'access').detect(); // Update the list of providers...
      cb();
    }).catch((err) => {
      cb(err);
    });
  },
});
<commit_msg>remove setting a principal id on testAndApply success<commit_after>import Service, { inject as service } from '@ember/service';
import Util from 'shared/utils/util';
import { get, set } from '@ember/object';

export default Service.extend({
  access: service(),
  cookies  : service(),
  session  : service(),
  globalStore: service(),
  app: service(),

  generateState() {
    var state = Math.random()+'';
    get(this, 'session').set('githubState', state);
    return state;
  },

  stateMatches(actual) {
    var expected = get(this, 'session.githubState');
    return actual && expected === actual;
  },

  testConfig(config) {
    return config.doAction('configureTest', config);
  },

  saveConfig(config, opt) {
    return config.doAction('testAndApply', opt);
  },

  authorize(auth, state) {
    var url = Util.addQueryParams(get(auth, 'redirectUrl'), {
      scope: 'read:org',
      redirect_uri: `${window.location.origin}/verify-auth`,
      authProvider: 'github',
      state: state,
    });

    return window.location.href = url;
  },

  login() {
    const provider = get(this, 'access.providers').findBy('id', 'github');
    const authRedirect = get(provider, 'redirectUrl');
    const redirect = Util.addQueryParams(`${window.location.origin}/verify-auth`, {
      login: true,
      state: this.generateState(),
    });

    const url = Util.addQueryParams(authRedirect, {
      scope: 'read:org',
      redirect_uri: redirect,
    });

    window.location.href = url;
  },

  test(config, cb) {
    var responded = false;
    window.onGithubTest = (err,code) => {
      if ( !responded ) {
        var ghConfig = config;
        responded = true;
        this.finishTest(ghConfig, code, cb);
        // cb(err,code);
      }
    };

    set(this, 'state', this.generateState());

    let url = Util.addQueryParams(`${window.location.origin}/verify-auth`, {
        config: 'github',
    });

    var popup = window.open(url, 'rancherAuth', Util.popupWindowOptions());
    var timer = setInterval(function() {
      if ( !popup || popup.closed ) {
        clearInterval(timer);
        if( !responded ) {
          responded = true;
          cb({type: 'error', message: 'Github access was not authorized'});
        }
      }
    }, 500);
  },

  finishTest(config, code, cb) {
    let ghConfig = config.clone();
    let out = {
      code: code,
      enabled: true,
      githubConfig: ghConfig,
    };

    return this.saveConfig(config, out).then(() => {
      get(this, 'access').detect(); // Update the list of providers...
      cb();
    }).catch((err) => {
      cb(err);
    });
  },
});
<|endoftext|>


<commit_before>'use strict';

// TODO: read(/annotate), write

function is_nil(datum) { return datum === null; }
function is_closure(datum) { return typeof datum === 'function'; }
function is_boolean(datum) { return typeof datum === 'boolean'; }
function is_text(datum) { return typeof datum === 'string'; }
function is_number(datum) { return typeof datum === 'number'; }
function is_int32(datum) {
  return (typeof datum === 'number') && (datum === (datum | 0));
}
function is_pair(datum) {
  return (typeof datum === 'object') && (datum !== null);
}

function env_extend(env, datum) { return [datum, env]; }
function env_ref(env, idx) {
  for (; idx > 0; --idx) { env = env[1]; }
  return env[0];
}
function env_find(env, found) {
  var index = 0;
  for (; env !== null; ++index) {
    if (found(env[0])) { return index; }
    env = env[1];
  }
  return undefined;
}
function env_find_name(env, name) {
  var index = env_find(env, function(b){return (name === b[0]);});
  if (index === undefined) { throw ['unbound variable', name]; }
  return index;
}
function env_lookup(env, name) {
  var index = env_find_name(env, name);
  return env_ref(env, index)[1];
}

// TODO: Expect annotated syntax.
function syntax_list_of_length(len, xs, err) {
  var result = [];
  for (; len > 0; --len) {
    if (!is_pair(xs)) { throw err; }
    result.push(xs[0]);
    xs = xs[1];
  }
  if (!is_nil(xs)) { throw err; }
  return result;
}
function syntax_list(xs, err) {
  var result = [];
  while (is_pair(xs)) {
    result.push(xs[0]);
    xs = xs[1];
  }
  if (!is_nil(xs)) { throw err; }
  return result;
}
function array_to_list(xs) {
  var i = xs.length - 1;
  var result = null;
  for (; i >= 0; --i) { result = [xs[i], result]; }
  return result;
}
function array_map(f, xs) {
  var i = xs.length - 1;
  var result = [];
  result.length = xs.length;
  for (; i >= 0; --i) { result[i] = f(xs[i]); }
  return result;
}

function evaluate(stx) {
  // TODO: It may be better to pass these registers around in an explicit
  // context rather than capturing them in closures.  It may also be more
  // efficient to represent continuations as tagged data structures.
  var result, env = null, ks = [function(){return null;}];

  // TODO: Might as well inline this everywhere.
  function unwind() { return ks.pop(); }

  function denote_literal(datum) {
    return function() { result = datum; return unwind(); };
  }
  function denote_var(senv, name) {
    var index = env_find_name(senv, name);
    if (env_ref(senv, index)[1] !== false) { throw ['invalid syntax', name]; }
    return function() { result = env_ref(env, index); return unwind(); };
  }

  function build_app(senv, dp, as) {
    if (is_nil(as)) { return dp; }
    var da = denote(senv, as[0]);
    var dapp = function(){
      var kenv = env;
      ks.push(function() {
        var proc = result;
        if (!is_closure(proc)) { throw ['cannot apply non-procedure', proc]; }
        ks.push(function() { return proc(result); });
        env = kenv;
        return da;
      });
      return dp;
    };
    return build_app(senv, dapp, as[1]);
  }
  function denote_app(senv, stx) {
    var err = ['invalid application', stx];
    if (!is_pair(stx)) { throw err; }
    syntax_list(stx[1], err);
    return build_app(senv, denote(senv, stx[0]), stx[1]);
  }

  function denote(senv, stx) {
    if (is_nil(stx) || is_boolean(stx) || is_number(stx)) {
      return denote_literal(stx);
    } else if (is_text(stx)) {
      return denote_var(senv, stx);
    } else if (is_pair(stx)) {
      if (is_text(stx[0])) {
        var special = env_lookup(senv, stx[0]);
        if (typeof special === 'function') { return special(senv, stx[1]); }
      }
      return denote_app(senv, stx);
    } else { throw ['unknown syntax', stx]; }
  }

  function build_lambda(senv, params, body) {
    if (is_nil(params)) { return denote(senv, body); }
    senv = env_extend(senv, [params[0], false]);
    var dl = build_lambda(senv, params[1], body);
    return function() {
      var clo_env = env;
      result = function(arg) {
        env = env_extend(clo_env, arg);
        return dl;
      };
      return unwind();
    };
  }
  function denote_lambda(senv, stx) {
    var err = ['invalid lambda', stx];
    stx = syntax_list_of_length(2, stx, err);
    var params = stx[0], body = stx[1];
    if (!is_pair(params)) { throw err; }
    array_map(function(p){ if (!is_text(p)) { throw err; } },
              syntax_list(params, err));
    return build_lambda(senv, params, body);
  }
  function denote_if(senv, stx) {
    stx = syntax_list_of_length(3, stx, ['invalid if', stx]);
    var dc = denote(senv, stx[0]);
    var dt = denote(senv, stx[1]);
    var df = denote(senv, stx[2]);
    return function() {
      var kenv = env;
      ks.push(function(){
        env = kenv;
        if (result === false) { return df; } else { return dt; }
      });
      return dc;
    };
  }
  function denote_quote(senv, stx) {
    stx = syntax_list_of_length(1, stx, ['invalid quote', stx]);
    return denote_literal(stx[0]);
  }
  function denote_qq(senv, stx) {
    // TODO:
  }
  function denote_let(senv, stx) {
    var err = ['invalid let', orig_stx];
    stx = syntax_list_of_length(2, stx, err);
    var bindings = array_map(function(binding) {
      return syntax_list_of_length(2, binding, err);
    }, syntax_list(stx[0], err));
    var params = array_map(function(binding) {
      if (!is_text(binding[0])) { throw err; } return binding[0];
    }, bindings);
    var args = array_map(function(binding) { return bindings[1]; }, bindings);
    var body = stx[1];
    var dp = build_lambda(senv, array_to_list(params), body);
    return build_app(senv, dp, array_to_list(args));
  }

  var operatives = [
    ['let', denote_let],
    ['quasiquote', denote_qq],
    ['quote', denote_quote],
    ['if', denote_if],
    ['lambda', denote_lambda]];

  function native_procedure_huh(datum) {
    result = is_closure(datum); return unwind();
  }
  function native_boolean_huh(datum) {
    result = is_boolean(datum); return unwind();
  }
  function native_pair_huh(datum) { result = is_pair(datum); return unwind(); }
  function native_nil_huh(datum) { result = is_nil(datum); return unwind(); }
  function native_text_huh(datum) { result = is_text(datum); return unwind(); }
  function native_number_huh(datum) { result = is_number(datum); return unwind(); }
  function native_int32_huh(datum) { result = is_int32(datum); return unwind(); }
  function make_eq(name, is_x) {
    return function(x0) {
      if (!is_x(x0)) { throw ["invalid argument to '"+name+"'", x0]; }
      result = function(x1) {
        if (!is_x(x1)) { throw ["invalid argument to '"+name+"'", x1]; }
        result = (x0 === x1);
        return unwind();
      };
      return unwind();
    };
  }
  var native_text_eq = make_eq('text=?', is_text);
  var native_number_eq = make_eq('number=?', is_number);
  var native_int32_eq = make_eq('int32=?', is_int32);
  function make_lt(name, is_x) {
    return function(x0) {
      if (!is_x(x0)) { throw ["invalid argument to '"+name+"'", x0]; }
      result = function(x1) {
        if (!is_x(x1)) { throw ["invalid argument to '"+name+"'", x1]; }
        result = (x0 < x1);
        return unwind();
      };
      return unwind();
    };
  }
  var native_text_lt = make_lt('text<?', is_text);
  var native_number_lt = make_lt('number<?', is_number);
  var native_int32_lt = make_lt('int32<?', is_int32);
  function native_pair(h) {
    result = function(t) { result = [h, t]; return unwind(); };
    return unwind();
  }
  function native_pair_head(p) {
    if (!is_pair(p)) { throw ['cannot take head of non-pair', p]; }
    result = p[0];
    return unwind();
  }
  function native_pair_tail(p) {
    if (!is_pair(p)) { throw ['cannot take tail of non-pair', p]; }
    result = p[1];
    return unwind();
  }

  function native_text_concat(t0) {
    if (!is_text(t0)) { throw ['cannot text-concat non-text', t0]; }
    result = function(t1) {
      if (!is_text(t1)) { throw ['cannot text-concat non-text', t1]; }
      result = t0.concat(t1);
      return unwind();
    };
    return unwind();
  }
  function native_text_to_list(txt) {
    if (!is_text(t0)) { throw ['cannot text->list non-text', txt]; }
    var i = txt.length - 1;
    var answer = null;
    for (; i >= 0; --i) { answer = [txt.charAt(i), answer]; }
    result = answer;
    return unwind();
  }
  // NOTE: codePointAt and String.fromCodePoint aren't supported in ES5
  function native_text_to_codes(txt) {
    if (!is_text(t0)) { throw ['cannot text->codes non-text', txt]; }
    var i = txt.length - 1;
    var answer = null;
    for (; i >= 0; --i) { answer = [txt.charCodeAt(i), answer]; }
    result = answer;
    return unwind();
  }
  function native_text_from_codes(cs) {
    var err = ['invalid text codes', cs];
    cs = syntax_list(cs, err);
    var i = cs.length - 1;
    for (; i >= 0; --i) { if (!is_int32(cs[i])) { throw err; } }
    result = String.fromCharCode.apply(this, cs);
    return unwind();
  }

  function native_nadd(n0) {
    if (!is_number(n0)) { throw ['cannot add non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot add non-number', n1]; }
      result = n0 + n1; return unwind();
    };
    return unwind();
  }
  function native_nsub(n0) {
    if (!is_number(n0)) { throw ['cannot subtract non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot subtract non-number', n1]; }
      result = n0 - n1; return unwind();
    };
    return unwind();
  }
  function native_nmul(n0) {
    if (!is_number(n0)) { throw ['cannot multiply non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot multiply non-number', n1]; }
      result = n0 * n1; return unwind();
    };
    return unwind();
  }
  function native_ndiv(n0) {
    if (!is_number(n0)) { throw ['cannot divide non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot divide non-number', n1]; }
      result = n0 / n1; return unwind();
    };
    return unwind();
  }
  function native_nmod(n0) {
    if (!is_number(n0)) { throw ['cannot modulo non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot modulo non-number', n1]; }
      result = n0 % n1; return unwind();
    };
    return unwind();
  }

  // TODO: More text and/or numerical operations?
  var applicatives = [
    ['procedure?', native_procedure_huh],
    ['pair?', native_pair_huh],
    ['nil?', native_nil_huh],
    ['boolean?', native_boolean_huh],
    ['text?', native_text_huh],
    ['number?', native_number_huh],
    ['int32?', native_int32_huh],
    ['text=?', native_text_eq],
    ['text<?', native_text_lt],
    ['number=?', native_number_eq],
    ['number<?', native_number_lt],
    ['int32=?', native_int32_eq],
    ['int32<?', native_int32_lt],
    ['pair', native_pair],
    ['head', native_pair_head],
    ['tail', native_pair_tail],
    ['text-concat', native_text_concat],
    ['text->list', native_text_to_list],
    ['text->codes', native_text_to_codes],
    ['text<-codes', native_text_from_codes],
    ['+', native_nadd],
    ['-', native_nsub],
    ['*', native_nmul],
    ['/', native_ndiv],
    ['%', native_nmod]];

  var initial_senv =
    array_to_list(
      array_map(function(binding){return [binding[0],false];},
                applicatives).concat(operatives));

  var initial_env =
    array_to_list(
      array_map(function(binding){return binding[1];}, applicatives).concat(
        array_map(function(binding){return binding[1];}, operatives)));

  env = initial_env;
  var k = denote(initial_senv, stx);
  while (k !== null) { k = k(); }
  return result;
}
<commit_msg>Fix denote_let<commit_after>'use strict';

// TODO: read(/annotate), write

function is_nil(datum) { return datum === null; }
function is_closure(datum) { return typeof datum === 'function'; }
function is_boolean(datum) { return typeof datum === 'boolean'; }
function is_text(datum) { return typeof datum === 'string'; }
function is_number(datum) { return typeof datum === 'number'; }
function is_int32(datum) {
  return (typeof datum === 'number') && (datum === (datum | 0));
}
function is_pair(datum) {
  return (typeof datum === 'object') && (datum !== null);
}

function env_extend(env, datum) { return [datum, env]; }
function env_ref(env, idx) {
  for (; idx > 0; --idx) { env = env[1]; }
  return env[0];
}
function env_find(env, found) {
  var index = 0;
  for (; env !== null; ++index) {
    if (found(env[0])) { return index; }
    env = env[1];
  }
  return undefined;
}
function env_find_name(env, name) {
  var index = env_find(env, function(b){return (name === b[0]);});
  if (index === undefined) { throw ['unbound variable', name]; }
  return index;
}
function env_lookup(env, name) {
  var index = env_find_name(env, name);
  return env_ref(env, index)[1];
}

// TODO: Expect annotated syntax.
function syntax_list_of_length(len, xs, err) {
  var result = [];
  for (; len > 0; --len) {
    if (!is_pair(xs)) { throw err; }
    result.push(xs[0]);
    xs = xs[1];
  }
  if (!is_nil(xs)) { throw err; }
  return result;
}
function syntax_list(xs, err) {
  var result = [];
  while (is_pair(xs)) {
    result.push(xs[0]);
    xs = xs[1];
  }
  if (!is_nil(xs)) { throw err; }
  return result;
}
function array_to_list(xs) {
  var i = xs.length - 1;
  var result = null;
  for (; i >= 0; --i) { result = [xs[i], result]; }
  return result;
}
function array_map(f, xs) {
  var i = xs.length - 1;
  var result = [];
  result.length = xs.length;
  for (; i >= 0; --i) { result[i] = f(xs[i]); }
  return result;
}

function evaluate(stx) {
  // TODO: It may be better to pass these registers around in an explicit
  // context rather than capturing them in closures.  It may also be more
  // efficient to represent continuations as tagged data structures.
  var result, env = null, ks = [function(){return null;}];

  // TODO: Might as well inline this everywhere.
  function unwind() { return ks.pop(); }

  function denote_literal(datum) {
    return function() { result = datum; return unwind(); };
  }
  function denote_var(senv, name) {
    var index = env_find_name(senv, name);
    if (env_ref(senv, index)[1] !== false) { throw ['invalid syntax', name]; }
    return function() { result = env_ref(env, index); return unwind(); };
  }

  function build_app(senv, dp, as) {
    if (is_nil(as)) { return dp; }
    var da = denote(senv, as[0]);
    var dapp = function(){
      var kenv = env;
      ks.push(function() {
        var proc = result;
        if (!is_closure(proc)) { throw ['cannot apply non-procedure', proc]; }
        ks.push(function() { return proc(result); });
        env = kenv;
        return da;
      });
      return dp;
    };
    return build_app(senv, dapp, as[1]);
  }
  function denote_app(senv, stx) {
    var err = ['invalid application', stx];
    if (!is_pair(stx)) { throw err; }
    syntax_list(stx[1], err);
    return build_app(senv, denote(senv, stx[0]), stx[1]);
  }

  function denote(senv, stx) {
    if (is_nil(stx) || is_boolean(stx) || is_number(stx)) {
      return denote_literal(stx);
    } else if (is_text(stx)) {
      return denote_var(senv, stx);
    } else if (is_pair(stx)) {
      if (is_text(stx[0])) {
        var special = env_lookup(senv, stx[0]);
        if (typeof special === 'function') { return special(senv, stx[1]); }
      }
      return denote_app(senv, stx);
    } else { throw ['unknown syntax', stx]; }
  }

  function build_lambda(senv, params, body) {
    if (is_nil(params)) { return denote(senv, body); }
    senv = env_extend(senv, [params[0], false]);
    var dl = build_lambda(senv, params[1], body);
    return function() {
      var clo_env = env;
      result = function(arg) {
        env = env_extend(clo_env, arg);
        return dl;
      };
      return unwind();
    };
  }
  function denote_lambda(senv, stx) {
    var err = ['invalid lambda', stx];
    stx = syntax_list_of_length(2, stx, err);
    var params = stx[0], body = stx[1];
    if (!is_pair(params)) { throw err; }
    array_map(function(p){ if (!is_text(p)) { throw err; } },
              syntax_list(params, err));
    return build_lambda(senv, params, body);
  }
  function denote_if(senv, stx) {
    stx = syntax_list_of_length(3, stx, ['invalid if', stx]);
    var dc = denote(senv, stx[0]);
    var dt = denote(senv, stx[1]);
    var df = denote(senv, stx[2]);
    return function() {
      var kenv = env;
      ks.push(function(){
        env = kenv;
        if (result === false) { return df; } else { return dt; }
      });
      return dc;
    };
  }
  function denote_quote(senv, stx) {
    stx = syntax_list_of_length(1, stx, ['invalid quote', stx]);
    return denote_literal(stx[0]);
  }
  function denote_qq(senv, stx) {
    // TODO:
  }
  function denote_let(senv, stx) {
    var err = ['invalid let', stx];
    stx = syntax_list_of_length(2, stx, err);
    var bindings = array_map(function(b) {
      return syntax_list_of_length(2, b, err);
    }, syntax_list(stx[0], err));
    var params = array_map(function(b) {
      if (!is_text(b[0])) { throw err; } return b[0];
    }, bindings);
    var args = array_map(function(b) { return b[1]; }, bindings);
    var body = stx[1];
    var dp = build_lambda(senv, array_to_list(params), body);
    return build_app(senv, dp, array_to_list(args));
  }

  var operatives = [
    ['let', denote_let],
    ['quasiquote', denote_qq],
    ['quote', denote_quote],
    ['if', denote_if],
    ['lambda', denote_lambda]];

  function native_procedure_huh(datum) {
    result = is_closure(datum); return unwind();
  }
  function native_boolean_huh(datum) {
    result = is_boolean(datum); return unwind();
  }
  function native_pair_huh(datum) { result = is_pair(datum); return unwind(); }
  function native_nil_huh(datum) { result = is_nil(datum); return unwind(); }
  function native_text_huh(datum) { result = is_text(datum); return unwind(); }
  function native_number_huh(datum) { result = is_number(datum); return unwind(); }
  function native_int32_huh(datum) { result = is_int32(datum); return unwind(); }
  function make_eq(name, is_x) {
    return function(x0) {
      if (!is_x(x0)) { throw ["invalid argument to '"+name+"'", x0]; }
      result = function(x1) {
        if (!is_x(x1)) { throw ["invalid argument to '"+name+"'", x1]; }
        result = (x0 === x1);
        return unwind();
      };
      return unwind();
    };
  }
  var native_text_eq = make_eq('text=?', is_text);
  var native_number_eq = make_eq('number=?', is_number);
  var native_int32_eq = make_eq('int32=?', is_int32);
  function make_lt(name, is_x) {
    return function(x0) {
      if (!is_x(x0)) { throw ["invalid argument to '"+name+"'", x0]; }
      result = function(x1) {
        if (!is_x(x1)) { throw ["invalid argument to '"+name+"'", x1]; }
        result = (x0 < x1);
        return unwind();
      };
      return unwind();
    };
  }
  var native_text_lt = make_lt('text<?', is_text);
  var native_number_lt = make_lt('number<?', is_number);
  var native_int32_lt = make_lt('int32<?', is_int32);
  function native_pair(h) {
    result = function(t) { result = [h, t]; return unwind(); };
    return unwind();
  }
  function native_pair_head(p) {
    if (!is_pair(p)) { throw ['cannot take head of non-pair', p]; }
    result = p[0];
    return unwind();
  }
  function native_pair_tail(p) {
    if (!is_pair(p)) { throw ['cannot take tail of non-pair', p]; }
    result = p[1];
    return unwind();
  }

  function native_text_concat(t0) {
    if (!is_text(t0)) { throw ['cannot text-concat non-text', t0]; }
    result = function(t1) {
      if (!is_text(t1)) { throw ['cannot text-concat non-text', t1]; }
      result = t0.concat(t1);
      return unwind();
    };
    return unwind();
  }
  function native_text_to_list(txt) {
    if (!is_text(t0)) { throw ['cannot text->list non-text', txt]; }
    var i = txt.length - 1;
    var answer = null;
    for (; i >= 0; --i) { answer = [txt.charAt(i), answer]; }
    result = answer;
    return unwind();
  }
  // NOTE: codePointAt and String.fromCodePoint aren't supported in ES5
  function native_text_to_codes(txt) {
    if (!is_text(t0)) { throw ['cannot text->codes non-text', txt]; }
    var i = txt.length - 1;
    var answer = null;
    for (; i >= 0; --i) { answer = [txt.charCodeAt(i), answer]; }
    result = answer;
    return unwind();
  }
  function native_text_from_codes(cs) {
    var err = ['invalid text codes', cs];
    cs = syntax_list(cs, err);
    var i = cs.length - 1;
    for (; i >= 0; --i) { if (!is_int32(cs[i])) { throw err; } }
    result = String.fromCharCode.apply(this, cs);
    return unwind();
  }

  function native_nadd(n0) {
    if (!is_number(n0)) { throw ['cannot add non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot add non-number', n1]; }
      result = n0 + n1; return unwind();
    };
    return unwind();
  }
  function native_nsub(n0) {
    if (!is_number(n0)) { throw ['cannot subtract non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot subtract non-number', n1]; }
      result = n0 - n1; return unwind();
    };
    return unwind();
  }
  function native_nmul(n0) {
    if (!is_number(n0)) { throw ['cannot multiply non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot multiply non-number', n1]; }
      result = n0 * n1; return unwind();
    };
    return unwind();
  }
  function native_ndiv(n0) {
    if (!is_number(n0)) { throw ['cannot divide non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot divide non-number', n1]; }
      result = n0 / n1; return unwind();
    };
    return unwind();
  }
  function native_nmod(n0) {
    if (!is_number(n0)) { throw ['cannot modulo non-number', n0]; }
    result = function(n1) {
      if (!is_number(n1)) { throw ['cannot modulo non-number', n1]; }
      result = n0 % n1; return unwind();
    };
    return unwind();
  }

  // TODO: More text and/or numerical operations?
  var applicatives = [
    ['procedure?', native_procedure_huh],
    ['pair?', native_pair_huh],
    ['nil?', native_nil_huh],
    ['boolean?', native_boolean_huh],
    ['text?', native_text_huh],
    ['number?', native_number_huh],
    ['int32?', native_int32_huh],
    ['text=?', native_text_eq],
    ['text<?', native_text_lt],
    ['number=?', native_number_eq],
    ['number<?', native_number_lt],
    ['int32=?', native_int32_eq],
    ['int32<?', native_int32_lt],
    ['pair', native_pair],
    ['head', native_pair_head],
    ['tail', native_pair_tail],
    ['text-concat', native_text_concat],
    ['text->list', native_text_to_list],
    ['text->codes', native_text_to_codes],
    ['text<-codes', native_text_from_codes],
    ['+', native_nadd],
    ['-', native_nsub],
    ['*', native_nmul],
    ['/', native_ndiv],
    ['%', native_nmod]];

  var initial_senv =
    array_to_list(
      array_map(function(binding){return [binding[0],false];},
                applicatives).concat(operatives));

  var initial_env =
    array_to_list(
      array_map(function(binding){return binding[1];}, applicatives).concat(
        array_map(function(binding){return binding[1];}, operatives)));

  env = initial_env;
  var k = denote(initial_senv, stx);
  while (k !== null) { k = k(); }
  return result;
}
<|endoftext|>


<commit_before>var options = require("./options.json");
var games = require("./games.json").games;
var Discord = require("discord.js");

function correctUsage(cmd) {
	var msg = "Usage: " + options.command_prefix + "" + cmd + " " + mod_commands[cmd].usage;
	return msg;
}

var mod_commands = {
	"help": {
		description: "Sends a DM containing all of these mod_commands.",
		usage: "[command]",
		permLevel: 0,
		process: function (bot, msg, suffix)
		{
			if(mod_commands[suffix])
			{
				{
					bot.sendMessage(msg.author, correctUsage(suffix))
					bot.deleteMessage(msg);
				}
			}
			else
			{
				var msgArray = [];
				msgArray.push("**mod_commands: **");
				msgArray.push("```");
				Object.keys(mod_commands).forEach(function (cmd) {
					msgArray.push("" + options.mod_command_prefix + "" + cmd + ": " + mod_commands[cmd].description + "");
				});
				msgArray.push("```");
				bot.sendMessage(msg.author, msgArray);
				bot.deleteMessage(msg);
			}
		}
	},
	"servers":
	{
		usage: "[none]",
		description: "lists servers bot is connected to",
		process: function (bot, msg) {
			bot.sendMessage(msg.channel,bot.user+" is currently connected to the following servers:\n ```" +bot.servers+"```");
			bot.deleteMessage(msg);
		}
	},
	"channels":
	{
		usage: ["none"],
		description: "lists channels bot is connected to",
		process: function (bot, msg) {
			bot.sendMessage(msg.channel, bot.channels);
		}
	},
	"stats": {
		usage: "[none]",
		description: "outputs different about the bot",
		process: function (bot, msg, suffix,commandsProcessed,talked) {
			var seconds = Math.round((bot.uptime / 1000) % 60);
			var minutes = Math.round((bot.uptime / (1000 * 60)) % 60);
			var hours = Math.round((bot.uptime / (1000 * 60 * 60)) % 60);
			bot.sendMessage(msg, "**Info about "+bot.user+":** \n```Bot Uptime: " + hours + " hours, " + minutes + " minutes, and " + seconds + " seconds.\nConnected to "+bot.servers.length+" server(s) and "+bot.channels.length+" channel(s).\nDuring the current session "+commandsProcessed+" command(s) have been processed.\nTalked to "+talked+" time(s).```");
			bot.deleteMessage(msg);
		}
	},
	"say": {
		usage: "[message]",
		description: "bot says message",
		process: function (bot, msg, suffix) {
			bot.sendMessage(msg.channel, suffix);
			bot.deleteMessage(msg);
		}
	},
	"announce": {
		usage: "[message]",
		description: "bot says message with text to speech",
		process: function (bot, msg, suffix) {
			bot.sendMessage(msg.channel, suffix, {
				tts: true
			});
			bot.deleteMessage(msg);
		}
	},
	"join": {
		usage: "[invite]",
		description: "joins the server it's invited to",
		process: function (bot, msg, suffix) {
			console.log(bot.joinServer(suffix, function (error, server) {
				console.log("callback: " + arguments);
				if (error) {
					bot.sendMessage(msg.channel, "failed to join: " + error);
				} else {
					console.log("Joined server " + server);
					bot.sendMessage(msg.channel, "Successfully joined " + server);
				}
			}));
		}
	},
	"create": {
		usage: "[channel name]",
		description: "creates a new text channel with the given name.",
		process: function (bot, msg, suffix) {
			bot.createChannel(msg.channel.server, suffix, "text").then(function (channel) {
				bot.sendMessage(msg.channel, "created " + channel);
			}).catch(function (error) {
				bot.sendMessage(msg.channel, "failed to create channel: " + error);
			});
		}
	},
	"voice": {
		usage: "[channel name]",
		description: "creates a new voice channel with the give name.",
		process: function (bot, msg, suffix) {
			bot.createChannel(msg.channel.server, suffix, "voice").then(function (channel) {
				bot.sendMessage(msg.channel, "created " + channel.id);
				console.log("created " + channel);
			}).catch(function (error) {
				bot.sendMessage(msg.channel, "failed to create channel: " + error);
			});
		}
	},
	"topic": {
		usage: "[topic]",
		description: "Sets the topic for the channel. No topic removes the topic.",
		process: function (bot, msg, suffix) {
			bot.setChannelTopic(msg.channel, suffix);
			bot.reply(msg, "done!")
		}
	},
	"playing": {
		usage: "[game]",
		description: "allows you to set a game for Onee-chan to play. If nothing specified it will be random.",
		process: function (bot, msg, suffix) {
			if (suffix) {
				bot.setPlayingGame(suffix);
			}
			if (!suffix) {
				bot.setPlayingGame(games[Math.floor(Math.random() * (games.length))]);
			}
			bot.deleteMessage(msg);
		}
	},
	"stop": {
		usage: "[none]",
		description: "stops the bot",
		process: function (bot, msg, suffix) {
			if (msg.author.id === "87600987040120832") {
				bot.reply(msg, "I will be taking my leave.")
				bot.logout();
				console.log("Stopped bot.");
			} else {
				bot.reply(msg, "I CANNOT BE STOPPED BY THE LIKES OF YOU");
			}
			bot.deleteMessage(msg);
		}
	},
	"setname": {
		usage: "[name]",
		description: "Changes the bots username",
		process: function (bot, msg, suffix) {
			if (suffix) {
				bot.setUsername(suffix);
				console.log("Mod Command - Set Username to " + suffix);
			} else {
				bot.setUsername("Onee-chan");
				console.log("Mod Command - Set Username to Onee-chan");
			}
			bot.reply(msg, "done!")
		}
	},
	"remove": {
		usage: "[channel name]",
		description: "deletes the specified channel",
		process: function (bot, msg, suffix) {
			var channel = bot.channels.get("id", suffix);
			if (suffix.startsWith('[#')) {
				channel = bot.channels.get("id", suffix.substr(2, suffix.length - 3));
			}
			if (!channel) {
				var channels = bot.channels.getAll("name", suffix);
				if (channels.length > 1) {
					https: //github.com/chalda/DiscordBot/issues/new
						var response = "Multiple channels match, please use id:";
					for (var i = 0; i < channels.length; i++) {
						response += channels[i] + ": " + channels[i].id;
					}
					bot.sendMessage(msg.channel, response);
					return;
				} else if (channels.length == 1) {
					channel = channels[0];
				} else {
					bot.sendMessage(msg.channel, "Couldn't find channel " + suffix + " to delete!");
					return;
				}
			}
			bot.sendMessage(msg.channel, "deleting channel " + suffix + " at " + msg.author + "'s request");
			bot.deleteChannel(channel).then(function (channel) {
				console.log("deleted " + suffix + " at " + msg.author + "'s request");
			}).catch(function (error) {
				bot.sendMessage(msg.channel, "couldn't delete channel: " + error);
			});
		}
	}
	/*,
	"eval": {
		usage: "[command]",
		description: 'Executes arbitrary javascript in the bot process.',
		process: function(bot,msg,suffix) {
				bot.sendMessage(msg.channel, eval(suffix,bot));
		}
	}*/
};

function rssfeed(bot, msg, url, count, full) {
	var FeedParser = require('feedparser');
	var feedparser = new FeedParser();
	var request = require('request');
	request(url).pipe(feedparser);
	feedparser.on('error', function (error) {
		bot.sendMessage(msg.channel, "failed reading feed: " + error);
	});
	var shown = 0;
	feedparser.on('readable', function () {
		var stream = this;
		shown += 1
		if (shown > count) {
			return;
		}
		var item = stream.read();
		bot.sendMessage(msg.channel, item.title + " - " + item.link, function () {
			if (full === true) {
				var text = htmlToText.fromString(item.description, {
					wordwrap: false,
					ignoreHref: true
				});
				bot.sendMessage(msg.channel, text);
			}
		});
		stream.alreadyRead = true;
	});
}
exports.mod_commands = mod_commands;
<commit_msg>Added a delete mod command for deleting messages in a chat<commit_after>var options = require("./options.json");
var games = require("./games.json").games;
var Discord = require("discord.js");

function correctUsage(cmd) {
	var msg = "Usage: " + options.command_prefix + "" + cmd + " " + mod_commands[cmd].usage;
	return msg;
}

var mod_commands = {
	"help": {
		description: "Sends a DM containing all of these mod_commands.",
		usage: "[command]",
		permLevel: 0,
		process: function (bot, msg, suffix)
		{
			if(mod_commands[suffix])
			{
				{
					bot.sendMessage(msg.author, correctUsage(suffix))
					bot.deleteMessage(msg);
				}
			}
			else
			{
				var msgArray = [];
				msgArray.push("**mod_commands: **");
				msgArray.push("```");
				Object.keys(mod_commands).forEach(function (cmd) {
					msgArray.push("" + options.mod_command_prefix + "" + cmd + ": " + mod_commands[cmd].description + "");
				});
				msgArray.push("```");
				bot.sendMessage(msg.author, msgArray);
				bot.deleteMessage(msg);
			}
		}
	},
	"servers":
	{
		usage: "[none]",
		description: "lists servers bot is connected to",
		process: function (bot, msg) {
			bot.sendMessage(msg.channel,bot.user+" is currently connected to the following servers:\n ```" +bot.servers+"```");
			bot.deleteMessage(msg);
		}
	},
	"channels":
	{
		usage: ["none"],
		description: "lists channels bot is connected to",
		process: function (bot, msg) {
			bot.sendMessage(msg.channel, bot.channels);
		}
	},
	"stats": {
		usage: "[none]",
		description: "outputs different about the bot",
		process: function (bot, msg, suffix,commandsProcessed,talked) {
			var seconds = Math.round((bot.uptime / 1000) % 60);
			var minutes = Math.round((bot.uptime / (1000 * 60)) % 60);
			var hours = Math.round((bot.uptime / (1000 * 60 * 60)) % 60);
			bot.sendMessage(msg, "**Info about "+bot.user+":** \n```Bot Uptime: " + hours + " hours, " + minutes + " minutes, and " + seconds + " seconds.\nConnected to "+bot.servers.length+" server(s) and "+bot.channels.length+" channel(s).\nDuring the current session "+commandsProcessed+" command(s) have been processed.\nTalked to "+talked+" time(s).```");
			bot.deleteMessage(msg);
		}
	},
	"say": {
		usage: "[message]",
		description: "bot says message",
		process: function (bot, msg, suffix) {
			bot.sendMessage(msg.channel, suffix);
			bot.deleteMessage(msg);
		}
	},
	"announce": {
		usage: "[message]",
		description: "bot says message with text to speech",
		process: function (bot, msg, suffix) {
			bot.sendMessage(msg.channel, suffix, {
				tts: true
			});
			bot.deleteMessage(msg);
		}
	},
	"join": {
		usage: "[invite]",
		description: "joins the server it's invited to",
		process: function (bot, msg, suffix) {
			console.log(bot.joinServer(suffix, function (error, server) {
				console.log("callback: " + arguments);
				if (error) {
					bot.sendMessage(msg.channel, "failed to join: " + error);
				} else {
					console.log("Joined server " + server);
					bot.sendMessage(msg.channel, "Successfully joined " + server);
				}
			}));
		}
	},
	"create": {
		usage: "[channel name]",
		description: "creates a new text channel with the given name.",
		process: function (bot, msg, suffix) {
			bot.createChannel(msg.channel.server, suffix, "text").then(function (channel) {
				bot.sendMessage(msg.channel, "created " + channel);
			}).catch(function (error) {
				bot.sendMessage(msg.channel, "failed to create channel: " + error);
			});
		}
	},
	"voice": {
		usage: "[channel name]",
		description: "creates a new voice channel with the give name.",
		process: function (bot, msg, suffix) {
			bot.createChannel(msg.channel.server, suffix, "voice").then(function (channel) {
				bot.sendMessage(msg.channel, "created " + channel.id);
				console.log("created " + channel);
			}).catch(function (error) {
				bot.sendMessage(msg.channel, "failed to create channel: " + error);
			});
		}
	},
	"topic": {
		usage: "[topic]",
		description: "Sets the topic for the channel. No topic removes the topic.",
		process: function (bot, msg, suffix) {
			bot.setChannelTopic(msg.channel, suffix);
			bot.reply(msg, "done!")
		}
	},
	"playing": {
		usage: "[game]",
		description: "allows you to set a game for Onee-chan to play. If nothing specified it will be random.",
		process: function (bot, msg, suffix) {
			if (suffix) {
				bot.setPlayingGame(suffix);
			}
			if (!suffix) {
				bot.setPlayingGame(games[Math.floor(Math.random() * (games.length))]);
			}
			bot.deleteMessage(msg);
		}
	},
	"stop": {
		usage: "[none]",
		description: "stops the bot",
		process: function (bot, msg, suffix) {
			if (msg.author.id === "87600987040120832") {
				bot.reply(msg, "I will be taking my leave.")
				bot.logout();
				console.log("Stopped bot.");
			} else {
				bot.reply(msg, "I CANNOT BE STOPPED BY THE LIKES OF YOU");
			}
			bot.deleteMessage(msg);
		}
	},
	"setname": {
		usage: "[name]",
		description: "Changes the bots username",
		process: function (bot, msg, suffix) {
			if (suffix) {
				bot.setUsername(suffix);
				console.log("Mod Command - Set Username to " + suffix);
			} else {
				bot.setUsername("Onee-chan");
				console.log("Mod Command - Set Username to Onee-chan");
			}
			bot.reply(msg, "done!")
		}
	},
	"remove": {
		usage: "[channel name]",
		description: "deletes the specified channel",
		process: function (bot, msg, suffix) {
			var channel = bot.channels.get("id", suffix);
			if (suffix.startsWith('[#')) {
				channel = bot.channels.get("id", suffix.substr(2, suffix.length - 3));
			}
			if (!channel) {
				var channels = bot.channels.getAll("name", suffix);
				if (channels.length > 1) {
					https: //github.com/chalda/DiscordBot/issues/new
						var response = "Multiple channels match, please use id:";
					for (var i = 0; i < channels.length; i++) {
						response += channels[i] + ": " + channels[i].id;
					}
					bot.sendMessage(msg.channel, response);
					return;
				} else if (channels.length == 1) {
					channel = channels[0];
				} else {
					bot.sendMessage(msg.channel, "Couldn't find channel " + suffix + " to delete!");
					return;
				}
			}
			bot.sendMessage(msg.channel, "deleting channel " + suffix + " at " + msg.author + "'s request");
			bot.deleteChannel(channel).then(function (channel) {
				console.log("deleted " + suffix + " at " + msg.author + "'s request");
			}).catch(function (error) {
				bot.sendMessage(msg.channel, "couldn't delete channel: " + error);
			});
		}
	},
	"delete": {
		usage: "[number of messages from 1 - 100]",
		description: "Deletes the specified number of messages from the channel",
		process: function (bot, msg, suffix)
		{
			if(suffix && /^\d+$/.test(suffix))
			{
				bot.getChannelLogs(msg.channel, 100, function(error,messages)
				{
					if(error)
					{
						console.log("there was an error getting the logs");
						return;
					}
					else {
						bot.startTyping(msg.channel);
						var deletes = parseInt(suffix, 10) + 1;
						console.log(deletes);
						var dones = 0;
						for (count of messages)
						{
							bot.deleteMessage(count);
							dones++;
							deletes--;
							console.log(dones);
							if(deletes == 0 || dones == 100)
							{
								console.log("Finished deleting "+deletes+" messages in "+msg.channel);
								bot.stopTyping(msg.channel);
								return;
							}
						}
						bot.stopTyping(msg.channel);
					}
				});
			}
			else
			{
					bot.reply(msg,"using the delete command requires a interger between 1-500")
			}
		}
	},
	/*,
	"eval": {
		usage: "[command]",
		description: 'Executes arbitrary javascript in the bot process.',
		process: function(bot,msg,suffix) {
				bot.sendMessage(msg.channel, eval(suffix,bot));
		}
	}*/
};

function rssfeed(bot, msg, url, count, full) {
	var FeedParser = require('feedparser');
	var feedparser = new FeedParser();
	var request = require('request');
	request(url).pipe(feedparser);
	feedparser.on('error', function (error) {
		bot.sendMessage(msg.channel, "failed reading feed: " + error);
	});
	var shown = 0;
	feedparser.on('readable', function () {
		var stream = this;
		shown += 1
		if (shown > count) {
			return;
		}
		var item = stream.read();
		bot.sendMessage(msg.channel, item.title + " - " + item.link, function () {
			if (full === true) {
				var text = htmlToText.fromString(item.description, {
					wordwrap: false,
					ignoreHref: true
				});
				bot.sendMessage(msg.channel, text);
			}
		});
		stream.alreadyRead = true;
	});
}
exports.mod_commands = mod_commands;
<|endoftext|>


<commit_before>/*jslint vars: false, browser: true, nomen: true */
/*global MOOC: true, Backbone, $, _, YT, async */

if (_.isUndefined(window.MOOC)) {
    window.MOOC = {};
}

MOOC.views = {};

MOOC.views.Unit = Backbone.View.extend({
    events: {
        "click li span.kq": "showKQ",
        "click li span.q": "showQ",
        "click li span.a": "showA"
    },

    render: function () {
        "use strict";
        var html = '

';
        this.model.get("knowledgeQuantumList").each(function (kq) {
            html += '
' + kq.get("title") + '';
            if (kq.has("question")) {
                html += ' ' + MOOC.trans.classroom.q + ' ';
                html += '/ ' + MOOC.trans.classroom.a + '';
            }
            html += '
';
        });
        html += '

';
        this.$el.html(html);
        return this;
    },

    showKQ: function (evt) {
        "use strict";
        var kq = $(evt.target).parent().attr("id").split("kq")[1];
        MOOC.router.navigate(this.id + "/kq" + kq, { trigger: true });
    },

    showQ: function (evt) {
        "use strict";
        var kq = $(evt.target).parent().attr("id").split("kq")[1];
        MOOC.router.navigate(this.id + "/kq" + kq + "/q", { trigger: true });
    },

    showA: function (evt) {
        "use strict";
        var kq = $(evt.target).parent().attr("id").split("kq")[1];
        MOOC.router.navigate(this.id + "/kq" + kq + "/a", { trigger: true });
    }
});

MOOC.views.unitViews = {};

MOOC.views.KnowledgeQuantum = Backbone.View.extend({
    render: function () {
        "use strict";
        var height = this.getVideoHeight(),
            player,
            html,
            unit,
            order,
            kq,
            kqObj;

        html = '';
        $("#kq-video").html(html);

        $("#kq-q-buttons").addClass("hide");
        $("#kq-next-container").addClass("offset4");

        if (this.model.has("question")) {
            kqObj = this.model;
            // Load Question Data
            MOOC.ajax.getResource(kqObj.get("question"), function (data, textStatus, jqXHR) {
                var aux = _.pick(data, "id", "last_frame", "solutionID"),
                    question = new MOOC.models.Question({
                        id: aux.id,
                        lastFrame: aux.last_frame,
                        solution: aux.solutionID
                    });
                kqObj.set("questionInstance", question);
                // Load Options for Question
                MOOC.ajax.getOptionsByQuestion(question.get("id"), function (data, textStatus, jqXHR) {
                    var options = _.map(data.objects, function (opt) {
                        return new MOOC.models.Option(_.pick(opt, "id", "optiontype", "x", "y"));
                    });
                    question.set("optionList", new MOOC.models.OptionList(options));
                });
            });
            this.waitForPlayer();
        }

        $("#kq-title").html(this.model.get("title"));

        unit = MOOC.models.course.getByKQ(this.model.get("id"));
        $("#unit-selector").find("div.collapse").removeClass("in");
        $("#unit" + unit.get("id")).addClass("in");
        order = this.model.get("order");
        $("#kq-previous").unbind("click");
        $("#kq-next").unbind("click");

        kq = unit.get("knowledgeQuantumList").getByPosition(order - 1);
        this.navigate("#kq-previous", unit, kq);
        kq = unit.get("knowledgeQuantumList").getByPosition(order + 1);
        this.navigate("#kq-next", unit, kq);

        this.$el.parent().children().removeClass("active");
        this.$el.addClass("active");

        return this;
    },

    getVideoHeight: function () {
        "use strict";
        var width = $("#kq-video").css("width"),
            height;

        if (width.indexOf('p') > 0) {
            width = parseInt(width.split('p')[0], 10);
        } else {
            width = parseInt(width, 10);
        }
        height = Math.round((width * 6) / 10);
        if (height < 200) {
            height = 200;
        }

        return height;
    },

    navigate: function (selector, unit, kq) {
        "use strict";
        if (_.isUndefined(kq)) {
            $(selector).addClass("disabled");
        } else {
            $(selector).removeClass("disabled");
            $(selector).click(function (evt) {
                MOOC.router.navigate("unit" + unit.get("id") + "/kq" + kq.get("id"), { trigger: true });
            });
        }
    },

    player: null,

    waitForPlayer: function (callback) {
        "use strict";
        if (MOOC.YTready) {
            this.player = new YT.Player("ytplayer", {
                events: {
                    onStateChange: _.bind(this.loadQuestion, this)
                }
            });
            if (!_.isUndefined(callback)) {
                callback();
            }
        } else {
            _.delay(_.bind(this.waitForPlayer, this), 200, callback);
        }
    },

    waitFor: function (model, property, callback) {
        "use strict";
        if (model.has(property)) {
            callback();
        } else {
            model.on("change", function (evt) {
                if (this.has(property)) {
                    this.off("change");
                    callback();
                }
            }, model);
        }
    },

    loadQuestion: function (evt) {
        "use strict";
        if (evt.data === YT.PlayerState.ENDED) {
            var toExecute = [];

            if (!this.model.has("questionInstance")) {
                toExecute.push(async.apply(this.waitFor, this.model, "questionInstance"));
            }

            toExecute.push(_.bind(function (callback) {
                var question = this.model.get("questionInstance");
                this.waitFor(question, "optionList", callback);
            }, this));

            toExecute.push(_.bind(function (callback) {
                var question = this.model.get("questionInstance"),
                    width = $("#kq-video").children().css("width"),
                    height = $("#kq-video").children().css("height"),
                    path = window.location.hash,
                    html = '';
                this.player.destroy();
                this.player = null;
                $("#kq-video").html(html);

                if (!(/#[\w\/]+\/q/.test(path))) {
                    path = path.substring(1) + "/q";
                    MOOC.router.navigate(path, { trigger: false });
                }

                $("#kq-q-buttons").removeClass("hide");
                $("#kq-q-showkq").click(function () {
                    var path = window.location.hash,
                        idx = path.lastIndexOf('/');
                    if ((path[idx] + path[idx + 1]) === "/q") {
                        path = path.substring(1, idx);
                        MOOC.router.navigate(path, { trigger: true });
                    }
                });
                $("#kq-q-submit").click(_.bind(function () {
                    this.submitAnswer(question);
                }, this));
                $("#kq-next-container").removeClass("offset4");

                question.get("optionList").each(function (opt) {
                    if (_.isUndefined(MOOC.views.optionViews[opt.get("id")])) {
                        MOOC.views.optionViews[opt.get("id")] = new MOOC.views.Option({
                            model: opt,
                            el: $("#kq-video")[0]
                        });
                    }
                    MOOC.views.optionViews[opt.get("id")].render();
                });

                callback();
            }, this));

            async.series(toExecute);
        }

        return this;
    },

    submitAnswer: function (question) {
        "use strict";
        var now = new Date(),
            answerList = [],
            put;

        put = question.get("optionList").any(function (opt) {
            return opt.has("lastAnswerDate");
        });

        question.get("optionList").each(function (opt) {
            var view = MOOC.views.optionViews[opt.get("id")],
                input = view.$el.find("input#option" + opt.get("id")),
                type = input.attr("type"),
                value;

            if (type === "text") {
                value = input.val();
            } else {
                value = !_.isUndefined(input.attr("checked"));
            }
            view.model.set("answer", value);
            view.model.set("lastAnswerDate", now);

            answerList.push({
                id: view.model.get("id"),
                answer: value,
                date: now
            });
        });

        MOOC.ajax.sendAnswers(put, answerList, function (data, textStatus, jqXHR) {
            MOOC.alerts.show(MOOC.alerts.SUCCESS, MOOC.trans.classroom.answersSent, MOOC.trans.classroom.answersSentMsg);
        });
    },

    loadSolution: function () {
        "use strict";
        var toExecute = [];

        toExecute.push(_.bind(this.waitForPlayer, this));
        toExecute.push(_.bind(function (callback) {
            this.player.destroy();
            this.player = null;
            callback();
        }, this));

        if (!this.model.has("questionInstance")) {
            toExecute.push(async.apply(this.waitFor, this.model, "questionInstance"));
        }

        toExecute.push(_.bind(function (callback) {
            var height = this.getVideoHeight(),
                html;

            html = '';
            $("#kq-video").html(html);
            $("#kq-q-buttons").addClass("hide");
            $("#kq-next-container").addClass("offset4");

            callback();
        }, this));

        async.series(toExecute);

        return this;
    }
});

MOOC.views.kqViews = {};

MOOC.views.Option = Backbone.View.extend({
    types: {
        i: "text",
        c: "checkbox",
        r: "radio"
    },

    render: function () {
        "use strict";
        var html = "<input type='" + this.types[this.model.get("optiontype")] + "' ",
            node;
        html += "id='option" + this.model.get("id") + "' ";
        html += "style='top: " + this.model.get("y") + "px; left: " + this.model.get("x") + "px;' ";
        if (this.model.get("optiontype") === 'r') {
            html += "name='radio' ";
        }
        if (this.model.has("answer")) {
            if (this.model.get("optiontype") === 'i') {
                html += "value='" + this.model.get("answer") + "' ";
            } else {
                html += "checked='" + this.model.get("answer") + "' ";
            }
        }
        html += "/>";
        node = $(html)[0];
        this.$el.append(node);
        return this;
    }
});

MOOC.views.optionViews = {};
<commit_msg>Improve 'prev' and 'next' navigation<commit_after>/*jslint vars: false, browser: true, nomen: true */
/*global MOOC: true, Backbone, $, _, YT, async */

if (_.isUndefined(window.MOOC)) {
    window.MOOC = {};
}

MOOC.views = {};

MOOC.views.Unit = Backbone.View.extend({
    events: {
        "click li span.kq": "showKQ",
        "click li span.q": "showQ",
        "click li span.a": "showA"
    },

    render: function () {
        "use strict";
        var html = '

';
        this.model.get("knowledgeQuantumList").each(function (kq) {
            html += '
' + kq.get("title") + '';
            if (kq.has("question")) {
                html += ' ' + MOOC.trans.classroom.q + ' ';
                html += '/ ' + MOOC.trans.classroom.a + '';
            }
            html += '
';
        });
        html += '

';
        this.$el.html(html);
        return this;
    },

    showKQ: function (evt) {
        "use strict";
        var kq = $(evt.target).parent().attr("id").split("kq")[1];
        MOOC.router.navigate(this.id + "/kq" + kq, { trigger: true });
    },

    showQ: function (evt) {
        "use strict";
        var kq = $(evt.target).parent().attr("id").split("kq")[1];
        MOOC.router.navigate(this.id + "/kq" + kq + "/q", { trigger: true });
    },

    showA: function (evt) {
        "use strict";
        var kq = $(evt.target).parent().attr("id").split("kq")[1];
        MOOC.router.navigate(this.id + "/kq" + kq + "/a", { trigger: true });
    }
});

MOOC.views.unitViews = {};

MOOC.views.KnowledgeQuantum = Backbone.View.extend({
    render: function () {
        "use strict";
        var height = this.getVideoHeight(),
            player,
            html,
            unit,
            order,
            kq,
            kqObj;

        html = '';
        $("#kq-video").html(html);

        $("#kq-q-buttons").addClass("hide");
        $("#kq-next-container").addClass("offset4");

        if (this.model.has("question")) {
            kqObj = this.model;
            // Load Question Data
            MOOC.ajax.getResource(kqObj.get("question"), function (data, textStatus, jqXHR) {
                var aux = _.pick(data, "id", "last_frame", "solutionID"),
                    question = new MOOC.models.Question({
                        id: aux.id,
                        lastFrame: aux.last_frame,
                        solution: aux.solutionID
                    });
                kqObj.set("questionInstance", question);
                // Load Options for Question
                MOOC.ajax.getOptionsByQuestion(question.get("id"), function (data, textStatus, jqXHR) {
                    var options = _.map(data.objects, function (opt) {
                        return new MOOC.models.Option(_.pick(opt, "id", "optiontype", "x", "y"));
                    });
                    question.set("optionList", new MOOC.models.OptionList(options));
                });
            });
            this.waitForPlayer();
        }

        $("#kq-title").html(this.model.get("title"));

        unit = MOOC.models.course.getByKQ(this.model.get("id"));
        $("#unit-selector").find("div.collapse").removeClass("in");
        $("#unit" + unit.get("id")).addClass("in");

        $("#kq-previous").unbind("click");
        $("#kq-next").unbind("click");
        this.navigate("#kq-previous", unit, this.model, false);
        this.navigate("#kq-next", unit, this.model, true);

        this.$el.parent().children().removeClass("active");
        this.$el.addClass("active");

        return this;
    },

    getVideoHeight: function () {
        "use strict";
        var width = $("#kq-video").css("width"),
            height;

        if (width.indexOf('p') > 0) {
            width = parseInt(width.split('p')[0], 10);
        } else {
            width = parseInt(width, 10);
        }
        height = Math.round((width * 6) / 10);
        if (height < 200) {
            height = 200;
        }

        return height;
    },

    navigate: function (selector, unit, kq, next) {
        "use strict";
        var path = window.location.hash,
            order = kq.get("order"),
            getUrlForOtherKQ,
            target,
            url;

        getUrlForOtherKQ = function (position, answer) {
            var aux = unit.get("knowledgeQuantumList").getByPosition(position),
                url;
            if (_.isUndefined(aux)) {
                $(selector).addClass("disabled");
            } else {
                url = "unit" + unit.get("id") + "/kq" + aux.get("id");
                if (answer && aux.has("question")) {
                    url += "/a";
                }
                return url;
            }
        };

        if (/#[\w\/]+\/q/.test(path)) {
            // Viewing question
            target = next ? "answer" : "same";
        } else if (/#[\w\/]+\/a/.test(path)) {
            // Viewing answer
            target = next ? "next" : "question";
        } else {
            // Viewing kq
            target = next ? "question" : "prev";
        }
        if (target === "question" && !kq.has("question")) {
            target = "next";
        }

        if (target === "question") {
            url = "unit" + unit.get("id") + "/kq" + kq.get("id") + "/q";
        } else if (target === "answer") {
            url = "unit" + unit.get("id") + "/kq" + kq.get("id") + "/a";
        } else if (target === "next") {
            url = getUrlForOtherKQ(order + 1, false);
        } else if (target === "prev") {
            url = getUrlForOtherKQ(order - 1, true);
        } else {
            // case same
            url = "unit" + unit.get("id") + "/kq" + kq.get("id");
        }

        if (_.isUndefined(url)) {
            $(selector).addClass("disabled");
        } else {
            $(selector).removeClass("disabled");
            $(selector).click(function (evt) {
                MOOC.router.navigate(url, { trigger: true });
            });
        }
    },

    player: null,

    waitForPlayer: function (callback) {
        "use strict";
        if (MOOC.YTready) {
            this.player = new YT.Player("ytplayer", {
                events: {
                    onStateChange: _.bind(this.loadQuestion, this)
                }
            });
            if (!_.isUndefined(callback)) {
                callback();
            }
        } else {
            _.delay(_.bind(this.waitForPlayer, this), 200, callback);
        }
    },

    waitFor: function (model, property, callback) {
        "use strict";
        if (model.has(property)) {
            callback();
        } else {
            model.on("change", function (evt) {
                if (this.has(property)) {
                    this.off("change");
                    callback();
                }
            }, model);
        }
    },

    loadQuestion: function (evt) {
        "use strict";
        if (evt.data === YT.PlayerState.ENDED) {
            var toExecute = [];

            if (!this.model.has("questionInstance")) {
                toExecute.push(async.apply(this.waitFor, this.model, "questionInstance"));
            }

            toExecute.push(_.bind(function (callback) {
                var question = this.model.get("questionInstance");
                this.waitFor(question, "optionList", callback);
            }, this));

            toExecute.push(_.bind(function (callback) {
                var question = this.model.get("questionInstance"),
                    width = $("#kq-video").children().css("width"),
                    height = $("#kq-video").children().css("height"),
                    path = window.location.hash,
                    html = '';
                this.player.destroy();
                this.player = null;
                $("#kq-video").html(html);

                if (!(/#[\w\/]+\/q/.test(path))) {
                    path = path.substring(1) + "/q";
                    MOOC.router.navigate(path, { trigger: false });
                }

                $("#kq-q-buttons").removeClass("hide");
                $("#kq-q-showkq").click(function () {
                    var path = window.location.hash,
                        idx = path.lastIndexOf('/');
                    if ((path[idx] + path[idx + 1]) === "/q") {
                        path = path.substring(1, idx);
                        MOOC.router.navigate(path, { trigger: true });
                    }
                });
                $("#kq-q-submit").click(_.bind(function () {
                    this.submitAnswer(question);
                }, this));
                $("#kq-next-container").removeClass("offset4");

                question.get("optionList").each(function (opt) {
                    if (_.isUndefined(MOOC.views.optionViews[opt.get("id")])) {
                        MOOC.views.optionViews[opt.get("id")] = new MOOC.views.Option({
                            model: opt,
                            el: $("#kq-video")[0]
                        });
                    }
                    MOOC.views.optionViews[opt.get("id")].render();
                });

                callback();
            }, this));

            async.series(toExecute);
        }

        return this;
    },

    submitAnswer: function (question) {
        "use strict";
        var now = new Date(),
            answerList = [],
            put;

        put = question.get("optionList").any(function (opt) {
            return opt.has("lastAnswerDate");
        });

        question.get("optionList").each(function (opt) {
            var view = MOOC.views.optionViews[opt.get("id")],
                input = view.$el.find("input#option" + opt.get("id")),
                type = input.attr("type"),
                value;

            if (type === "text") {
                value = input.val();
            } else {
                value = !_.isUndefined(input.attr("checked"));
            }
            view.model.set("answer", value);
            view.model.set("lastAnswerDate", now);

            answerList.push({
                id: view.model.get("id"),
                answer: value,
                date: now
            });
        });

        MOOC.ajax.sendAnswers(put, answerList, function (data, textStatus, jqXHR) {
            MOOC.alerts.show(MOOC.alerts.SUCCESS, MOOC.trans.classroom.answersSent, MOOC.trans.classroom.answersSentMsg);
        });
    },

    loadSolution: function () {
        "use strict";
        var toExecute = [];

        toExecute.push(_.bind(this.waitForPlayer, this));
        toExecute.push(_.bind(function (callback) {
            this.player.destroy();
            this.player = null;
            callback();
        }, this));

        if (!this.model.has("questionInstance")) {
            toExecute.push(async.apply(this.waitFor, this.model, "questionInstance"));
        }

        toExecute.push(_.bind(function (callback) {
            var height = this.getVideoHeight(),
                html;

            html = '';
            $("#kq-video").html(html);
            $("#kq-q-buttons").addClass("hide");
            $("#kq-next-container").addClass("offset4");

            callback();
        }, this));

        async.series(toExecute);

        return this;
    }
});

MOOC.views.kqViews = {};

MOOC.views.Option = Backbone.View.extend({
    types: {
        i: "text",
        c: "checkbox",
        r: "radio"
    },

    render: function () {
        "use strict";
        var html = "<input type='" + this.types[this.model.get("optiontype")] + "' ",
            node;
        html += "id='option" + this.model.get("id") + "' ";
        html += "style='top: " + this.model.get("y") + "px; left: " + this.model.get("x") + "px;' ";
        if (this.model.get("optiontype") === 'r') {
            html += "name='radio' ";
        }
        if (this.model.has("answer")) {
            if (this.model.get("optiontype") === 'i') {
                html += "value='" + this.model.get("answer") + "' ";
            } else {
                html += "checked='" + this.model.get("answer") + "' ";
            }
        }
        html += "/>";
        node = $(html)[0];
        this.$el.append(node);
        return this;
    }
});

MOOC.views.optionViews = {};
<|endoftext|>


<commit_before>var utils = require('../lib/utils.js'),
  ecdsa = require('ecdsa'),
  BigInteger = require('bigi'),
  ecurve = require('ecurve');

var ecparams = ecurve.getECParams('secp256k1');

/**
 * @method verifySignature
 * @return {Boolean}
 */
exports.txVerifySignature = function () {
  var msgHash = this.hash(false),
    pubKey = this.getSenderPublicKey(),
    sig = {
      r: BigInteger.fromBuffer(this.r),
      s: BigInteger.fromBuffer(this.s),
      v: utils.bufferToInt(this.v) - 27
    };

  if (pubKey) {
    return ecdsa.verify(msgHash, sig, pubKey);
  } else {
    return false;
  }
};

/**
 * sign a transaction with a given a private key
 * @method sign
 * @param {Buffer} privateKey
 */
exports.txSign = function (privateKey) {
  var msgHash = this.hash(false),
    e = BigInteger.fromBuffer(msgHash),
    pKey  = BigInteger.fromBuffer(privateKey),
    signature = ecdsa.sign(msgHash,  pKey);

  this.r = signature.r.toBuffer();
  this.s = signature.s.toBuffer();

  var curvePt = ecparams.g.multiply(pKey);
  this.v = ecdsa.calcPubKeyRecoveryParam(e, signature, curvePt) + 27;
};

/**
 * gets the senders public key
 * @method getSenderPublicKey
 * @return {Buffer}
 */
exports.txGetSenderPublicKey = function () {

  var msgHash = this.hash(false),
    sig = {
      r: BigInteger.fromBuffer(this.r),
      s: BigInteger.fromBuffer(this.s),
      v: utils.bufferToInt(this.v) - 27
    },
    e = BigInteger.fromBuffer(msgHash);

  var key = false;
  try {
    key = ecdsa.recoverPubKey(e, sig, sig.v).getEncoded(false);
  } catch (e) {}

  return key;

};
<commit_msg>browser/ecdsaOps: require ethereumjs-util<commit_after>var utils = require('ethereumj-utils'),
  ecdsa = require('ecdsa'),
  BigInteger = require('bigi'),
  ecurve = require('ecurve');

var ecparams = ecurve.getECParams('secp256k1');

/**
 * @method verifySignature
 * @return {Boolean}
 */
exports.txVerifySignature = function () {
  var msgHash = this.hash(false),
    pubKey = this.getSenderPublicKey(),
    sig = {
      r: BigInteger.fromBuffer(this.r),
      s: BigInteger.fromBuffer(this.s),
      v: utils.bufferToInt(this.v) - 27
    };

  if (pubKey) {
    return ecdsa.verify(msgHash, sig, pubKey);
  } else {
    return false;
  }
};

/**
 * sign a transaction with a given a private key
 * @method sign
 * @param {Buffer} privateKey
 */
exports.txSign = function (privateKey) {
  var msgHash = this.hash(false),
    e = BigInteger.fromBuffer(msgHash),
    pKey  = BigInteger.fromBuffer(privateKey),
    signature = ecdsa.sign(msgHash,  pKey);

  this.r = signature.r.toBuffer();
  this.s = signature.s.toBuffer();

  var curvePt = ecparams.g.multiply(pKey);
  this.v = ecdsa.calcPubKeyRecoveryParam(e, signature, curvePt) + 27;
};

/**
 * gets the senders public key
 * @method getSenderPublicKey
 * @return {Buffer}
 */
exports.txGetSenderPublicKey = function () {

  var msgHash = this.hash(false),
    sig = {
      r: BigInteger.fromBuffer(this.r),
      s: BigInteger.fromBuffer(this.s),
      v: utils.bufferToInt(this.v) - 27
    },
    e = BigInteger.fromBuffer(msgHash);

  var key = false;
  try {
    key = ecdsa.recoverPubKey(e, sig, sig.v).getEncoded(false);
  } catch (e) {}

  return key;

};
<|endoftext|>


<commit_before>
var body = document.querySelector("body");
body.classList.add("testing");

module.exports = Reporter;
function Reporter() {
    this.root = this;
    this.passed = 0;
    this.failed = 0;
    this.skipped = 0;
    this.errors = 0;
    this.passedAssertions = 0;
    this.failedAssertions = 0;
    this.depth = 0;
}

Reporter.prototype.start = function (test) {
    var child = Object.create(this);
    child.test = test;
    child.depth = this.depth + 1;
    child.failed = false;
    child.skipped = false;
    console.group(test.type + " " + test.name);
    return child;
};

Reporter.prototype.end = function (test) {
    if (test.type === "it") {
        if (this.failed) {
            this.root.failed++;
            body.classList.add("fail");
            console.error("FAIL");
        } else if (this.skipped) {
            this.root.skipped++;
        } else {
            this.root.passed++;
        }
    }
    console.groupEnd();
};

Reporter.prototype.skip = function () {
    this.skipped = true;
    this.root.skipped++;
};

Reporter.prototype.assert = function (guard, isNot, messages, objects) {
    var passed = !guard === isNot;
    if (passed) {
        this.root.passedAssertions++;
    } else {
        var interleaved = [];
        var format = [];
        for (var index = 0; index < Math.max(messages.length, objects.length); index++) {
            if (index < messages.length) {
                var message = "" + messages[index];
                if (isNot) {
                    message = message.replace(/\[not\] /, "not ");
                } else {
                    message = message.replace(/\[not\] /, "");
                }
                format.push("%s");
                interleaved.push(message);
            }
            if (index < objects.length) {
                format.push("%O");
                interleaved.push(objects[index]);
            }
        }
        //interleaved.unshift(format.join(" "));
        console.log.apply(console, interleaved);
        this.failed = true;
        this.root.failedAssertions++;
    }
};

Reporter.prototype.error = function (error, test) {
    this.failed = true;
    this.root.errors++;
    console.log(error.stack);
};

Reporter.prototype.summarize = function (suite) {
    if (!this.failed) {
        body.classList.add("pass");
    }
    console.log(this.passed + " passed tests");
    console.log(this.passedAssertions + " passed assertions");
    if (this.failed) {
        console.error(this.failed + " failed tests");
    } else {
        console.log(this.failed + " failed tests");
    }
    if (this.failedAssertions) {
        console.error(this.failedAssertions + " failed assertions");
    } else {
        console.log(this.failedAssertions + " failed assertions");
    }
    console.log(this.errors + " errors");
    var skipped = suite.testCount - this.passed - this.failed;
    console.log(skipped + " skipped tests");

    global.global_test_results = {
        passed: this.passed,
        passedAssertions: this.passedAssertions,
        failed: this.failed,
        failedAssertions: this.failedAssertions,
        skipped: skipped
    };
};

<commit_msg>Fix browser tests<commit_after>
var body = document.querySelector("body");
body.classList.add("testing");

module.exports = Reporter;
function Reporter() {
    this.root = this;
    this.passed = 0;
    this.failed = 0;
    this.skipped = 0;
    this.errors = 0;
    this.passedAssertions = 0;
    this.failedAssertions = 0;
    this.depth = 0;
}

Reporter.prototype.start = function (test) {
    var child = Object.create(this);
    child.test = test;
    child.depth = this.depth + 1;
    child.failed = test.shouldFail;
    child.skipped = false;
    console.group(test.type + " " + test.name);
    return child;
};

Reporter.prototype.end = function (test) {
    if (this.failed && this.parent && this.parent.parent) {
        this.parent.failed = true;
    }
    if (test.type === "it") {
        if (this.failed) {
            this.root.failed++;
            body.classList.add("fail");
            console.error("FAIL");
        } else if (this.skipped) {
            this.root.skipped++;
        } else {
            this.root.passed++;
        }
    }
    console.groupEnd();
};

Reporter.prototype.skip = function () {
    this.skipped = true;
    this.root.skipped++;
};

Reporter.prototype.assert = function (guard, isNot, messages, objects) {
    var passed = !guard === isNot;
    if ((!passed && !this.test.shouldFail) || this.showPasses) {
        var interleaved = [];
        var format = [];
        for (var index = 0; index < Math.max(messages.length, objects.length); index++) {
            if (index < messages.length) {
                var message = "" + messages[index];
                if (isNot) {
                    message = message.replace(/\[not\] /, "not ");
                } else {
                    message = message.replace(/\[not\] /, "");
                }
                format.push("%s");
                interleaved.push(message);
            }
            if (index < objects.length) {
                format.push("%O");
                interleaved.push(objects[index]);
            }
        }
        //interleaved.unshift(format.join(" "));
        console.log.apply(console, interleaved);
    }
    if (passed) { // passed
        if (this.test.shouldFail) { // but should fail
            this.failed = false;
        } else { // and passed
            this.root.passedAssertions++;
        }
    } else { // failed
        if (!this.test.shouldFail) { // but should pass
            this.failed = true;
            this.root.failedAssertions++;
        } else { // and should fail
            this.failed = false;
            this.root.passedAssertions++;
        }
    }
};

Reporter.prototype.error = function (error, test) {
    this.failed = true;
    this.root.errors++;
    if (this.test.shouldFail) {
        this.failed = false;
    } else if (error && typeof error.stack === "string") {
        console.log(error.stack);
    } else {
        console.log(error);
    }
};

Reporter.prototype.summarize = function (suite) {
    if (!this.failed) {
        body.classList.add("pass");
    }
    console.log(this.passed + " passed tests");
    console.log(this.passedAssertions + " passed assertions");
    if (this.failed) {
        console.error(this.failed + " failed tests");
    } else {
        console.log(this.failed + " failed tests");
    }
    if (this.failedAssertions) {
        console.error(this.failedAssertions + " failed assertions");
    } else {
        console.log(this.failedAssertions + " failed assertions");
    }
    console.log(this.errors + " errors");
    var skipped = suite.testCount - this.passed - this.failed;
    console.log(skipped + " skipped tests");

    global.global_test_results = {
        passed: this.passed,
        passedAssertions: this.passedAssertions,
        failed: this.failed,
        failedAssertions: this.failedAssertions,
        skipped: skipped
    };
};

<|endoftext|>