<commit_before>
/* HACKER
   - general user info
   - skills & favorites
   - map to pick a location
   - link external social services
*/

// get the information of the hacker on the current page
// this session variable 'hacker' is setted in the router
var hacker = function () { return Session.get('hacker'); }
var hackerId = function () { return Session.get('hackerId'); }

// DB: checkbox-to-array
// when user check or uncheck a checkboxes it will be saved to the database.
//
// this is how the html is related to the database
// input[name]  --> database field name
// input[value] --> the value to store
// input[checked] --> if checked then add to array or remove otherwise
var addToSet = function(event) {
  var $elm = $(event.currentTarget);
  var field = $elm.attr('name');
  var value = $elm.val();
  var checked = $elm.is(':checked');

  exec(function() {
    var action = checked ? '$addToSet' : '$pull';
    var modifier = _.object([ action ], [ _.object([field], [value]) ]);
    Meteor.users.update(Meteor.userId(), modifier);
  });
}

// DB: input-to-string
// when user input field becomes unfoccused
// update the user info in the database
//
// this is how the html is related to the database
// input[name]  --> database field name
// input[value] --> the value to store
var saveChangedField = function(event, cb) {
  var $elm = $(event.currentTarget); //input element
  var field = $elm.attr('name');
  var value = $elm.val();

  // show feedback on input element
  addDynamicClass($elm, 'saved', 600);

  exec(function() {
    var modifier = _.object([ '$set' ], [ _.object([field], [value]) ]);
    Meteor.users.update(Meteor.userId(), modifier, cb);
  });
}

// the editing mode will be exited if user press the ESCAPE or RETURN button
var fieldChanged = function(event) {
  var $elm = $(event.currentTarget);  //input element
  var keyCode = event.which;
  var ESC = '27', RET = '13';
  if (keyCode == RET)
    $elm.blur()
}

// special case when autosaving email field
// callback after email field updated in the database
var updateEmailCallback = function(err) {
  Session.set('isDuplicateEmail', false);
  Session.set('isNotValidEmail', false);
  if (err) {
    if (err.reason === "Access denied") {
      // possible no valid e-mailaddress
      Session.set('isNotValidEmail', true);
    } else {
      // the most possible reason that the update fails is when
      // there is another account with the same e-mailaddress
      Session.set('isDuplicateEmail', true);
    }
  }
}

// show picture choser when user clicked on the current profile picture
// and user is connected to multiple services
var showPictureChoser = function() {
  if (countSocialServices() > 1) {
    var $elm = $("#hacker #profilePicture .picture-choser");
    addDynamicClass($elm, 'show');
  }
}

// hide picture choser
var hidePictureChoser = function() {
  var $elm = $("#hacker #profilePicture .picture-choser");
  removeDynamicClass($elm, 'show');
}

// user has selected a profile picture
var pictureChanged = function(event) {
  var $picture = $("#hacker #profilePicture .current-picture .picture");
  var $elm = $(event.currentTarget); //input element
  var value = $elm.val();

  // hide picture-choser
  hidePictureChoser();

  // replace current-image in the template
  $picture.css('background-image', "url('"+value+"')");

  // store in database
  exec(function() {
    Meteor.users.update(Meteor.userId(), {$set: {'profile.picture': value}});
  });
}

// toggle between edit/view mode
var toggleEditMode = function(event) {
  event.preventDefault();
  Session.set('hackerEditMode', !Session.get('hackerEditMode'));
}

// count the number of social services the user is connected to
var countSocialServices = function() {
  return _.compact(_.values(hacker().profile.social || {})).length
}

// check if the profile we are viewing is owned by the logged in user
var isCurrentUser = function() {
  return Meteor.userId() == hackerId();
}

// EVENTS

Template.hacker.events({
  'click .toggle-edit-mode': toggleEditMode
});

Template.hackerEdit.events({

  // general autosave input fields
  "blur input.text.save": function(evt) {
    var callback;

    if ($(event.currentTarget).hasClass('email')) //email field
      callback = updateEmailCallback; //run after saving new email

    saveChangedField(evt, callback);
    checkAccess();
  },
  "keyup input.text.save": fieldChanged,
  "click input[type='checkbox'].save": addToSet,

  // special input fields
  "click .current-picture": showPictureChoser,
  "mouseleave .picture-choser": hidePictureChoser,
  "click input[name='picture']": pictureChanged,

});

// TEMPLATE DATA

Template.hacker.helpers({
  "hacker": function() { return hacker(); },
  'isCurrentUser': function() { return isCurrentUser(); },
  'editMode': function() { return isCurrentUser() && Session.get('hackerEditMode'); },
});

Template.hackerEdit.helpers({
  "selected": function(socialPicture) {
    var isSelected = Meteor.user().profile.picture == socialPicture;
    return  isSelected ? 'checked="checked"' : "";
  },
  "checked": function(field, value) {
    var isChecked = _.contains(pathValue(Meteor.user(), field), value);
    return isChecked ? 'checked="checked"' : "";
  },
  "changePictureAllowed": function() {
    // activate changing social pictures only when connected to multiple services
    return countSocialServices() > 1 ? 'change-allowed' : '';
  },
  "isDuplicateEmail": function() {
    return Session.equals('isDuplicateEmail', true);
  },
  "isNotValidEmail": function() {
    return Session.equals('isNotValidEmail', true);
  },
  "isAddServiceError": function(service) {
    return Session.equals('isAddServiceError_'+service, true);
  }
});

Template.hackerView.helpers({
  "checked": function(field, value) {
    var isChecked = _.contains(pathValue(Meteor.user(), field), value);
    return isChecked ? 'checked="checked"' : "";
  },
  "urlCurrentUser": function() {
    var currentUser = Meteor.user();
    return Router.routes['hacker'].url(currentUser);
  }
});

// RENDERING

Template.hackerEdit.rendered = function() {
  if (!this.initialized)
    initializeMap(this.find('#editMap'), Meteor.user(), true); // initialize map
  this.initialized = true;
}

Template.hackerView.rendered = function() {
  if (!this.initialized)
    initializeMap(this.find('#viewMap'), hacker(), false); // initialize map
  this.initialized = true;
}

<commit_msg>fix: initialize map<commit_after>
/* HACKER
   - general user info
   - skills & favorites
   - map to pick a location
   - link external social services
*/

// get the information of the hacker on the current page
// this session variable 'hacker' is setted in the router
var hacker = function () { return Session.get('hacker'); }
var hackerId = function () { return Session.get('hackerId'); }

// DB: checkbox-to-array
// when user check or uncheck a checkboxes it will be saved to the database.
//
// this is how the html is related to the database
// input[name]  --> database field name
// input[value] --> the value to store
// input[checked] --> if checked then add to array or remove otherwise
var addToSet = function(event) {
  var $elm = $(event.currentTarget);
  var field = $elm.attr('name');
  var value = $elm.val();
  var checked = $elm.is(':checked');

  exec(function() {
    var action = checked ? '$addToSet' : '$pull';
    var modifier = _.object([ action ], [ _.object([field], [value]) ]);
    Meteor.users.update(Meteor.userId(), modifier);
  });
}

// DB: input-to-string
// when user input field becomes unfoccused
// update the user info in the database
//
// this is how the html is related to the database
// input[name]  --> database field name
// input[value] --> the value to store
var saveChangedField = function(event, cb) {
  var $elm = $(event.currentTarget); //input element
  var field = $elm.attr('name');
  var value = $elm.val();

  // show feedback on input element
  addDynamicClass($elm, 'saved', 600);

  exec(function() {
    var modifier = _.object([ '$set' ], [ _.object([field], [value]) ]);
    Meteor.users.update(Meteor.userId(), modifier, cb);
  });
}

// the editing mode will be exited if user press the ESCAPE or RETURN button
var fieldChanged = function(event) {
  var $elm = $(event.currentTarget);  //input element
  var keyCode = event.which;
  var ESC = '27', RET = '13';
  if (keyCode == RET)
    $elm.blur()
}

// special case when autosaving email field
// callback after email field updated in the database
var updateEmailCallback = function(err) {
  Session.set('isDuplicateEmail', false);
  Session.set('isNotValidEmail', false);
  if (err) {
    if (err.reason === "Access denied") {
      // possible no valid e-mailaddress
      Session.set('isNotValidEmail', true);
    } else {
      // the most possible reason that the update fails is when
      // there is another account with the same e-mailaddress
      Session.set('isDuplicateEmail', true);
    }
  }
}

// show picture choser when user clicked on the current profile picture
// and user is connected to multiple services
var showPictureChoser = function() {
  if (countSocialServices() > 1) {
    var $elm = $("#hacker #profilePicture .picture-choser");
    addDynamicClass($elm, 'show');
  }
}

// hide picture choser
var hidePictureChoser = function() {
  var $elm = $("#hacker #profilePicture .picture-choser");
  removeDynamicClass($elm, 'show');
}

// user has selected a profile picture
var pictureChanged = function(event) {
  var $picture = $("#hacker #profilePicture .current-picture .picture");
  var $elm = $(event.currentTarget); //input element
  var value = $elm.val();

  // hide picture-choser
  hidePictureChoser();

  // replace current-image in the template
  $picture.css('background-image', "url('"+value+"')");

  // store in database
  exec(function() {
    Meteor.users.update(Meteor.userId(), {$set: {'profile.picture': value}});
  });
}

// toggle between edit/view mode
var toggleEditMode = function(event) {
  event.preventDefault();
  Session.set('hackerEditMode', !Session.get('hackerEditMode'));
}

// count the number of social services the user is connected to
var countSocialServices = function() {
  return _.compact(_.values(hacker().profile.social || {})).length
}

// check if the profile we are viewing is owned by the logged in user
var isCurrentUser = function() {
  return Meteor.userId() == hackerId();
}

// EVENTS

Template.hacker.events({
  'click .toggle-edit-mode': toggleEditMode
});

Template.hackerEdit.events({

  // general autosave input fields
  "blur input.text.save": function(evt) {
    var callback;

    if ($(event.currentTarget).hasClass('email')) //email field
      callback = updateEmailCallback; //run after saving new email

    saveChangedField(evt, callback);
    checkAccess();
  },
  "keyup input.text.save": fieldChanged,
  "click input[type='checkbox'].save": addToSet,

  // special input fields
  "click .current-picture": showPictureChoser,
  "mouseleave .picture-choser": hidePictureChoser,
  "click input[name='picture']": pictureChanged,

});

// TEMPLATE DATA

Template.hacker.helpers({
  "hacker": function() { return hacker(); },
  'isCurrentUser': function() { return isCurrentUser(); },
  'editMode': function() { return isCurrentUser() && Session.get('hackerEditMode'); },
});

Template.hackerEdit.helpers({
  "selected": function(socialPicture) {
    var isSelected = Meteor.user().profile.picture == socialPicture;
    return  isSelected ? 'checked="checked"' : "";
  },
  "checked": function(field, value) {
    var isChecked = _.contains(pathValue(Meteor.user(), field), value);
    return isChecked ? 'checked="checked"' : "";
  },
  "changePictureAllowed": function() {
    // activate changing social pictures only when connected to multiple services
    return countSocialServices() > 1 ? 'change-allowed' : '';
  },
  "isDuplicateEmail": function() {
    return Session.equals('isDuplicateEmail', true);
  },
  "isNotValidEmail": function() {
    return Session.equals('isNotValidEmail', true);
  },
  "isAddServiceError": function(service) {
    return Session.equals('isAddServiceError_'+service, true);
  }
});

Template.hackerView.helpers({
  "checked": function(field, value) {
    var isChecked = _.contains(pathValue(Meteor.user(), field), value);
    return isChecked ? 'checked="checked"' : "";
  },
  "urlCurrentUser": function() {
    var currentUser = Meteor.user();
    return Router.routes['hacker'].url(currentUser);
  }
});

// RENDERING

Template.hackerEdit.rendered = function() {
  if (!this.initialized && this.find('#editMap')) {
    initializeMap(this.find('#editMap'), Meteor.user(), true); // initialize map
    this.initialized = true;
  }
}

Template.hackerView.rendered = function() {
  if (!this.initialized && this.find('#viewMap')) {
    initializeMap(this.find('#viewMap'), hacker(), false); // initialize map
    this.initialized = true;
  }
}

<|endoftext|>


<commit_before>// 1. start the dev server using production config
process.env.NODE_ENV = 'testing'
var server = require('../../build/dev-server.js')

// 2. run the nightwatch test suite against it
// to run in additional browsers:
//    1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
//    2. add it to the --env flag below
// For more information on Nightwatch's config file, see
// http://nightwatchjs.org/guide#settings-file
var spawn = require('cross-spawn')
var runner = spawn(
  './node_modules/.bin/nightwatch',
  [
    '--config', 'test/e2e/nightwatch.conf.js',
    '--env', 'chrome,firefox'
  ],
  {
    stdio: 'inherit'
  }
)

runner.on('exit', function (code) {
  server.close()
  process.exit(code)
})

runner.on('error', function (err) {
  server.close()
  throw err
})
<commit_msg>Ability to pass arguments to Nightwatch.js process (#135)<commit_after>// 1. start the dev server using production config
process.env.NODE_ENV = 'testing'
var server = require('../../build/dev-server.js')

// 2. run the nightwatch test suite against it
// to run in additional browsers:
//    1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
//    2. add it to the --env flag below
// or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
// For more information on Nightwatch's config file, see
// http://nightwatchjs.org/guide#settings-file
var opts = process.argv.slice(2)
if (opts.indexOf('--config') === -1) {
  opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
}
if (opts.indexOf('--env') === -1) {
  opts = opts.concat(['--env', 'chrome'])
}

var spawn = require('cross-spawn')
var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })

runner.on('exit', function (code) {
  server.close()
  process.exit(code)
})

runner.on('error', function (err) {
  server.close()
  throw err
})
<|endoftext|>


<commit_before>/*! JRPC v3.1.0
 * <https://github.com/vphantom/js-jrpc>
 * Copyright 2016 Stéphane Lavergne
 * Free software under MIT License: <https://opensource.org/licenses/MIT> */

'use strict';

global.setImmediate = require('timers').setImmediate;

/**
 * Constructor
 *
 * @typedef {Object} JRPC
 *
 * @param {Object} [options] Options to initialize with
 *
 * @return {undefined} No return value
 */
function JRPC(options) {
  this.active = true;
  this.transmitter = null;
  this.remoteTimeout = 60000;
  this.localTimeout = 0;
  this.serial = 0;
  this.outbox = {
    requests : [],
    responses: []
  };
  this.inbox = {};
  this.localTimers = {};
  this.outTimers = {};
  this.localComponents = {
    'system.listComponents'      : true,
    'system.extension.dual-batch': true
  };
  this.remoteComponents = {};
  this.exposed = {};

  this.exposed['system.listComponents'] = (function(params, next) {
    if (typeof params === 'object' && params !== null) {
      this.remoteComponents = params;
      this.remoteComponents['system._upgraded'] = true;
    }
    return next(null, this.localComponents);
  }).bind(this);

  this.exposed['system.extension.dual-batch'] = function(params, next) {
    return next(null, true);
  };

  if (typeof options === 'object') {
    if (
      'remoteTimeout' in options
      && typeof options['remoteTimeout'] === 'number'
    ) {
      this.remoteTimeout = options['remoteTimeout'] * 1000;
    }

    if (
      'localTimeout' in options
      && typeof options['localTimeout'] === 'number'
    ) {
      this.localTimeout = options['localTimeout'] * 1000;
    }
  }
}

/**
 * Semi-destructor for limbo conditions
 *
 * When we lose connection permanently, we help garbage collection by removing
 * as many references as we can, including cancelling any outstanding timers.
 * We may still get some callbacks, but they will immediately return.
 *
 * @return {undefined} No return value
 */
function shutdown() {
  var instance = this;

  instance.active = false;
  instance.transmitter = null;
  instance.remoteTimeout = 0;
  instance.localTimeout = 0;
  instance.localComponents = {};
  instance.remoteComponents = {};
  instance.outbox.requests.length = 0;
  instance.outbox.responses.length = 0;
  instance.inbox = {};
  instance.exposed = {};

  Object.keys(instance.localTimers).forEach(function(key) {
    clearTimeout(instance.localTimers[key]);
    delete instance.localTimers[key];
  });

  Object.keys(instance.outTimers).forEach(function(key) {
    clearTimeout(instance.outTimers[key]);
    delete instance.outTimers[key];
  });

  return instance;
}

// I/O

/**
 * Send a message if there is something in the queue
 *
 * @param {JRPC~transmitCallback} callback Transmission handler
 *
 * @return {JRPC} This instance, for chaining
 */
function transmit(callback) {
  // Will call next(data, next)
  // Expect OUR next to be called with (err) so we know if it worked
  var iRes;
  var iReq;
  var msg = null;
  var outpacket = {
    responses: [],
    requests : []
  };

  if (typeof callback !== 'function') {
    callback = this.transmitter;
  }
  if (!this.active || typeof callback !== 'function') {
    return this;
  }

  iRes = this.outbox.responses.length;
  iReq = this.outbox.requests.length;
  if (
    iRes > 0
    && iReq > 0
    && 'system.extension.dual-batch' in this.remoteComponents
  ) {
    // Use dual-batch extension to send it all at once
    outpacket = msg = {
      responses: this.outbox.responses,
      requests : this.outbox.requests
    };
    // Setting length=0 would preserve references and we want to renew them
    this.outbox.responses = [];
    this.outbox.requests = [];
  } else if (iRes > 0) {
    // Responses have priority over requests
    if (iRes > 1) {
      outpacket.responses = msg = this.outbox.responses;
      this.outbox.responses = [];
    } else {
      outpacket.responses.push(msg = this.outbox.responses.pop());
    }
  } else if (iReq > 0) {
    if (iReq > 1) {
      outpacket.requests = msg = this.outbox.requests;
      this.outbox.requests = [];
    } else {
      outpacket.requests.push(msg = this.outbox.requests.pop());
    }
  } else {
    return this;
  }

  // Send msg using callback
  setImmediate(
    callback,
    JSON.stringify(msg),
    confirmTransmit.bind(this, outpacket)
  );

  return this;
}

/**
 * Callback invoked by transmit()
 *
 * @callback JRPC~transmitCallback
 *
 * @param {string} msg                        Message to send out
 * @param {JRPC~transmitConfirmCallback} next Callback handling errors
 */

/**
 * Set transmitter callback permanently
 *
 * @param {JRPC~transmitCallback} callback Transmission handler
 *
 * @return {JRPC} This instance, for chaining
 */
function setTransmitter(callback) {
  this.transmitter = callback;
  return this.transmit();
}

/**
 * Handle transmission errors
 *
 * @type {JRPC~transmitConfirmCallback}
 *
 * @param {Object}  outpacket Outbox data of the attempted transmission
 * @param {boolean} err       Anything non-falsey means an error occured
 *
 * @return {undefined} No return value
 */
function confirmTransmit(outpacket, err) {
  if (this.active && err) {
    // Roll it all back into outbox (which may not be empty anymore)
    if (outpacket.responses.length > 0) {
      Array.prototype.push.apply(this.outbox.responses, outpacket.responses);
    }
    if (outpacket.requests.length > 0) {
      Array.prototype.push.apply(this.outbox.requests, outpacket.requests);
    }
  }
}

/**
 * Handle incoming message
 *
 * @param {string} msg JSON message to parse
 *
 * @return {JRPC} This instance, for chaining
 */
function receive(msg) {
  var requests = [];
  var responses = [];

  if (!this.active) {
    return this;
  }

  // If we got JSON, parse it
  if (typeof msg === 'string') {
    try {
      msg = JSON.parse(msg);
    } catch (e) {
      // The specification doesn't force us to respond in error, ignoring
      return this;
    }
  }

  // If we get a standard single-type batch, dispatch it
  if (msg.constructor === Array) {
    if (msg.length === 0) {
      return this;
    }
    // Hint of request batch
    if (typeof msg[0].method === 'string') {
      requests = msg;
    } else {
      responses = msg;
    }
  } else if (typeof msg === 'object') {
    // Could we be a 'dual-batch' extended message?
    if (
      typeof msg.requests !== 'undefined'
      && typeof msg.responses !== 'undefined'
    ) {
      requests = msg.requests;
      responses = msg.responses;
    } else if (typeof msg.method === 'string') {
      // We're a single request
      requests.push(msg);
    } else {
      // We must be a single response
      responses.push(msg);
    }
  }

  responses.forEach(deliverResponse.bind(this));
  requests.forEach(serveRequest.bind(this));
  return this;
}

/**
 * Handshake to discover remote extended capabilities
 *
 * @return {JRPC} This instance, for chaining
 */
function upgrade() {
  if (!this.active) {
    return this;
  }
  return this.call(
    'system.listComponents',
    this.localComponents,
    (function(err, result) {
      if (!err && typeof result === 'object') {
        this.remoteComponents = result;
        this.remoteComponents['system._upgraded'] = true;
      }
    }).bind(this)
  );
}

// Client side

/**
 * Queue up a remote method call
 *
 * @param {string}               methodName Name of method to call
 * @param {(Object|Array|null)}  [params]   Parameters
 * @param {JRPC~receiveCallback} [next]     Callback to receive result
 *
 * @return {JRPC} This instance, for chaining
 */
function call(methodName, params, next) {
  var request = {
    jsonrpc: '2.0',
    method : methodName
  };

  if (!this.active) {
    return this;
  }

  if (typeof params === 'function') {
    next = params;
    params = null;
  }

  if (
    'system._upgraded' in this.remoteComponents
    && !(methodName in this.remoteComponents)
  ) {
    // We're upgraded, yet method name isn't found, immediate error!
    if (typeof next === 'function') {
      setImmediate(next, {
        code   : -32601,
        message: 'Unknown remote method'
      });
    }
    return this;
  }

  if (typeof params === 'object') {
    request.params = params;
  }

  this.serial++;
  if (typeof next === 'function') {
    request.id = this.serial;
    this.inbox[this.serial] = next;
  }
  this.outbox.requests.push(request);

  // If we're interactive, send the new request
  this.transmit();

  if (typeof next !== 'function') {
    return this;
  }
  if (this.remoteTimeout > 0) {
    this.outTimers[this.serial] = setTimeout(
      deliverResponse.bind(
        this,
        {
          jsonrpc: '2.0',
          id     : this.serial,
          error  : {
            code   : -1000,
            message: 'Timed out waiting for response'
          }
        }
      ),
      this.remoteTimeout
    );
  } else {
    this.outTimers[this.serial] = true;  // Placeholder
  }

  return this;
}

/**
 * Callback invoked when remote results are ready
 *
 * @callback JRPC~receiveCallback
 *
 * @param {boolean} err    True if the result is an error or unavailable
 * @param {Object}  result The result from the remote method
 *
 * @return {undefined} No return value
 */

/**
 * Deliver a received result
 *
 * @param {Object}  res     The single result to parse
 *
 * @return {undefined} No return value
 */
function deliverResponse(res) {
  var err = false;
  var result = null;

  if (this.active && 'id' in res && res['id'] in this.outTimers) {
    clearTimeout(this.outTimers[res['id']]);  // Passing true instead of a timeout is safe
    delete this.outTimers[res['id']];
  } else {
    // Silently ignoring second response to same request
    return;
  }

  if (res['id'] in this.inbox) {
    if ('error' in res) {
      err = res['error'];
    } else {
      result = res['result'];
    }
    setImmediate(this.inbox[res['id']], err, result);
    delete this.inbox[res['id']];
  }
  // Silently ignore timeout duplicate and malformed responses
}

// Server side

/**
 * Expose a single or collection of methods to remote end
 *
 * @param {(Object|String)}      subject    Name of method or direct object
 * @param {JRPC~serviceCallback} [callback] Callback to handle requests
 *
 * @return {JRPC} This instance, for chaining
 */
function expose(subject, callback) {
  var name;

  if (!this.active) {
    return this;
  }

  if (typeof subject === 'string') {
    this.localComponents[subject] = true;
    this.exposed[subject] = callback;
  } else if (typeof subject === 'object') {
    for (name in subject) {
      if (subject.hasOwnProperty(name)) {
        this.localComponents[name] = true;
        this.exposed[name] = subject[name];
      }
    }
  }

  return this;
}

/**
 * Callback invoked to handle calls to our side's methods
 *
 * @callback JRPC~serviceCallback
 *
 * @param {(Object|Array|null)}        params Parameters received
 * @param {JRPC~serviceResultCallback} next   Callback to send your result
 *
 * @return {undefined} No return value
 */

/**
 * Serve a request we received
 *
 * @param {Object} request Request to parse
 *
 * @return {undefined} No return value
 */
function serveRequest(request) {
  var id = null;
  var params = null;

  if (!this.active || typeof request !== 'object' || request === null) {
    return;
  }

  if (!(typeof request.jsonrpc === 'string' && request.jsonrpc === '2.0')) {
    return;
  }

  id = (typeof request.id !== 'undefined' ? request.id : null);
  if (typeof request.method !== 'string') {
    if (id !== null) {
      this.localTimers[id] = true;
      setImmediate(sendResponse.bind(this, id, -32600));
    }
    return;
  }

  if (!(request.method in this.exposed)) {
    if (id !== null) {
      this.localTimers[id] = true;
      setImmediate(sendResponse.bind(this, id, -32601));
    }
    return;
  }

  if ('params' in request) {
    if (typeof request['params'] === 'object') {
      params = request['params'];
    } else {
      if (id !== null) {
        this.localTimers[id] = true;
        setImmediate(sendResponse.bind(this, id, -32602));
      }
      return;
    }
  }

  if (id !== null) {
    if (this.localTimeout > 0) {
      this.localTimers[id] = setTimeout(
        sendResponse.bind(
          this,
          id,
          {
            code   : -1002,
            message: 'Method handler timed out'
          }
        ),
        this.localTimeout
      );
    } else {
      this.localTimers[id] = true;
    }
  }
  setImmediate(
    this.exposed[request.method],
    params,
    sendResponse.bind(this, id)
  );

  return;
}

/**
 * Handle local method results
 *
 * @type {JRPC~serviceResultCallback}
 *
 * @param {number}  id        Serial number, bound, no need to supply
 * @param {boolean} err       Anything non-falsey means error and is sent
 * @param {Object}  result    Any result you wish to produce
 *
 * @return {undefined} No return value
 */
function sendResponse(id, err, result) {
  var response = {
    jsonrpc: '2.0',
    id     : id
  };

  if (id === null) {
    return;
  }

  if (this.active && id in this.localTimers) {
    clearTimeout(this.localTimers[id]);  // Passing true instead of a timeout is safe
    delete this.localTimers[id];
  } else {
    // Silently ignoring second response to same request
    return;
  }

  if (typeof err !== 'undefined' && err !== null && err !== false) {
    if (typeof err === 'number') {
      response.error = {
        code   : err,
        message: 'error'
      };
    } else if (err === true) {
      response.error = {
        code   : -1,
        message: 'error'
      };
    } else if (typeof err === 'string') {
      response.error = {
        code   : -1,
        message: err
      };
    } else if (
      typeof err === 'object'
      && 'code' in err
      && 'message' in err
    ) {
      response.error = err;
    } else {
      response.error = {
        code   : -2,
        message: 'error',
        data   : err
      };
    }
  } else {
    response.result = result;
  }
  this.outbox.responses.push(response);

  // If we're interactive, send the new response
  this.transmit();
}

// Public methods

JRPC.prototype.shutdown = shutdown;
JRPC.prototype.call = call;
JRPC.prototype.notify = call;
JRPC.prototype.expose = expose;
JRPC.prototype.upgrade = upgrade;
JRPC.prototype.receive = receive;
JRPC.prototype.transmit = transmit;
JRPC.prototype.setTransmitter = setTransmitter;

// Support Bluebird automatically if it's globally available

if (typeof Promise.promisify === 'function') {
  JRPC.prototype.callAsync = Promise.promisify(call);
}

module.exports = JRPC;
<commit_msg>Don't assume Promise exists (fixes #10)<commit_after>/*! JRPC v3.1.0
 * <https://github.com/vphantom/js-jrpc>
 * Copyright 2016 Stéphane Lavergne
 * Free software under MIT License: <https://opensource.org/licenses/MIT> */

'use strict';

global.setImmediate = require('timers').setImmediate;

/**
 * Constructor
 *
 * @typedef {Object} JRPC
 *
 * @param {Object} [options] Options to initialize with
 *
 * @return {undefined} No return value
 */
function JRPC(options) {
  this.active = true;
  this.transmitter = null;
  this.remoteTimeout = 60000;
  this.localTimeout = 0;
  this.serial = 0;
  this.outbox = {
    requests : [],
    responses: []
  };
  this.inbox = {};
  this.localTimers = {};
  this.outTimers = {};
  this.localComponents = {
    'system.listComponents'      : true,
    'system.extension.dual-batch': true
  };
  this.remoteComponents = {};
  this.exposed = {};

  this.exposed['system.listComponents'] = (function(params, next) {
    if (typeof params === 'object' && params !== null) {
      this.remoteComponents = params;
      this.remoteComponents['system._upgraded'] = true;
    }
    return next(null, this.localComponents);
  }).bind(this);

  this.exposed['system.extension.dual-batch'] = function(params, next) {
    return next(null, true);
  };

  if (typeof options === 'object') {
    if (
      'remoteTimeout' in options
      && typeof options['remoteTimeout'] === 'number'
    ) {
      this.remoteTimeout = options['remoteTimeout'] * 1000;
    }

    if (
      'localTimeout' in options
      && typeof options['localTimeout'] === 'number'
    ) {
      this.localTimeout = options['localTimeout'] * 1000;
    }
  }
}

/**
 * Semi-destructor for limbo conditions
 *
 * When we lose connection permanently, we help garbage collection by removing
 * as many references as we can, including cancelling any outstanding timers.
 * We may still get some callbacks, but they will immediately return.
 *
 * @return {undefined} No return value
 */
function shutdown() {
  var instance = this;

  instance.active = false;
  instance.transmitter = null;
  instance.remoteTimeout = 0;
  instance.localTimeout = 0;
  instance.localComponents = {};
  instance.remoteComponents = {};
  instance.outbox.requests.length = 0;
  instance.outbox.responses.length = 0;
  instance.inbox = {};
  instance.exposed = {};

  Object.keys(instance.localTimers).forEach(function(key) {
    clearTimeout(instance.localTimers[key]);
    delete instance.localTimers[key];
  });

  Object.keys(instance.outTimers).forEach(function(key) {
    clearTimeout(instance.outTimers[key]);
    delete instance.outTimers[key];
  });

  return instance;
}

// I/O

/**
 * Send a message if there is something in the queue
 *
 * @param {JRPC~transmitCallback} callback Transmission handler
 *
 * @return {JRPC} This instance, for chaining
 */
function transmit(callback) {
  // Will call next(data, next)
  // Expect OUR next to be called with (err) so we know if it worked
  var iRes;
  var iReq;
  var msg = null;
  var outpacket = {
    responses: [],
    requests : []
  };

  if (typeof callback !== 'function') {
    callback = this.transmitter;
  }
  if (!this.active || typeof callback !== 'function') {
    return this;
  }

  iRes = this.outbox.responses.length;
  iReq = this.outbox.requests.length;
  if (
    iRes > 0
    && iReq > 0
    && 'system.extension.dual-batch' in this.remoteComponents
  ) {
    // Use dual-batch extension to send it all at once
    outpacket = msg = {
      responses: this.outbox.responses,
      requests : this.outbox.requests
    };
    // Setting length=0 would preserve references and we want to renew them
    this.outbox.responses = [];
    this.outbox.requests = [];
  } else if (iRes > 0) {
    // Responses have priority over requests
    if (iRes > 1) {
      outpacket.responses = msg = this.outbox.responses;
      this.outbox.responses = [];
    } else {
      outpacket.responses.push(msg = this.outbox.responses.pop());
    }
  } else if (iReq > 0) {
    if (iReq > 1) {
      outpacket.requests = msg = this.outbox.requests;
      this.outbox.requests = [];
    } else {
      outpacket.requests.push(msg = this.outbox.requests.pop());
    }
  } else {
    return this;
  }

  // Send msg using callback
  setImmediate(
    callback,
    JSON.stringify(msg),
    confirmTransmit.bind(this, outpacket)
  );

  return this;
}

/**
 * Callback invoked by transmit()
 *
 * @callback JRPC~transmitCallback
 *
 * @param {string} msg                        Message to send out
 * @param {JRPC~transmitConfirmCallback} next Callback handling errors
 */

/**
 * Set transmitter callback permanently
 *
 * @param {JRPC~transmitCallback} callback Transmission handler
 *
 * @return {JRPC} This instance, for chaining
 */
function setTransmitter(callback) {
  this.transmitter = callback;
  return this.transmit();
}

/**
 * Handle transmission errors
 *
 * @type {JRPC~transmitConfirmCallback}
 *
 * @param {Object}  outpacket Outbox data of the attempted transmission
 * @param {boolean} err       Anything non-falsey means an error occured
 *
 * @return {undefined} No return value
 */
function confirmTransmit(outpacket, err) {
  if (this.active && err) {
    // Roll it all back into outbox (which may not be empty anymore)
    if (outpacket.responses.length > 0) {
      Array.prototype.push.apply(this.outbox.responses, outpacket.responses);
    }
    if (outpacket.requests.length > 0) {
      Array.prototype.push.apply(this.outbox.requests, outpacket.requests);
    }
  }
}

/**
 * Handle incoming message
 *
 * @param {string} msg JSON message to parse
 *
 * @return {JRPC} This instance, for chaining
 */
function receive(msg) {
  var requests = [];
  var responses = [];

  if (!this.active) {
    return this;
  }

  // If we got JSON, parse it
  if (typeof msg === 'string') {
    try {
      msg = JSON.parse(msg);
    } catch (e) {
      // The specification doesn't force us to respond in error, ignoring
      return this;
    }
  }

  // If we get a standard single-type batch, dispatch it
  if (msg.constructor === Array) {
    if (msg.length === 0) {
      return this;
    }
    // Hint of request batch
    if (typeof msg[0].method === 'string') {
      requests = msg;
    } else {
      responses = msg;
    }
  } else if (typeof msg === 'object') {
    // Could we be a 'dual-batch' extended message?
    if (
      typeof msg.requests !== 'undefined'
      && typeof msg.responses !== 'undefined'
    ) {
      requests = msg.requests;
      responses = msg.responses;
    } else if (typeof msg.method === 'string') {
      // We're a single request
      requests.push(msg);
    } else {
      // We must be a single response
      responses.push(msg);
    }
  }

  responses.forEach(deliverResponse.bind(this));
  requests.forEach(serveRequest.bind(this));
  return this;
}

/**
 * Handshake to discover remote extended capabilities
 *
 * @return {JRPC} This instance, for chaining
 */
function upgrade() {
  if (!this.active) {
    return this;
  }
  return this.call(
    'system.listComponents',
    this.localComponents,
    (function(err, result) {
      if (!err && typeof result === 'object') {
        this.remoteComponents = result;
        this.remoteComponents['system._upgraded'] = true;
      }
    }).bind(this)
  );
}

// Client side

/**
 * Queue up a remote method call
 *
 * @param {string}               methodName Name of method to call
 * @param {(Object|Array|null)}  [params]   Parameters
 * @param {JRPC~receiveCallback} [next]     Callback to receive result
 *
 * @return {JRPC} This instance, for chaining
 */
function call(methodName, params, next) {
  var request = {
    jsonrpc: '2.0',
    method : methodName
  };

  if (!this.active) {
    return this;
  }

  if (typeof params === 'function') {
    next = params;
    params = null;
  }

  if (
    'system._upgraded' in this.remoteComponents
    && !(methodName in this.remoteComponents)
  ) {
    // We're upgraded, yet method name isn't found, immediate error!
    if (typeof next === 'function') {
      setImmediate(next, {
        code   : -32601,
        message: 'Unknown remote method'
      });
    }
    return this;
  }

  if (typeof params === 'object') {
    request.params = params;
  }

  this.serial++;
  if (typeof next === 'function') {
    request.id = this.serial;
    this.inbox[this.serial] = next;
  }
  this.outbox.requests.push(request);

  // If we're interactive, send the new request
  this.transmit();

  if (typeof next !== 'function') {
    return this;
  }
  if (this.remoteTimeout > 0) {
    this.outTimers[this.serial] = setTimeout(
      deliverResponse.bind(
        this,
        {
          jsonrpc: '2.0',
          id     : this.serial,
          error  : {
            code   : -1000,
            message: 'Timed out waiting for response'
          }
        }
      ),
      this.remoteTimeout
    );
  } else {
    this.outTimers[this.serial] = true;  // Placeholder
  }

  return this;
}

/**
 * Callback invoked when remote results are ready
 *
 * @callback JRPC~receiveCallback
 *
 * @param {boolean} err    True if the result is an error or unavailable
 * @param {Object}  result The result from the remote method
 *
 * @return {undefined} No return value
 */

/**
 * Deliver a received result
 *
 * @param {Object}  res     The single result to parse
 *
 * @return {undefined} No return value
 */
function deliverResponse(res) {
  var err = false;
  var result = null;

  if (this.active && 'id' in res && res['id'] in this.outTimers) {
    clearTimeout(this.outTimers[res['id']]);  // Passing true instead of a timeout is safe
    delete this.outTimers[res['id']];
  } else {
    // Silently ignoring second response to same request
    return;
  }

  if (res['id'] in this.inbox) {
    if ('error' in res) {
      err = res['error'];
    } else {
      result = res['result'];
    }
    setImmediate(this.inbox[res['id']], err, result);
    delete this.inbox[res['id']];
  }
  // Silently ignore timeout duplicate and malformed responses
}

// Server side

/**
 * Expose a single or collection of methods to remote end
 *
 * @param {(Object|String)}      subject    Name of method or direct object
 * @param {JRPC~serviceCallback} [callback] Callback to handle requests
 *
 * @return {JRPC} This instance, for chaining
 */
function expose(subject, callback) {
  var name;

  if (!this.active) {
    return this;
  }

  if (typeof subject === 'string') {
    this.localComponents[subject] = true;
    this.exposed[subject] = callback;
  } else if (typeof subject === 'object') {
    for (name in subject) {
      if (subject.hasOwnProperty(name)) {
        this.localComponents[name] = true;
        this.exposed[name] = subject[name];
      }
    }
  }

  return this;
}

/**
 * Callback invoked to handle calls to our side's methods
 *
 * @callback JRPC~serviceCallback
 *
 * @param {(Object|Array|null)}        params Parameters received
 * @param {JRPC~serviceResultCallback} next   Callback to send your result
 *
 * @return {undefined} No return value
 */

/**
 * Serve a request we received
 *
 * @param {Object} request Request to parse
 *
 * @return {undefined} No return value
 */
function serveRequest(request) {
  var id = null;
  var params = null;

  if (!this.active || typeof request !== 'object' || request === null) {
    return;
  }

  if (!(typeof request.jsonrpc === 'string' && request.jsonrpc === '2.0')) {
    return;
  }

  id = (typeof request.id !== 'undefined' ? request.id : null);
  if (typeof request.method !== 'string') {
    if (id !== null) {
      this.localTimers[id] = true;
      setImmediate(sendResponse.bind(this, id, -32600));
    }
    return;
  }

  if (!(request.method in this.exposed)) {
    if (id !== null) {
      this.localTimers[id] = true;
      setImmediate(sendResponse.bind(this, id, -32601));
    }
    return;
  }

  if ('params' in request) {
    if (typeof request['params'] === 'object') {
      params = request['params'];
    } else {
      if (id !== null) {
        this.localTimers[id] = true;
        setImmediate(sendResponse.bind(this, id, -32602));
      }
      return;
    }
  }

  if (id !== null) {
    if (this.localTimeout > 0) {
      this.localTimers[id] = setTimeout(
        sendResponse.bind(
          this,
          id,
          {
            code   : -1002,
            message: 'Method handler timed out'
          }
        ),
        this.localTimeout
      );
    } else {
      this.localTimers[id] = true;
    }
  }
  setImmediate(
    this.exposed[request.method],
    params,
    sendResponse.bind(this, id)
  );

  return;
}

/**
 * Handle local method results
 *
 * @type {JRPC~serviceResultCallback}
 *
 * @param {number}  id        Serial number, bound, no need to supply
 * @param {boolean} err       Anything non-falsey means error and is sent
 * @param {Object}  result    Any result you wish to produce
 *
 * @return {undefined} No return value
 */
function sendResponse(id, err, result) {
  var response = {
    jsonrpc: '2.0',
    id     : id
  };

  if (id === null) {
    return;
  }

  if (this.active && id in this.localTimers) {
    clearTimeout(this.localTimers[id]);  // Passing true instead of a timeout is safe
    delete this.localTimers[id];
  } else {
    // Silently ignoring second response to same request
    return;
  }

  if (typeof err !== 'undefined' && err !== null && err !== false) {
    if (typeof err === 'number') {
      response.error = {
        code   : err,
        message: 'error'
      };
    } else if (err === true) {
      response.error = {
        code   : -1,
        message: 'error'
      };
    } else if (typeof err === 'string') {
      response.error = {
        code   : -1,
        message: err
      };
    } else if (
      typeof err === 'object'
      && 'code' in err
      && 'message' in err
    ) {
      response.error = err;
    } else {
      response.error = {
        code   : -2,
        message: 'error',
        data   : err
      };
    }
  } else {
    response.result = result;
  }
  this.outbox.responses.push(response);

  // If we're interactive, send the new response
  this.transmit();
}

// Public methods

JRPC.prototype.shutdown = shutdown;
JRPC.prototype.call = call;
JRPC.prototype.notify = call;
JRPC.prototype.expose = expose;
JRPC.prototype.upgrade = upgrade;
JRPC.prototype.receive = receive;
JRPC.prototype.transmit = transmit;
JRPC.prototype.setTransmitter = setTransmitter;

// Support Bluebird automatically if it's globally available

if (typeof Promise !== 'undefined' && typeof Promise.promisify === 'function') {
  JRPC.prototype.callAsync = Promise.promisify(call);
}

module.exports = JRPC;
<|endoftext|>


<commit_before>(function() {
  /* globals define */
  'use strict';

  function l(config) {
    var i = function() {
      i.c(arguments);
    };
    i.q = [];
    i.c = function(args) {
      i.q.push(args);
    };

    window.Intercom = i;

    var d = document;
    var s = d.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = 'https://widget.intercom.io/widget/' + config.intercom.appId;
    var x = d.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
  }

  var ic = window.Intercom;
  if (typeof ic === 'function') {
    ic('reattach_activator');
    ic('update', {});
  }

  function generateModule(name, values) {
    define(name, [], function() {
      'use strict'; // jshint ignore:line

      return values;
    });
  }

  generateModule('intercom', {
    default: function() {
      return window.Intercom.apply(null, arguments);
    },
    _setup: l
  });
})();
<commit_msg>Make sure intercom object is on the window before trying to call apply<commit_after>(function() {
  /* globals define */
  'use strict';

  function l(config) {
    var i = function() {
      i.c(arguments);
    };
    i.q = [];
    i.c = function(args) {
      i.q.push(args);
    };

    window.Intercom = i;

    var d = document;
    var s = d.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = 'https://widget.intercom.io/widget/' + config.intercom.appId;
    var x = d.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
  }

  var ic = window.Intercom;
  if (typeof ic === 'function') {
    ic('reattach_activator');
    ic('update', {});
  }

  function generateModule(name, values) {
    define(name, [], function() {
      'use strict'; // jshint ignore:line

      return values;
    });
  }

  generateModule('intercom', {
    default: function() {
      if (window.Intercom && typeof window.Intercom === 'function') {
        return window.Intercom.apply(null, arguments);
      }
    },
    _setup: l
  });
})();
<|endoftext|>


<commit_before>var config = require('clientconfig');
var log = require('bows')('fenix');
var cannon = require('client/js/auth/cannon');
var fenix = require('fenixedu');
var fenixAuth = {};
var xhr = require('xhr')

fenixAuth.login = function(cb) {
  var authUrl = fenix.auth.getAuthUrl()

  xhr({
    uri: authUrl,
    useXDR: true,
  }, function (err, resp, body) {
    log(err);
  });
};

module.exports = fenixAuth;
<commit_msg>fenix module init<commit_after>var config = require('clientconfig');
var log = require('bows')('fenix');
var cannon = require('client/js/auth/cannon');
var fenix = require('fenixedu');
var fenixAuth = {};
var xhr = require('xhr');

fenix = fenix(config.fenix);

fenixAuth.login = function(cb) {
  var authUrl = fenix.auth.getAuthUrl();

  xhr({
    uri: authUrl,
    useXDR: true,
  }, function (err, resp, body) {
    log(err);
  });
};

module.exports = fenixAuth;
<|endoftext|>


<commit_before>var clc = require('cli-color');
var maxNickLen = 12;
var fileBuf = 4096; // how many characters of file to remember
var path = require('path');
var myNick = "FruitieX";
var hilight_re = new RegExp(".*" + myNick + ".*", 'i');
var ansi_escape_re = /\x1b[^m]*m/;

var separatorColor = clc.xterm(239);
var numColor = clc.xterm(232).bgXterm(255);
var chanColor = clc.xterm(255).bgXterm(239);
var myNickColor = 1;
var hilightColor = 3;

// we need this in global scope so we can remove the event listeners!
var out;
var openChan = function(filePath) {
	var outFile = filePath + '/out';
	var inFile = filePath + '/in';
	var file = require('fs').readFileSync(outFile, 'utf8');

	var bn = path.basename(filePath);
	var num_s = ' ' + bn.substring(0, bn.indexOf('_')) + ' ';
	var num = numColor(num_s);
	var chan_s = ' ' + bn.substring(bn.indexOf('_') + 1, bn.length) + ' ';
	var chan = chanColor(chan_s);

	var printLine = function(line) {
		var hilight = false;

		// clear channel name
		process.stdout.write('\r' + Array(num_s.length + chan_s.length + 1).join(' ') + '\r');

		// remove timestamps
		line = line.replace(/^([^ ]+ ){2}/, '');
		line = line.split(' ');
		// remove <> around nick
		var nick = line[0].substring(1, line[0].length - 1);

		if(nick === myNick) {
			clrnick = myNickColor;
		} else {
			// nick color, avoids dark colors
			var clrnick = 0;
			for(var i = 0; i < nick.length; i++) {
				clrnick += nick.charCodeAt(i);
			}
			clrnick = Math.pow(clrnick, 2) + clrnick * 2;
			clrnick = clrnick % 255;
			switch(clrnick) {
				case 18: case 22: case 23: case 24:
					clrnick += 3; break;
				case 52: case 53: case 54: case 55: case 56: case 57: case 88: case 89:
					clrnick += 6; break;
				case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239:
					clrnick += 8; break;
				case 0: case 8: case 19: case 22:
					clrnick++; break;
			}
		}

		// limit nicklen
		nick = nick.substr(0, maxNickLen);
		// align nicks
		process.stdout.write(Array(maxNickLen - nick.length + 1).join(' '));
		process.stdout.write(clc.xterm(clrnick)(nick) + separatorColor(':'));
		process.stdout.write(' ');

		// remove nick from line array, now contains space separated text message
		line.shift();
		line = line.join(' ');
		line = line.replace(ansi_escape_re, '');

		if(line.match(hilight_re))
			hilight = true;

		var textColor = 15;
		if (nick === myNick)
			textColor = myNickColor;
		else if (hilight)
			textColor = hilightColor;

		// separator takes up 1 char + whitespace
		var availWidth = process.stdout.columns - maxNickLen - 2;

		// TODO: wrap at whitespace
		for (var i = 0; i < Math.ceil(line.length / availWidth); i++) {
			var curLine = line.substr(i * availWidth, availWidth);

			// empty space on line wrap
			if (i > 0)
				process.stdout.write(Array(process.stdout.columns - availWidth + 1).join(' '));

			process.stdout.write(clc.xterm(textColor)(curLine));
			process.stdout.write('\n');
		}

		// print channel name again
		process.stdout.write(num + chan + ' ');
	};

	// log entire file
	var printFile = function(file) {
		var start = 0;
		while (start < file.length) {
			var end = file.indexOf('\n', start);
			if(end === -1)
				break;
			printLine(file.substring(start, end));
			start = end + 1;
		}
	};

	// limit file to size fileBuf
	if(file.length >= fileBuf) {
		file = file.substr(file.length - fileBuf, file.length);
		file = file.substr(file.indexOf("\n") + 1, file.length);
	}

	// set raw mode
	var stdin = process.stdin;
	stdin.setRawMode(true);
	stdin.resume();
	stdin.setEncoding('utf8');

	// handle 'q', 'ctrl-c' by quitting
	stdin.on('data', function(key) {
		if(key == 'q' || key == '\u0003') process.exit();
	});

	// clear terminal and print
	process.stdout.write('\u001B[2J\u001B[0;0f');
	printFile(file);

	// watch file
	Tail = require('tail').Tail;
	out = new Tail(outFile);

	out.on('line', function(data) {
		file += data + '\n';
		// limit file to size fileBuf
		if(file.length >= fileBuf) {
			file = file.substr(file.length - fileBuf, file.length);
			file = file.substr(file.indexOf("\n") + 1, file.length);
		}

		// print the line
		printLine(data);
	});

	process.stdout.on('resize', function() {
		process.stdout.write('\u001B[2J\u001B[0;0f');
		printFile(file);
	});
};

// TODO: changing channels?
var currentChan = process.argv[2];
openChan(process.argv[2]);
<commit_msg>word wrap<commit_after>var clc = require('cli-color');
var maxNickLen = 12;
var fileBuf = 4096; // how many characters of file to remember
var path = require('path');
var myNick = "FruitieX";
var hilight_re = new RegExp(".*" + myNick + ".*", 'i');
var ansi_escape_re = /\x1b[^m]*m/;

var separatorColor = clc.xterm(239);
var numColor = clc.xterm(232).bgXterm(255);
var chanColor = clc.xterm(255).bgXterm(239);
var myNickColor = 1;
var hilightColor = 3;

// we need this in global scope so we can remove the event listeners!
var out;
var openChan = function(filePath) {
	var outFile = filePath + '/out';
	var inFile = filePath + '/in';
	var file = require('fs').readFileSync(outFile, 'utf8');

	var bn = path.basename(filePath);
	var num_s = ' ' + bn.substring(0, bn.indexOf('_')) + ' ';
	var num = numColor(num_s);
	var chan_s = ' ' + bn.substring(bn.indexOf('_') + 1, bn.length) + ' ';
	var chan = chanColor(chan_s);

	var printLine = function(line) {
		var hilight = false;

		// clear channel name
		process.stdout.write('\r' + Array(num_s.length + chan_s.length + 1).join(' ') + '\r');

		// remove timestamps
		line = line.replace(/^([^ ]+ ){2}/, '');
		line = line.split(' ');
		// remove <> around nick
		var nick = line[0].substring(1, line[0].length - 1);

		if(nick === myNick) {
			clrnick = myNickColor;
		} else {
			// nick color, avoids dark colors
			var clrnick = 0;
			for(var i = 0; i < nick.length; i++) {
				clrnick += nick.charCodeAt(i);
			}
			clrnick = Math.pow(clrnick, 2) + clrnick * 2;
			clrnick = clrnick % 255;
			switch(clrnick) {
				case 18: case 22: case 23: case 24:
					clrnick += 3; break;
				case 52: case 53: case 54: case 55: case 56: case 57: case 88: case 89:
					clrnick += 6; break;
				case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239:
					clrnick += 8; break;
				case 0: case 8: case 19: case 22:
					clrnick++; break;
			}
		}

		// limit nicklen
		nick = nick.substr(0, maxNickLen);
		// align nicks
		process.stdout.write(Array(maxNickLen - nick.length + 1).join(' '));
		process.stdout.write(clc.xterm(clrnick)(nick) + separatorColor(':'));
		process.stdout.write(' ');

		// remove nick from line array, now contains space separated text message
		line.shift();
		line = line.join(' ');
		line = line.replace(ansi_escape_re, '');

		if(line.match(hilight_re))
			hilight = true;

		var textColor = 15;
		if (nick === myNick)
			textColor = myNickColor;
		else if (hilight)
			textColor = hilightColor;

		// separator takes up 1 char + whitespace
		var availWidth = process.stdout.columns - maxNickLen - 2;

		var wrappedChars = 0;
		var i = 0;

		while(i * availWidth - wrappedChars < line.length) {
			var start = i * availWidth - wrappedChars;
			var curLine = line.substr(start, availWidth);
			// remove leading space on next line
			curLine.replace(/^\s+/, '');
			// line wrap at word boundary only if there is whitespace on this line
			if(start + availWidth < line.length && curLine.lastIndexOf(' ') !== -1) {
				curLine = curLine.slice(0, curLine.lastIndexOf(' '));
				// remove whitespace
				wrappedChars--;
			}

			wrappedChars += availWidth - curLine.length;

			// empty space on line wrap
			if (i > 0)
				process.stdout.write(Array(process.stdout.columns - availWidth + 1).join(' '));

			process.stdout.write(clc.xterm(textColor)(curLine));
			process.stdout.write('\n');
			i++;
		}

		// print channel name again
		process.stdout.write(num + chan + ' ');
	};

	// log entire file
	var printFile = function(file) {
		var start = 0;
		while (start < file.length) {
			var end = file.indexOf('\n', start);
			if(end === -1)
				break;
			printLine(file.substring(start, end));
			start = end + 1;
		}
	};

	// limit file to size fileBuf
	if(file.length >= fileBuf) {
		file = file.substr(file.length - fileBuf, file.length);
		file = file.substr(file.indexOf("\n") + 1, file.length);
	}

	// set raw mode
	var stdin = process.stdin;
	stdin.setRawMode(true);
	stdin.resume();
	stdin.setEncoding('utf8');

	// handle 'q', 'ctrl-c' by quitting
	stdin.on('data', function(key) {
		if(key == 'q' || key == '\u0003') process.exit();
	});

	// clear terminal and print
	process.stdout.write('\u001B[2J\u001B[0;0f');
	printFile(file);

	// watch file
	Tail = require('tail').Tail;
	out = new Tail(outFile);

	out.on('line', function(data) {
		file += data + '\n';
		// limit file to size fileBuf
		if(file.length >= fileBuf) {
			file = file.substr(file.length - fileBuf, file.length);
			file = file.substr(file.indexOf("\n") + 1, file.length);
		}

		// print the line
		printLine(data);
	});

	process.stdout.on('resize', function() {
		process.stdout.write('\u001B[2J\u001B[0;0f');
		printFile(file);
	});
};

// TODO: changing channels?
var currentChan = process.argv[2];
openChan(process.argv[2]);
<|endoftext|>


<commit_before>//Actions are initiated by 'data-action' attributes on elements.
//By applying specific 'data-action' attributes to elements, global app events may occur.

Template.body.events({
    //Sign Out [data-action=signout]
    'click [data-action="signout"]': function (event) {
        clearCanvas();
        event.preventDefault(); event.stopPropagation();
        Meteor.logout(function (error) {
            if (error instanceof Error)
                console.error(error);
        })
    }

});
<commit_msg>Added correct scope to function in events.js<commit_after>//Actions are initiated by 'data-action' attributes on elements.
//By applying specific 'data-action' attributes to elements, global app events may occur.
Template.body.events({
    //Sign Out [data-action=signout]
    'click [data-action="signout"]': function (event) {
        c.clearCanvas();
        event.preventDefault(); event.stopPropagation();
        Meteor.logout(function (error) {
            if (error instanceof Error)
                console.error(error);
        })
    }

});
<|endoftext|>


<commit_before>const fs = require('fs');
import hbs from 'handlebars';
import domify from 'domify';

const {{component}} = () => {

};

{{component}}.prototype = {
  init(req, done) {
    this.dom = domify(hbs.compile(fs.readFileSync(__dirname + '/template.hbs', 'utf8'))());
    document.body.appendChild(this.dom);

    done();
  },

  animateIn(req, done) {
    done();
  },

  animateOut(req, done) {
    done();
  },

  destroy() {

  }
};

export default {{component}};<commit_msg>added Bigwheel comments<commit_after>const fs = require('fs');
import hbs from 'handlebars';
import domify from 'domify';

const {{component}} = () => {

};

{{component}}.prototype = {
  init(req, done) {
    this.dom = domify(hbs.compile(fs.readFileSync(__dirname + '/template.hbs', 'utf8'))());
    document.body.appendChild(this.dom);

    done();
  },

  animateIn(req, done) {
    // this function will be automatically called by init()
    done();
  },

  animateOut(req, done) {
    done();
  },

  destroy() {
    // this function will be automatically called by animateOut()
  }
};

export default {{component}};<|endoftext|>


<commit_before>/* globals: Stripe */

(function ($) {

  var ERRORS_CLASS = 'payment-errors';
  var ERRORS_SELECTOR = '.' + ERRORS_CLASS;

  window.StripeBundle = {
    EVENTS: {
      FORMAT_ERROR_MSG: 'cm_stripe:formatError'
    }
  };

  // -----------------------------------------------------------------------------------------------------------------
  // StriptForm
  // -----------------------------------------------------------------------------------------------------------------

  /**
   * @param form
   * @constructor
   */
  function StripeForm(form) {
    this.$form = $(form);

    console.log(this.$form);

    /**
     * @type {jQuery}
     */
    this.$errors = null;

    this.$form.submit($.proxy(this.hijackFormSubmission, this));

    this.setupErrors();
  }

  /**
   * Adds the errors element if not already found
   */
  StripeForm.prototype.setupErrors = function () {
    this.$errors = $(ERRORS_SELECTOR, this.$form);
    if (this.$errors.length === 0) {
      this.$errors = $('

');
      this.$form.prepend(this.$errors);
    }
  };

  /**
   * Event handler for intercepting the form submission & redirecting it to the Stripe card token creation script
   * @param event
   * @return {boolean}
   */
  StripeForm.prototype.hijackFormSubmission = function (event) {
    var $form = this.$form;

    // Disable the submit button to prevent repeated clicks
    $form.find('button').prop('disabled', true);

    console.log('Handling!');

    Stripe.card.createToken($form, $.proxy(this.stripeResponseHandler, this));

    // Prevent the form from submitting with the default action
    return false;
  };

  /**
   * Processes the Stripe card token creation response and assigns the token value to the hidden field
   *
   * @param {int}                                              status
   * @param {{}}                                               response
   * @param {{}}                                               response.error
   * @param {'invalid_request_error'|'api_error'|'card_error'} response.error.type
   * @param {string}                                           response.error.message
   * @param {string}                                           response.error.code
   * @param {string}                                           response.error.param
   * @param {string}                                           response.id
   * @param {{}}                                               response.card
   * @param {timestamp}                                        response.created
   * @param {string}                                           response.currency
   * @param {bool}                                             response.livemode
   * @param {'token'}                                          response.object
   * @param {bool}                                             response.used
   */
  StripeForm.prototype.stripeResponseHandler = function (status, response) {
    if (response.error) {
      var errorMessage     = response.error.message,
          errorDetails = {errorMessage: errorMessage};

      /**
       * Event: StripeBundle.EVENTS.FORMAT_ERROR_MSG
       * Object: {{errorMessage: string}}
       */
      this.$form.trigger(StripeBundle.EVENTS.FORMAT_ERROR_MSG, errorDetails);
      errorMessage = errorDetails.errorMessage;

      // Show the errors on the form
      this.$form.find('.payment-errors').html(errorMessage);
      this.$form.find('button').prop('disabled', false);
    } else {
      // response contains id and card, which contains additional card details
      var token = response.id;
      // Insert the token into the form so it gets submitted to the server
      $('.stripe-token', this.$form).val(token);
      // and submit
      this.$form.get(0).submit();
    }
  };

  $(function ($) {
    $('form.stripe-form').each(function (i, form) {
      $(form).data('stripeForm', new StripeForm(form));
    });
  });
})(jQuery);<commit_msg>Sanitizing error message before displaying<commit_after>/* globals: Stripe */

(function ($) {

  var ERRORS_CLASS = 'payment-errors';
  var ERRORS_SELECTOR = '.' + ERRORS_CLASS;

  window.StripeBundle = {
    EVENTS: {
      FORMAT_ERROR_MSG: 'cm_stripe:formatError'
    }
  };

  // -----------------------------------------------------------------------------------------------------------------
  // StriptForm
  // -----------------------------------------------------------------------------------------------------------------

  /**
   * @param form
   * @constructor
   */
  function StripeForm(form) {
    this.$form = $(form);

    console.log(this.$form);

    /**
     * @type {jQuery}
     */
    this.$errors = null;

    this.$form.submit($.proxy(this.hijackFormSubmission, this));

    this.setupErrors();
  }

  /**
   * Adds the errors element if not already found
   */
  StripeForm.prototype.setupErrors = function () {
    this.$errors = $(ERRORS_SELECTOR, this.$form);
    if (this.$errors.length === 0) {
      this.$errors = $('

');
      this.$form.prepend(this.$errors);
    }
  };

  /**
   * Event handler for intercepting the form submission & redirecting it to the Stripe card token creation script
   * @param event
   * @return {boolean}
   */
  StripeForm.prototype.hijackFormSubmission = function (event) {
    var $form = this.$form;

    // Disable the submit button to prevent repeated clicks
    $form.find('button').prop('disabled', true);

    console.log('Handling!');

    Stripe.card.createToken($form, $.proxy(this.stripeResponseHandler, this));

    // Prevent the form from submitting with the default action
    return false;
  };

  /**
   * Processes the Stripe card token creation response and assigns the token value to the hidden field
   *
   * @param {int}                                              status
   * @param {{}}                                               response
   * @param {{}}                                               response.error
   * @param {'invalid_request_error'|'api_error'|'card_error'} response.error.type
   * @param {string}                                           response.error.message
   * @param {string}                                           response.error.code
   * @param {string}                                           response.error.param
   * @param {string}                                           response.id
   * @param {{}}                                               response.card
   * @param {timestamp}                                        response.created
   * @param {string}                                           response.currency
   * @param {bool}                                             response.livemode
   * @param {'token'}                                          response.object
   * @param {bool}                                             response.used
   */
  StripeForm.prototype.stripeResponseHandler = function (status, response) {
    if (response.error) {
      var errorMessage     = response.error.message,
          errorDetails = {errorMessage: errorMessage};

      /**
       * Event: StripeBundle.EVENTS.FORMAT_ERROR_MSG
       * Object: {{errorMessage: string}}
       */
      this.$form.trigger(StripeBundle.EVENTS.FORMAT_ERROR_MSG, errorDetails);
      errorMessage = errorDetails.errorMessage;

      // Sanitise the error message to remove HTML tags
      var sanitizer = $('

');
      sanitizer.text(errorMessage);
      errorMessage = sanitizer.html();

      // Show the errors on the form
      this.$form.find('.payment-errors').html(errorMessage);
      this.$form.find('button').prop('disabled', false);
    } else {
      // response contains id and card, which contains additional card details
      var token = response.id;
      // Insert the token into the form so it gets submitted to the server
      $('.stripe-token', this.$form).val(token);
      // and submit
      this.$form.get(0).submit();
    }
  };

  $(function ($) {
    $('form.stripe-form').each(function (i, form) {
      $(form).data('stripeForm', new StripeForm(form));
    });
  });
})(jQuery);<|endoftext|>


<commit_before>(function(global) {
  function inherit(base, fn) {
    var constructor = fn;
    constructor.prototype = base.prototype;
    return constructor;
  };

  function compare(x, y, fn) {
    if (typeof fn === "function") {
      return compare(fn(x), fn(y));
    }

    if (x === y) {
      return 0;
    }

    return x > y ? 1 : -1;
  };

  function forEach(array, fn) {
    for (var i = 0; i < array.length; ++i) {
      if (fn(array[i]) === false) {
        break;
      }
    }
  }

  var Iterator = function(parent, source) {
    var memoized;

    this.parent = parent;
    this.source = source;

    this.memoize = function() {
      if (!memoized) {
        memoized = this.toArray();
      }
      return memoized;
    };
  };

  Iterator.prototype.get = function(i) {
    return this.source ? this.source[i] : this.parent.get(i);
  };

  Iterator.prototype.length = function() {
    return this.source ? this.source.length : this.parent.length();
  };

  Iterator.prototype.each = function(fn) {
    for (var i = 0; i < this.length(); ++i) {
      if (fn(this.get(i)) === false) {
        break;
      }
    }
  };

  Iterator.prototype.reverseEach = function(fn) {
    for (var i = this.length() - 1; i >= 0; --i) {
      if (fn(this.get(i)) === false) {
        break;
      }
    }
  };

  Iterator.prototype.changeIteration = function(eachFn) {
    var parent = this.parent;

    this.each = function(action) {
      parent.each(function(e) { eachFn(action, e); });
    };
    this.reverseEach = function(action) {
      parent.reverseEach(function(e) { eachFn(action, e); });
    };
  };

  Iterator.prototype.toArray = function() {
    var array = [];
    this.each(function(e) {
      array.push(e);
    });
    return array;
  };

  Iterator.prototype.map = function(mapFn) {
    return new MapIterator(this, mapFn);
  };

  Iterator.prototype.filter = function(filterFn) {
    return new FilterIterator(this, filterFn);
  };

  Iterator.prototype.reject = function(rejectFn) {
    return new FilterIterator(this, function(e) {
      return !rejectFn(e);
    });
  };

  Iterator.prototype.reverse = function() {
    return new ReverseIterator(this);
  };

  Iterator.prototype.take = function(count) {
    return new TakeIterator(this, count);
  };

  Iterator.prototype.drop = function(count) {
    return new DropIterator(this, count);
  };

  Iterator.prototype.sortBy = function(sortFn) {
    return new SortIterator(this, sortFn);
  };

  Iterator.prototype.uniq = function() {
    return new UniqIterator(this);
  };

  var MapIterator = inherit(Iterator, function(parent, mapFn) {
    Iterator.call(this, parent);
    this.changeIteration(function(action, e) {
      return action(mapFn(e));
    });
  });

  var FilterIterator = inherit(Iterator, function(parent, filterFn) {
    Iterator.call(this, parent);
    this.changeIteration(function(action, e) {
      if (filterFn(e)) {
        return action(e);
      }
    });
  });

  var ReverseIterator = inherit(Iterator, function(parent) {
    Iterator.call(this, parent);
    this.each = parent.reverseEach;
    this.reverseEach = parent.each;
  });

  var TakeIterator = inherit(Iterator, function(parent, count) {
    Iterator.call(this, parent);
    var i = 0;
    this.changeIteration(function(action, e) {
      if (i++ >= count) { return false; }
      return action(e);
    });
  });

  var DropIterator = inherit(Iterator, function(parent, count) {
    Iterator.call(this, parent);
    var i = 0;
    this.changeIteration(function(action, e) {
      if (i++ < count) { return; }
      return action(e);
    });
  });

  var SortIterator = inherit(Iterator, function(parent, sortFn) {
    Iterator.call(this, parent);

    this.each = function(action) {
      var sorted = parent.toArray();
      sorted.sort(function(x, y) { return compare(x, y, sortFn); });
      forEach(sorted, action);
    };

    this.reverseEach = function(action) {
      var sorted = parent.toArray();
      sorted.sort(function(x, y) { return compare(y, x, sortFn); });
      forEach(sorted, action);
    };
  });

  var UniqIterator = inherit(Iterator, function(parent, count) {
    Iterator.call(this, parent);
    var set = {};
    this.changeIteration(function(action, e) {
      if (e in set) { return; }
      set[e] = true;
      return action(e);
    });
  });

  global.Lazy = function(source) {
    return new Iterator(null, source);
  };

})(window);
<commit_msg>cache length<commit_after>(function(global) {
  function inherit(base, fn) {
    var constructor = fn;
    constructor.prototype = base.prototype;
    return constructor;
  };

  function compare(x, y, fn) {
    if (typeof fn === "function") {
      return compare(fn(x), fn(y));
    }

    if (x === y) {
      return 0;
    }

    return x > y ? 1 : -1;
  };

  function forEach(array, fn) {
    for (var i = 0; i < array.length; ++i) {
      if (fn(array[i]) === false) {
        break;
      }
    }
  }

  var Iterator = function(parent, source) {
    var length, memoized;

    this.parent = parent;
    this.source = source;

    this.length = function() {
      if (typeof length === "undefined") {
        length = this.source ? this.source.length : this.parent.length();
      }
      return length;
    };

    this.memoize = function() {
      if (!memoized) {
        memoized = this.toArray();
      }
      return memoized;
    };
  };

  Iterator.prototype.get = function(i) {
    return this.source ? this.source[i] : this.parent.get(i);
  };

  Iterator.prototype.each = function(fn) {
    for (var i = 0; i < this.length(); ++i) {
      if (fn(this.get(i)) === false) {
        break;
      }
    }
  };

  Iterator.prototype.reverseEach = function(fn) {
    for (var i = this.length() - 1; i >= 0; --i) {
      if (fn(this.get(i)) === false) {
        break;
      }
    }
  };

  Iterator.prototype.changeIteration = function(eachFn) {
    var parent = this.parent;

    this.each = function(action) {
      parent.each(function(e) { eachFn(action, e); });
    };
    this.reverseEach = function(action) {
      parent.reverseEach(function(e) { eachFn(action, e); });
    };
  };

  Iterator.prototype.toArray = function() {
    var array = [];
    this.each(function(e) {
      array.push(e);
    });
    return array;
  };

  Iterator.prototype.map = function(mapFn) {
    return new MapIterator(this, mapFn);
  };

  Iterator.prototype.filter = function(filterFn) {
    return new FilterIterator(this, filterFn);
  };

  Iterator.prototype.reject = function(rejectFn) {
    return new FilterIterator(this, function(e) {
      return !rejectFn(e);
    });
  };

  Iterator.prototype.reverse = function() {
    return new ReverseIterator(this);
  };

  Iterator.prototype.take = function(count) {
    return new TakeIterator(this, count);
  };

  Iterator.prototype.drop = function(count) {
    return new DropIterator(this, count);
  };

  Iterator.prototype.sortBy = function(sortFn) {
    return new SortIterator(this, sortFn);
  };

  Iterator.prototype.uniq = function() {
    return new UniqIterator(this);
  };

  var MapIterator = inherit(Iterator, function(parent, mapFn) {
    Iterator.call(this, parent);
    this.changeIteration(function(action, e) {
      return action(mapFn(e));
    });
  });

  var FilterIterator = inherit(Iterator, function(parent, filterFn) {
    Iterator.call(this, parent);
    this.changeIteration(function(action, e) {
      if (filterFn(e)) {
        return action(e);
      }
    });
  });

  var ReverseIterator = inherit(Iterator, function(parent) {
    Iterator.call(this, parent);
    this.each = parent.reverseEach;
    this.reverseEach = parent.each;
  });

  var TakeIterator = inherit(Iterator, function(parent, count) {
    Iterator.call(this, parent);
    var i = 0;
    this.changeIteration(function(action, e) {
      if (i++ >= count) { return false; }
      return action(e);
    });
  });

  var DropIterator = inherit(Iterator, function(parent, count) {
    Iterator.call(this, parent);
    var i = 0;
    this.changeIteration(function(action, e) {
      if (i++ < count) { return; }
      return action(e);
    });
  });

  var SortIterator = inherit(Iterator, function(parent, sortFn) {
    Iterator.call(this, parent);

    this.each = function(action) {
      var sorted = parent.toArray();
      sorted.sort(function(x, y) { return compare(x, y, sortFn); });
      forEach(sorted, action);
    };

    this.reverseEach = function(action) {
      var sorted = parent.toArray();
      sorted.sort(function(x, y) { return compare(y, x, sortFn); });
      forEach(sorted, action);
    };
  });

  var UniqIterator = inherit(Iterator, function(parent, count) {
    Iterator.call(this, parent);
    var set = {};
    this.changeIteration(function(action, e) {
      if (e in set) { return; }
      set[e] = true;
      return action(e);
    });
  });

  global.Lazy = function(source) {
    return new Iterator(null, source);
  };

})(window);
<|endoftext|>