<commit_before>/**
 * @class CM_Form_Abstract
 * @extends CM_View_Abstract
 */
var CM_Form_Abstract = CM_View_Abstract.extend({
  _class: 'CM_Form_Abstract',

  /** @type String **/
  autosave: null,

  /** @type Object **/
  _fields: {},

  /** @type Object **/
  _actions: {},

  initialize: function() {
    CM_View_Abstract.prototype.initialize.call(this);

    this._fields = {};
    this._actions = {};
  },

  events: {
    'reset': function() {
      _.each(this._fields, function(field) {
        field.reset();
      });
      this.resetErrors();
    }
  },

  ready: function() {
  },

  _ready: function() {
    var handler = this;

    _.each(this._actions, function(action, name) {
      var $btn = $('#' + this.getAutoId() + '-' + name + '-button');
      var event = $btn.data('event');
      if (!event) {
        event = 'click';
      }
      $btn.on(event, {action: name}, function(event) {
        event.preventDefault();
        event.stopPropagation();
        return handler.submit(event.data.action);
      });
    }, this);

    if (this.autosave) {
      this.on('change', function(field) {
        if (field) {
          handler._submitOnly(handler.autosave, false)
            .then(function() {
              field.success();
            })
            .catch(CM_Exception_FormFieldValidation, function(error) {
              handler._displayValidationError(error);
            });
        }
      });
    } else {
      this.$el.on('submit', function() {
        handler.$el.find('input[type="submit"], button[type="submit"]').first().click();
        return false;
      });
    }

    this.$el.on('reset', function() {
      _.defer(function() {
        handler.trigger('reset');
      });
    });

    CM_View_Abstract.prototype._ready.call(this);
  },

  /**
   * @param {CM_FormField_Abstract} field
   */
  registerField: function(field) {
    this._fields[field.getName()] = field;

    field.on('change', function() {
      this.trigger('change', field);
    }, this);
  },

  /**
   * @param {String} name
   * @param {Object} presentation
   */
  registerAction: function(name, presentation) {
    this._actions[name] = presentation;
  },

  /**
   * @return CM_FormField_Abstract
   */
  getField: function(name) {
    if (!this._fields[name]) {
      throw new CM_Exception(this.getClass() + ' cannot find form field `' + name + '`');
    }
    return this._fields[name];
  },

  /**
   * @return Boolean
   */
  hasField: function(name) {
    return !!this._fields[name];
  },

  /**
   * @return jQuery
   */
  $: function(selector) {
    if (!selector) {
      return this.$el;
    }
    selector = selector.replace('#', '#' + this.getAutoId() + '-');
    return $(selector, this.el);
  },

  /**
   * @returns {String[]}
   */
  getFieldNames: function() {
    return _.keys(this._fields);
  },

  /**
   * @returns {CM_FormField_Abstract[]}
   */
  getFields: function() {
    return _.values(this._fields);
  },

  /**
   * @returns {{}}
   */
  getData: function() {
    var data = {};
    _.each(this._fields, function(field) {
      if (field.getEnabled()) {
        data[field.getName()] = field.getValue();
      }
    });
    return data;
  },

  /**
   * @param {String} actionName
   * @returns {{}}
   */
  getActionData: function(actionName) {
    var action = this._getAction(actionName);
    var data = {};

    _.each(action.fields, function(isRequired, fieldName) {
      if (this.hasField(fieldName)) {
        var field = this.getField(fieldName);
        if (field.getEnabled()) {
          data[field.getName()] = field.getValue();
        }
      }
    }, this);

    return data;
  },

  /**
   * @param {String} actionName
   * @return Promise
   */
  submit: function(actionName) {
    return this
      .try(function() {
        return this._submitOnly(actionName, true);
      })
      .catch(CM_Exception_FormFieldValidation, function(error) {
        this._displayValidationError(error);
      });
  },

  /**
   * @param {String} actionName
   * @param {Boolean} disableUI
   * @return Promise
   */
  _submitOnly: function(actionName, disableUI) {
    var action = this._getAction(actionName);
    var data = this.getActionData(action.name);
    var errorListRequired = this._getErrorListRequired(action.name, data);

    this.resetErrors();
    if (_.size(errorListRequired)) {
      var error = new CM_Exception_FormFieldValidation();
      error.setErrorList(errorListRequired);
      return Promise.reject(error);
    }

    return this
      .try(function() {
        if (disableUI) {
          this.disable();
        }
        this.trigger('submit', [data]);
        return cm.ajax('form', {viewInfoList: this.getViewInfoList(), actionName: action.name, data: data})
      })
      .then(function(response) {
        if (response.errors) {
          var error = new CM_Exception_FormFieldValidation();
          error.setErrorList(response.errors);
          this.trigger('error error.' + actionName, error);
          throw error;
        }

        if (response.exec) {
          this.evaluation = new Function(response.exec);
          this.evaluation();
        }

        if (response.messages) {
          for (var i = 0, msg; msg = response.messages[i]; i++) {
            this.message(msg);
          }
        }

        this.trigger('success success.' + action.name, response.data);
        return response.data;
      })
      .finally(function() {
        if (disableUI) {
          this.enable();
        }
      });
  },

  /**
   * @param {CM_Exception_FormFieldValidation} validationError
   */
  _displayValidationError: function(validationError) {
    var errorList = validationError.getErrorList();
    for (var i = errorList.length - 1, error; error = errorList[i]; i--) {
      if (_.isArray(error)) {
        this.getField(error[1]).error(error[0]);
      } else {
        this.error(error);
      }
    }
  },

  reset: function() {
    this.el.reset();
  },

  disable: function() {
    this.$().disable();
  },

  enable: function() {
    this.$().enable();
  },

  /**
   * @param {String} message
   */
  error: function(message) {
    cm.window.hint(message);
  },

  /**
   * @param {String} message
   */
  message: function(message) {
    cm.window.hint(message);
  },

  resetErrors: function() {
    _.each(this._fields, function(field) {
      field.error(null);
    });
  },

  /**
   * @param {String} actionName
   * @returns {Object}
   */
  _getAction: function(actionName) {
    var action = this._actions[actionName];
    if (!action) {
      throw new CM_Exception('Form `' + this.getClass() + '` has no action `' + actionName + '`.');
    }
    action.name = actionName;
    return action;
  },

  /**
   * @param {String} actionName
   * @param {Object} data
   * @returns {Array[]}
   */
  _getErrorListRequired: function(actionName, data) {
    var action = this._getAction(actionName);
    var errorList = [];

    _.each(action.fields, function(isRequired, fieldName) {
      if (isRequired) {
        var field = this.getField(fieldName);
        if (field.isEmpty(data[fieldName])) {
          var label = this._getFieldLabel(field);
          if (label) {
            errorList.push([cm.language.get('{$label} is required.', {label: label}), fieldName]);
          } else {
            errorList.push([cm.language.get('Required'), fieldName]);
          }
        }
      }
    }, this);

    return errorList;
  },

  /**
   * @param {CM_FormField_Abstract} field
   * @returns {String|null}
   * @private
   */
  _getFieldLabel: function(field) {
    var $labels = this.$('label[for="' + field.getAutoId() + '-input"]');
    if ($labels.length) {
      return $labels.first().text();
    }
    if (field.getInput().attr('placeholder')) {
      return field.getInput().attr('placeholder');
    }
    return null;
  }
});
<commit_msg>throttle autosave submit<commit_after>/**
 * @class CM_Form_Abstract
 * @extends CM_View_Abstract
 */
var CM_Form_Abstract = CM_View_Abstract.extend({
  _class: 'CM_Form_Abstract',

  /** @type String **/
  autosave: null,

  /** @type Object **/
  _fields: {},

  /** @type Object **/
  _actions: {},

  /** @type PromiseThrottled */
  _autosaveSubmitThrottled: promiseThrottler(function(field) {
    return this._submitOnly(this.autosave, false)
      .then(function() {
        field.success();
      })
      .catch(CM_Exception_FormFieldValidation, function(error) {
        this._displayValidationError(error);
      }.bind(this));
  }, {cancelLeading: true}),

  initialize: function() {
    CM_View_Abstract.prototype.initialize.call(this);

    this._fields = {};
    this._actions = {};
  },

  events: {
    'reset': function() {
      _.each(this._fields, function(field) {
        field.reset();
      });
      this.resetErrors();
    }
  },

  ready: function() {
  },

  _ready: function() {
    var handler = this;

    _.each(this._actions, function(action, name) {
      var $btn = $('#' + this.getAutoId() + '-' + name + '-button');
      var event = $btn.data('event');
      if (!event) {
        event = 'click';
      }
      $btn.on(event, {action: name}, function(event) {
        event.preventDefault();
        event.stopPropagation();
        return handler.submit(event.data.action);
      });
    }, this);

    if (this.autosave) {
      this.on('change', function(field) {
        if (field) {
          handler._autosaveSubmitThrottled(field);
        }
      });
    } else {
      this.$el.on('submit', function() {
        handler.$el.find('input[type="submit"], button[type="submit"]').first().click();
        return false;
      });
    }

    this.$el.on('reset', function() {
      _.defer(function() {
        handler.trigger('reset');
      });
    });

    CM_View_Abstract.prototype._ready.call(this);
  },

  /**
   * @param {CM_FormField_Abstract} field
   */
  registerField: function(field) {
    this._fields[field.getName()] = field;

    field.on('change', function() {
      this.trigger('change', field);
    }, this);
  },

  /**
   * @param {String} name
   * @param {Object} presentation
   */
  registerAction: function(name, presentation) {
    this._actions[name] = presentation;
  },

  /**
   * @return CM_FormField_Abstract
   */
  getField: function(name) {
    if (!this._fields[name]) {
      throw new CM_Exception(this.getClass() + ' cannot find form field `' + name + '`');
    }
    return this._fields[name];
  },

  /**
   * @return Boolean
   */
  hasField: function(name) {
    return !!this._fields[name];
  },

  /**
   * @return jQuery
   */
  $: function(selector) {
    if (!selector) {
      return this.$el;
    }
    selector = selector.replace('#', '#' + this.getAutoId() + '-');
    return $(selector, this.el);
  },

  /**
   * @returns {String[]}
   */
  getFieldNames: function() {
    return _.keys(this._fields);
  },

  /**
   * @returns {CM_FormField_Abstract[]}
   */
  getFields: function() {
    return _.values(this._fields);
  },

  /**
   * @returns {{}}
   */
  getData: function() {
    var data = {};
    _.each(this._fields, function(field) {
      if (field.getEnabled()) {
        data[field.getName()] = field.getValue();
      }
    });
    return data;
  },

  /**
   * @param {String} actionName
   * @returns {{}}
   */
  getActionData: function(actionName) {
    var action = this._getAction(actionName);
    var data = {};

    _.each(action.fields, function(isRequired, fieldName) {
      if (this.hasField(fieldName)) {
        var field = this.getField(fieldName);
        if (field.getEnabled()) {
          data[field.getName()] = field.getValue();
        }
      }
    }, this);

    return data;
  },

  /**
   * @param {String} actionName
   * @return Promise
   */
  submit: function(actionName) {
    return this
      .try(function() {
        return this._submitOnly(actionName, true);
      })
      .catch(CM_Exception_FormFieldValidation, function(error) {
        this._displayValidationError(error);
      });
  },

  /**
   * @param {String} actionName
   * @param {Boolean} disableUI
   * @return Promise
   */
  _submitOnly: function(actionName, disableUI) {
    var action = this._getAction(actionName);
    var data = this.getActionData(action.name);
    var errorListRequired = this._getErrorListRequired(action.name, data);

    this.resetErrors();
    if (_.size(errorListRequired)) {
      var error = new CM_Exception_FormFieldValidation();
      error.setErrorList(errorListRequired);
      return Promise.reject(error);
    }

    return this
      .try(function() {
        if (disableUI) {
          this.disable();
        }
        this.trigger('submit', [data]);
        return cm.ajax('form', {viewInfoList: this.getViewInfoList(), actionName: action.name, data: data})
      })
      .then(function(response) {
        if (response.errors) {
          var error = new CM_Exception_FormFieldValidation();
          error.setErrorList(response.errors);
          this.trigger('error error.' + actionName, error);
          throw error;
        }

        if (response.exec) {
          this.evaluation = new Function(response.exec);
          this.evaluation();
        }

        if (response.messages) {
          for (var i = 0, msg; msg = response.messages[i]; i++) {
            this.message(msg);
          }
        }

        this.trigger('success success.' + action.name, response.data);
        return response.data;
      })
      .finally(function() {
        if (disableUI) {
          this.enable();
        }
      });
  },

  /**
   * @param {CM_Exception_FormFieldValidation} validationError
   */
  _displayValidationError: function(validationError) {
    var errorList = validationError.getErrorList();
    for (var i = errorList.length - 1, error; error = errorList[i]; i--) {
      if (_.isArray(error)) {
        this.getField(error[1]).error(error[0]);
      } else {
        this.error(error);
      }
    }
  },

  reset: function() {
    this.el.reset();
  },

  disable: function() {
    this.$().disable();
  },

  enable: function() {
    this.$().enable();
  },

  /**
   * @param {String} message
   */
  error: function(message) {
    cm.window.hint(message);
  },

  /**
   * @param {String} message
   */
  message: function(message) {
    cm.window.hint(message);
  },

  resetErrors: function() {
    _.each(this._fields, function(field) {
      field.error(null);
    });
  },

  /**
   * @param {String} actionName
   * @returns {Object}
   */
  _getAction: function(actionName) {
    var action = this._actions[actionName];
    if (!action) {
      throw new CM_Exception('Form `' + this.getClass() + '` has no action `' + actionName + '`.');
    }
    action.name = actionName;
    return action;
  },

  /**
   * @param {String} actionName
   * @param {Object} data
   * @returns {Array[]}
   */
  _getErrorListRequired: function(actionName, data) {
    var action = this._getAction(actionName);
    var errorList = [];

    _.each(action.fields, function(isRequired, fieldName) {
      if (isRequired) {
        var field = this.getField(fieldName);
        if (field.isEmpty(data[fieldName])) {
          var label = this._getFieldLabel(field);
          if (label) {
            errorList.push([cm.language.get('{$label} is required.', {label: label}), fieldName]);
          } else {
            errorList.push([cm.language.get('Required'), fieldName]);
          }
        }
      }
    }, this);

    return errorList;
  },

  /**
   * @param {CM_FormField_Abstract} field
   * @returns {String|null}
   * @private
   */
  _getFieldLabel: function(field) {
    var $labels = this.$('label[for="' + field.getAutoId() + '-input"]');
    if ($labels.length) {
      return $labels.first().text();
    }
    if (field.getInput().attr('placeholder')) {
      return field.getInput().attr('placeholder');
    }
    return null;
  }
});
<|endoftext|>


<commit_before>
//Constructor
function NomadsMobileClient(initCallback, changeClientMode) {
	//Public member variables

	user = {};
	this.socket = io.connect();
	this.initCallback = initCallback;
	this.changeClientMode = changeClientMode;
	loggedin = false;
	latitude = 0;
	longitude = 0;

	//Socket Listeners
	this.socket.on('connect', function(data){});
	this.socket.on('auksalaq_user_confirmed', function(data){
		if(data.id == user.id){
			console.log("User Confirmed "+data + " " + data.mode);
			loggedin = true;
			changeClientMode(data.mode);
		}

	});

  this.socket.on("disconnect", function() {
  	//https://github.com/LearnBoost/socket.io-client/issues/251
  	console.log("reconnecting");
    socket.socket.reconnect();
  });

  //add to global thought object when any user sends a message.
  // only use this function for Desktops. NO PHONES. Too much info and too slow.
  this.socket.on('auksalaq_client_update', function(data){
		console.log("data received ", data);
		if(data.type == 'aukthought'){

			//var xLoc = GRAPHICSW - data.messageText.length - (Math.random()*data);
			//var yLoc = Math.random()*200+20;
    	allClientThoughts.push({
	    	"thought":data.messageText,
		    "x":data.x,
		    "y":data.y,
		    "life":4000,
		    "size":12,
		    "alpha":1.0,
		    "vectorX":data.rX,
		    "vectorY":data.rY
		  });
  	}

  	if(data.type == 'aukchatmessage'){
  		console.log('got chat message '+data.messageText);
  		if($('chat-log')!=null){
  			$('#chat-log').append("
"+data.messageText + "
");
  			var dy = $('#chat-log').height() - $('#mainui').height();
  			if(dy>0){
  				$('#chat-log').css('top',-dy-20+'px');
  			}
  		}
  	}
  });

  this.socket.on('auksalaq_mode', function(data){
  	console.log('mode change to '+data);
  	changeClientMode(data);
  	//change inteface to new mode
  	//initCallback(data);
  });

	//Private functions
	geo_success_callback = function(p){
	  latitude = parseFloat(p.coords.latitude);
	  longitude = parseFloat(p.coords.longitude);
	  console.log("Lat/Long = " + latitude + " " + longitude);
	  initCallback();
	}

	geo_error_callback = function(p){
	    // p.message : error message
	    console.log("callback: Geolocation is not available");
	    latitude = 0;
	  	longitude = 0;
	    initCallback();
	}

}

NomadsMobileClient.prototype = {
	constructor:NomadsMobileClient,

	geolocate:function(){
		// Geolocation Initialisation
		if(typeof(geoPosition)=='undefined'){
			// You cannot use Geolocation in this device
  	  console.log("Geolocation is not available");
  	  latitude = 0;
	  	longitude = 0;
  	  initCallback();
  	  return;
		}
		if(geoPosition.init()){
    	geoPosition.getCurrentPosition(geo_success_callback, geo_error_callback,{enableHighAccuracy:true});
  	}else{
  	  // You cannot use Geolocation in this device
  	  console.log("Geolocation is not available");
  	  latitude = 0;
	  	longitude = 0;
  	  initCallback();

  	}
	},

	login:function(username, callback){
		console.log('logging in');
		var messageToSend = {};
    user.id = messageToSend.id = "nomads_" + username + "_" + Math.floor(Math.random()*1000);
    user.username = messageToSend.username = username;
    messageToSend.type = 'newUser';
    messageToSend.latitude = latitude; //changed to latitude, not this.latitude to work in server.js
    messageToSend.longitude = longitude;
    var date = new Date();
    d = date.getMonth()+1+"."+date.getDate()+"."+date.getFullYear()+ " at " + date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
    messageToSend.timestamp = d;
    this.socket.emit('auksalaq_newuser', messageToSend);
    if(typeof(callback)!='undefined'){
    	callback();
    }
	},

	sendMessage:function(messageText, type, x, y, callback){
		if(!loggedin){
			console.log('not logged in');
			return;
		}
		var messageToSend = {};
		rX = Math.floor(random()*2);
	  rY = Math.floor(random()*2);

	  if(rX==1){
	    rX = .5;
	  }else {
	    rX= -.5;
	  }

	  if(rY==1){
	    rY = .5;
	  }else {
	    rY = -.5;
	  }

		messageToSend.id = user.id;
		messageToSend.username = user.username;
		messageToSend.type = type;
		messageToSend.messageText = messageText;

    messageToSend.x = x;
    messageToSend.y = y;
    messageToSend.rX = rX;
    messageToSend.rY = rY;
		var date = new Date();
    d = date.getMonth()+1+"."+date.getDate()+"."+date.getFullYear()+ " at " + date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
    messageToSend.timestamp = d;
		this.socket.emit('auksalaq_message', messageToSend);
		//also fire processing on user's own page.
		//var pjs = Processing.getInstanceById('animationUserText');
    //pjs.drawNewUserThought(location, messageText);
		if(typeof(callback)!='undefined'){
    	callback();
    }
	},

	changeMode:function(mode){
		this.socket.emit('auksalaq_mode', mode);
	}
}

<commit_msg>client fix<commit_after>
//Constructor
function NomadsMobileClient(initCallback, changeClientMode) {
	//Public member variables

	user = {};
	this.socket = io.connect();
	this.initCallback = initCallback;
	this.changeClientMode = changeClientMode;
	loggedin = false;
	latitude = 0;
	longitude = 0;

	//Socket Listeners
	this.socket.on('connect', function(data){});
	this.socket.on('auksalaq_user_confirmed', function(data){
		if(data.id == user.id){
			console.log("User Confirmed "+data + " " + data.mode);
			loggedin = true;
			changeClientMode(data.mode);
		}

	});

  this.socket.on("disconnect", function() {
  	//https://github.com/LearnBoost/socket.io-client/issues/251
  	console.log("reconnecting");
    socket.socket.reconnect();
  });

  //add to global thought object when any user sends a message.
  // only use this function for Desktops. NO PHONES. Too much info and too slow.
  this.socket.on('auksalaq_client_update', function(data){
		console.log("data received ", data);
		if(data.type == 'aukthought'){

			//var xLoc = GRAPHICSW - data.messageText.length - (Math.random()*data);
			//var yLoc = Math.random()*200+20;
			if(allClientThoughts!=null){
	    	allClientThoughts.push({
		    	"thought":data.messageText,
			    "x":data.x,
			    "y":data.y,
			    "life":4000,
			    "size":12,
			    "alpha":1.0,
			    "vectorX":data.rX,
			    "vectorY":data.rY
			  });
	    }
  	}

  	if(data.type == 'aukchatmessage'){
  		console.log('got chat message '+data.messageText);
  		if($('chat-log')!=null){
  			$('#chat-log').append("
"+data.messageText + "
");
  			var dy = $('#chat-log').height() - $('#mainui').height();
  			if(dy>0){
  				$('#chat-log').css('top',-dy-20+'px');
  			}
  		}
  	}
  });

  this.socket.on('auksalaq_mode', function(data){
  	console.log('mode change to '+data);
  	changeClientMode(data);
  	//change inteface to new mode
  	//initCallback(data);
  });

	//Private functions
	geo_success_callback = function(p){
	  latitude = parseFloat(p.coords.latitude);
	  longitude = parseFloat(p.coords.longitude);
	  console.log("Lat/Long = " + latitude + " " + longitude);
	  initCallback();
	}

	geo_error_callback = function(p){
	    // p.message : error message
	    console.log("callback: Geolocation is not available");
	    latitude = 0;
	  	longitude = 0;
	    initCallback();
	}

}

NomadsMobileClient.prototype = {
	constructor:NomadsMobileClient,

	geolocate:function(){
		// Geolocation Initialisation
		if(typeof(geoPosition)=='undefined'){
			// You cannot use Geolocation in this device
  	  console.log("Geolocation is not available");
  	  latitude = 0;
	  	longitude = 0;
  	  initCallback();
  	  return;
		}
		if(geoPosition.init()){
    	geoPosition.getCurrentPosition(geo_success_callback, geo_error_callback,{enableHighAccuracy:true});
  	}else{
  	  // You cannot use Geolocation in this device
  	  console.log("Geolocation is not available");
  	  latitude = 0;
	  	longitude = 0;
  	  initCallback();

  	}
	},

	login:function(username, callback){
		console.log('logging in');
		var messageToSend = {};
    user.id = messageToSend.id = "nomads_" + username + "_" + Math.floor(Math.random()*1000);
    user.username = messageToSend.username = username;
    messageToSend.type = 'newUser';
    messageToSend.latitude = latitude; //changed to latitude, not this.latitude to work in server.js
    messageToSend.longitude = longitude;
    var date = new Date();
    d = date.getMonth()+1+"."+date.getDate()+"."+date.getFullYear()+ " at " + date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
    messageToSend.timestamp = d;
    this.socket.emit('auksalaq_newuser', messageToSend);
    if(typeof(callback)!='undefined'){
    	callback();
    }
	},

	sendMessage:function(messageText, type, x, y, callback){
		if(!loggedin){
			console.log('not logged in');
			return;
		}
		var messageToSend = {};
		rX = Math.floor(random()*2);
	  rY = Math.floor(random()*2);

	  if(rX==1){
	    rX = .5;
	  }else {
	    rX= -.5;
	  }

	  if(rY==1){
	    rY = .5;
	  }else {
	    rY = -.5;
	  }

		messageToSend.id = user.id;
		messageToSend.username = user.username;
		messageToSend.type = type;
		messageToSend.messageText = messageText;

    messageToSend.x = x;
    messageToSend.y = y;
    messageToSend.rX = rX;
    messageToSend.rY = rY;
		var date = new Date();
    d = date.getMonth()+1+"."+date.getDate()+"."+date.getFullYear()+ " at " + date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
    messageToSend.timestamp = d;
		this.socket.emit('auksalaq_message', messageToSend);
		//also fire processing on user's own page.
		//var pjs = Processing.getInstanceById('animationUserText');
    //pjs.drawNewUserThought(location, messageText);
		if(typeof(callback)!='undefined'){
    	callback();
    }
	},

	changeMode:function(mode){
		this.socket.emit('auksalaq_mode', mode);
	}
}

<|endoftext|>


<commit_before>(function() {

	var setSvgClass = function(obj, value, replace) {
		updateSvg(obj, function() {
			var svg = obj.contentDocument.querySelector('svg');
			svg.setAttribute('class', replace ? svg.className.baseVal.replace(replace, value) : svg.className.baseVal + ' ' + value);
		});
	};

	var updateSvg = function(obj, fn) {
		if (obj.contentDocument && obj.contentDocument.readyState === 'complete' && obj.contentDocument.querySelector('svg')) fn();
		else obj.addEventListener('load', fn);
	};

	Array.from(document.getElementsByClassName('svg-button')).filter(button => button.dataset.section !== 'home').forEach(function(button) {
		var obj = button.children[0];
		obj.parentNode.addEventListener('mouseover', function(e) { setSvgClass(obj, 'over'); });
		obj.parentNode.addEventListener('mouseout', function(e) { setSvgClass(obj, '', 'over'); });
	});
	Array.from(document.getElementsByClassName('svg-image')).forEach(function(obj) {
		if (obj.parentNode.classList.contains('selected')) setSvgClass(obj, 'selected');
	});
	Array.from(document.getElementById('masthead').getElementsByClassName('svg-image')).filter(function(obj) {
		return window.getComputedStyle(obj.parentNode)["background-color"].includes('0.');
	}).forEach(function(obj) { setSvgClass(obj, 'selected'); });

})();
<commit_msg>Removed es6 fat arrow<commit_after>(function() {

	var setSvgClass = function(obj, value, replace) {
		updateSvg(obj, function() {
			var svg = obj.contentDocument.querySelector('svg');
			svg.setAttribute('class', replace ? svg.className.baseVal.replace(replace, value) : svg.className.baseVal + ' ' + value);
		});
	};

	var updateSvg = function(obj, fn) {
		if (obj.contentDocument && obj.contentDocument.readyState === 'complete' && obj.contentDocument.querySelector('svg')) fn();
		else obj.addEventListener('load', fn);
	};

	Array.from(document.getElementsByClassName('svg-button')).filter(function(button) { return button.dataset.section !== 'home'; }).forEach(function(button) {
		var obj = button.children[0];
		obj.parentNode.addEventListener('mouseover', function(e) { setSvgClass(obj, 'over'); });
		obj.parentNode.addEventListener('mouseout', function(e) { setSvgClass(obj, '', 'over'); });
	});
	Array.from(document.getElementsByClassName('svg-image')).forEach(function(obj) {
		if (obj.parentNode.classList.contains('selected')) setSvgClass(obj, 'selected');
	});
	Array.from(document.getElementById('masthead').getElementsByClassName('svg-image')).filter(function(obj) {
		return window.getComputedStyle(obj.parentNode)["background-color"].includes('0.');
	}).forEach(function(obj) { setSvgClass(obj, 'selected'); });

})();
<|endoftext|>


<commit_before>var https       = require('https'),
    sys         = require('sys'),
    querystring = require('querystring'),
    url         = require('url');

var Client = function(clientId, accessToken){
  this._clientId = clientId;
  this._accessToken = accessToken;
  this._prefix = 'https://api.instagram.com/v1';
  return this;
};

var fixNumericValues = function(data){
  var keysToFix = ['id', 'created_time'];
  if (data === null || data === undefined) {
    return data;
  } else if (typeof data.map === 'function') {
    return data.map(fixNumericValues);
  } else if (typeof data === 'object') {
    return Object.keys(data).reduce(function(o, k){
      switch (k) {
        case 'id':
        case 'created_time':
          o[k] = parseInt(data[k], 10);
          break;
        case 'tags':
          if (typeof data[k] === 'string') {
            o[k] = data[k].split(/\s+/);
          } else {
            o[k] = data[k];
          }
          break;
        default:
          o[k] = fixNumericValues(data[k]);
      }
      return o;
    }, {});
  } else {
    return data;
  }
};

var P = Client.prototype;

P.query = function(method, path, data, callback){
  var body = null;

  data.client_id = this._clientId;

  if (method == 'GET') {
    path = path + '?' + querystring.stringify(data);
  } else {
    body = querystring.stringify(data);
  }

  this.makeRequest(method, this._prefix + path, body, callback);
};

P.makeRequest = function(method, loc, body, callback){
  var u = url.parse(loc);

  var options = {
    host: u.hostname,
    port: u.port || 443,
    path: u.pathname + (u.search || ''),
    method: method
  };

  var chunks = [];

  var req = https.request(options, function(res){
    res.on('data', function(chunk){
      chunks.push(chunk);
    });

    res.on('end', function(){
      try {
        callback(null, fixNumericValues(JSON.parse(chunks.join(''))));
      } catch(err) {
        err.context = chunks.join('');
        callback(err);
      }
    });
  });

  req.on('error', function(err) {
    callback(err);
  });

  if (body) {
    req.write(body);
  }

  req.end();
};

P.GET = function(path, data, callback){
  if (!callback) { callback = data; data = {}; }
  this.query('GET', path, data, callback);
};

P.getUser = function(userId, callback){
  this.GET('/users/' + userId, callback);
};

P.searchUser = function(q, callback){
  this.GET('/users/search', {q: q}, callback);
};

P.getUserMedia = function(userId, options, callback){
  options.access_token = this._accessToken;
  this.GET('/users/'+userId+'/media/recent', options, callback);
};

P.getNextPage = function(resultSet, callback){
  if (resultSet.hasOwnProperty('pagination') &&
      resultSet.pagination.hasOwnProperty('next_url')) {
    this.makeRequest('GET', resultSet.pagination.next_url, null, callback);
  } else {
    callback(null, {});
  }
};

exports.createClient = function(clientId, accessToken){
  return new Client(clientId, accessToken);
};

exports.Client = Client;
<commit_msg>More accurate name for function.<commit_after>var https       = require('https'),
    sys         = require('sys'),
    querystring = require('querystring'),
    url         = require('url');

var Client = function(clientId, accessToken){
  this._clientId = clientId;
  this._accessToken = accessToken;
  this._prefix = 'https://api.instagram.com/v1';
  return this;
};

var fixAPIDataRecursive = function(data){
  var keysToFix = ['id', 'created_time'];
  if (data === null || data === undefined) {
    return data;
  } else if (typeof data.map === 'function') {
    return data.map(fixAPIDataRecursive);
  } else if (typeof data === 'object') {
    return Object.keys(data).reduce(function(o, k){
      switch (k) {
        case 'id':
        case 'created_time':
          o[k] = parseInt(data[k], 10);
          break;
        case 'tags':
          if (typeof data[k] === 'string') {
            o[k] = data[k].split(/\s+/);
          } else {
            o[k] = data[k];
          }
          break;
        default:
          o[k] = fixAPIDataRecursive(data[k]);
      }
      return o;
    }, {});
  } else {
    return data;
  }
};

var P = Client.prototype;

P.query = function(method, path, data, callback){
  var body = null;

  data.client_id = this._clientId;

  if (method == 'GET') {
    path = path + '?' + querystring.stringify(data);
  } else {
    body = querystring.stringify(data);
  }

  this.makeRequest(method, this._prefix + path, body, callback);
};

P.makeRequest = function(method, loc, body, callback){
  var u = url.parse(loc);

  var options = {
    host: u.hostname,
    port: u.port || 443,
    path: u.pathname + (u.search || ''),
    method: method
  };

  var chunks = [];

  var req = https.request(options, function(res){
    res.on('data', function(chunk){
      chunks.push(chunk);
    });

    res.on('end', function(){
      try {
        callback(null, fixAPIDataRecursive(JSON.parse(chunks.join(''))));
      } catch(err) {
        err.context = chunks.join('');
        callback(err);
      }
    });
  });

  req.on('error', function(err) {
    callback(err);
  });

  if (body) {
    req.write(body);
  }

  req.end();
};

P.GET = function(path, data, callback){
  if (!callback) { callback = data; data = {}; }
  this.query('GET', path, data, callback);
};

P.getUser = function(userId, callback){
  this.GET('/users/' + userId, callback);
};

P.searchUser = function(q, callback){
  this.GET('/users/search', {q: q}, callback);
};

P.getUserMedia = function(userId, options, callback){
  options.access_token = this._accessToken;
  this.GET('/users/'+userId+'/media/recent', options, callback);
};

P.getNextPage = function(resultSet, callback){
  if (resultSet.hasOwnProperty('pagination') &&
      resultSet.pagination.hasOwnProperty('next_url')) {
    this.makeRequest('GET', resultSet.pagination.next_url, null, callback);
  } else {
    callback(null, {});
  }
};

exports.createClient = function(clientId, accessToken){
  return new Client(clientId, accessToken);
};

exports.Client = Client;
<|endoftext|>


<commit_before>'use strict';

var child_process = require('child_process');
var fs = require('fs');
var os = require('os');
var path = require('path');

var AccountManager = require('./account-manager');
var AtomHelper = require('./atom-helper');
var StateController = require('./state-controller');
var utils = require('./utils');
const Logger = require('./logger');

var Tracker = require('../ext/telemetry/metrics').Tracker;

var Installer = class {
  static get INTERVAL() {
    return 2500;
  }

  constructor(paths) {
    paths = paths || [];
    this.flow = null;
    this.path = paths.length ? paths[0] : os.homedir();
  }

  instrument(fn) {
    this.flow.disable();
    fn.call(this)
    .then(() => this.flow.enable())
    .catch(() => this.flow.enable());
  }

  init(flow, onFinish) {
    this.flow = flow;
    this.flow.onInstall(() => this.instrument(this.install));
    this.flow.onCreateAccount(() => this.instrument(this.createAccount));
    this.flow.onLogin(() => this.instrument(this.login));
    this.flow.onResetPassword(() => this.instrument(this.resetPassword));
    this.flow.onLoginBack(() => this.flow.showCreateAccount());
    this.flow.onWhitelist(() => this.instrument(this.whitelist));
    this.flow.onSkipWhitelist(() => this.instrument(this.skipWhitelist));

    this.parsedEmail = null;
    this.kiteCanRun = true;
    this.installPromise = null;
    this.authTimerID = null;
    this.whitelistTimerID = null;
    this.onFinish = onFinish || null;

    this.opts = {
      install: false,
    };

    this.parseUserEmail();
    Tracker.trackEvent('start flow');
  }

  get projectName() {
    if (!this.path) {
      return null;
    }
    var parts = this.path.split('/');
    return parts[parts.length - 1];
  }

  install() {
    Tracker.trackEvent('enabled kite');
    this.flow.showCreateAccount(this.parsedEmail);
    this.installPromise = StateController.downloadKiteRelease(this.opts);
    return this.installPromise.catch((err) => {
      Tracker.trackEvent('error downloading to memory', { error: err });
      Logger.error('error installing kite:', err);
    });
  }

  installAndRun(callback) {
    Tracker.trackEvent('saving to disk');
    return (this.installPromise || StateController.downloadKiteRelease(this.opts))
    .then(() => {
      StateController.installKite(this.opts).then(() => {
        Tracker.trackEvent('installed successfully');
        StateController.runKiteAndWait(30, Installer.INTERVAL).then(() => {
          Tracker.trackEvent('app started successfully');
          if (typeof callback === 'function') {
            callback();
          }
        }, (err) => {
          Tracker.trackEvent('error running kite', { error: err });
          Logger.error('error running kite:', err);
          this.kiteCanRun = false;
        });
      }, (err) => {
        Tracker.trackEvent('error saving kite', { error: err });
        Logger.error('error saving kite:', err);
      });
    });
  }

  createAccount() {
    Tracker.trackEvent('creating account');
    try {
      var data = this.flow.createAccountStep.data;
      return AccountManager.createAccount(data, (resp) => {
        Tracker.trackEvent('attempt to create account');
        switch (resp.statusCode) {
          case 200:
            utils.handleResponseData(resp, (raw) => {
              var info = JSON.parse(raw);
              Tracker.props.distinct_id = info.id;
              Tracker.trackEvent('account created');
            });
            if (typeof this.onAuthenticate === 'function') {
              this.onAuthenticate();
            }
            this.flow.showWhitelist({
              email: data.email,
              path: this.path,
            });
            this.installAndRun(() => this.attemptAuthenticate());
            break;
          case 409:
            Tracker.trackEvent('email exists showing login');
            this.flow.showLogin();
            break;
          default:
            Tracker.trackEvent('create account error', { code: resp.statusCode });
            this.flow.createAccountStep.showError('An error occurred');
            break;
        }
      });
    } catch (err) {
      Tracker.trackEvent('error creating account', { error: err.message });
      Logger.error('error creating account:', err);
      return Promise.reject();
    }
  }

  login() {
    Tracker.trackEvent('logging in');
    var handleUnauthorized = (resp) => {
      try {
        var data = JSON.parse(resp);
        if (data.code === 9) {
          Tracker.trackEvent('user needs to set password');
          this.flow.loginStep.showError('To login, set your password first');
        } else {
          Tracker.trackEvent('incorrect credentials');
          this.flow.loginStep.showError('Wrong email/password combination');
        }
      } catch (e) {
        Tracker.trackEvent('error handling unauthorized user');
        this.flow.loginStep.showError('An error occurred');
      }
    };
    try {
      var data = this.flow.loginStep.data;
      return AccountManager.login(data, (resp) => {
        switch (resp.statusCode) {
          case 200:
            utils.handleResponseData(resp, (raw) => {
              var info = JSON.parse(raw);
              Tracker.props.distinct_id = info.id;
              Tracker.trackEvent('login successful');
            });
            if (typeof this.onAuthenticate === 'function') {
              this.onAuthenticate();
            }
            this.flow.showWhitelist({ path: this.path });
            this.installAndRun(() => this.attemptAuthenticate());
            break;
          case 400:
          case 401:
            Tracker.trackEvent('unauthorized login');
            utils.handleResponseData(resp, (raw) => handleUnauthorized(raw));
            break;
          default:
            Tracker.trackEvent('login error', { code: resp.statusCode });
            this.flow.loginStep.showError('An error occurred');
            break;
        }
      });
    } catch (err) {
      Tracker.trackEvent('error logging in', { error: err.message });
      Logger.error('error logging in:', err);
      return Promise.reject();
    }
  }

  resetPassword() {
    Tracker.trackEvent('resetting password');
    try {
      var data = this.flow.loginStep.data;
      return AccountManager.resetPassword(data, (resp) => {
        switch (resp.statusCode) {
          case 200:
            Tracker.trackEvent('sent password reset');
            var msg = "We've sent you an email with instructions " +
            'to reset your password.';
            this.flow.loginStep.showStatus(msg);
            break;
          default:
            Tracker.trackEvent('reset error', { code: resp.statusCode });
            this.flow.loginStep.showError('An error occurred');
            break;
        }
      });
    } catch (err) {
      Tracker.trackEvent('error resetting password', { error: err });
      Logger.error('error resetting password:', err);
      return Promise.reject();
    }
  }

  attemptAuthenticate() {
    Tracker.trackEvent('attempting to authenticate');
    var auth = () => {
      if (!this.kiteCanRun) {
        Tracker.trackEvent("kite can't run - aborting authenticate");
        Logger.error("kite can't run - aborting authenticate");
        return;
      }
      var sessionKey = AccountManager.client.cookies['kite-session'];
      StateController.authenticateSessionID(sessionKey.Value).catch((err) => {
        Tracker.trackEvent('error authenticating', { error: err });
        Logger.error('error authenticating:', err);
        this.attemptAuthenticate();
      });
    };
    this.authTimerID = setTimeout(() => {
      auth();
    }, Installer.INTERVAL);
  }

  whitelist() {
    Tracker.trackEvent('whitelisting');
    this.flow.finishWhitelist();
    return StateController.waitForKite(30, Installer.INTERVAL).then(() => {
      this.attemptWhitelist();
    }, (err) => {
      Tracker.trackEvent('error waiting to whitelisting', { error: err });
      Logger.error('error waiting to whitelist:', err);
      this.finish();
    });
  }

  attemptWhitelist() {
    Tracker.trackEvent('attempting to whitelist');
    var whitelist = () => {
      if (!this.kiteCanRun) {
        Tracker.trackEvent("kite can't run - aborting whitelist");
        Logger.error("kite can't run - aborting whitelist");
        return;
      }
      if (!this.path) {
        Tracker.trackEvent('no path to whitelist');
        return;
      }
      StateController.whitelistPath(this.path).then(() => {
        this.finish();
      }, (err) => {
        if (err.type === 'bad_state' &&
            err.data === StateController.STATES.WHITELISTED) {
          this.finish();
          return;
        }
        Tracker.trackEvent('error whitelisting', { error: err });
        Logger.error('error whitelisting:', err);
        this.attemptWhitelist();
      });
    };
    this.whitelistTimerID = setTimeout(() => {
      whitelist();
    }, Installer.INTERVAL);
  }

  skipWhitelist() {
    Tracker.trackEvent('skipped whitelist');
    this.flow.finishWhitelist();
    return StateController.waitForKite(30, Installer.INTERVAL).then(() => {
      this.finish();
    }, (err) => {
      Tracker.trackEvent('error waiting to whitelist:', { error: err });
      Logger.error('error waiting to whitelist:', err);
      this.finish();
    });
  }

  finish() {
    var endProgress = () => {
      this.flow.finishFlow();
      if (typeof this.onFinish === 'function') {
        this.onFinish();
      }
    };
    var prom = AtomHelper.installPackage();
    if (!prom) {
      Tracker.trackEvent('no kite.js - finishing flow');
      endProgress();
    } else {
      prom.then(() => {
        Tracker.trackEvent('installing kite.js and finishing');
        endProgress();
      }, (err) => {
        Tracker.trackEvent('error installing kite.js - finishing', { error: err });
        Logger.error('error refreshing Atom package:', err);
        endProgress();
      });
    }
  }

  getUserEmail() {
    var proc = child_process.spawnSync('git', ['config', 'user.email'], {
      encoding: 'utf8',
    });
    return proc.stdout.trim();
  }

  parseUserEmail() {
    try {
      this.parsedEmail = null;
      var cfg = fs.readFileSync(path.join(os.homedir(), '.gitconfig')).toString();
      var lines = cfg.split('\n');
      for (var i = 0; i < lines.length; i++) {
        var items = lines[i].trim().split('=');
        if (items[0].trim() === 'email') {
          this.parsedEmail = items[1].trim();
          break;
        }
      }
    } catch (err) {
      Tracker.trackEvent('error parsing gitconfig', { error: err.message });
      Logger.error('error parsing gitconfig:', err);
    }
  }
};

module.exports = Installer;
<commit_msg>:bug: Guard against missing sessionKey in auth<commit_after>'use strict';

var child_process = require('child_process');
var fs = require('fs');
var os = require('os');
var path = require('path');

var AccountManager = require('./account-manager');
var AtomHelper = require('./atom-helper');
var StateController = require('./state-controller');
var utils = require('./utils');
const Logger = require('./logger');

var Tracker = require('../ext/telemetry/metrics').Tracker;

var Installer = class {
  static get INTERVAL() {
    return 2500;
  }

  constructor(paths) {
    paths = paths || [];
    this.flow = null;
    this.path = paths.length ? paths[0] : os.homedir();
  }

  instrument(fn) {
    this.flow.disable();
    fn.call(this)
    .then(() => this.flow.enable())
    .catch(() => this.flow.enable());
  }

  init(flow, onFinish) {
    this.flow = flow;
    this.flow.onInstall(() => this.instrument(this.install));
    this.flow.onCreateAccount(() => this.instrument(this.createAccount));
    this.flow.onLogin(() => this.instrument(this.login));
    this.flow.onResetPassword(() => this.instrument(this.resetPassword));
    this.flow.onLoginBack(() => this.flow.showCreateAccount());
    this.flow.onWhitelist(() => this.instrument(this.whitelist));
    this.flow.onSkipWhitelist(() => this.instrument(this.skipWhitelist));

    this.parsedEmail = null;
    this.kiteCanRun = true;
    this.installPromise = null;
    this.authTimerID = null;
    this.whitelistTimerID = null;
    this.onFinish = onFinish || null;

    this.opts = {
      install: false,
    };

    this.parseUserEmail();
    Tracker.trackEvent('start flow');
  }

  get projectName() {
    if (!this.path) {
      return null;
    }
    var parts = this.path.split('/');
    return parts[parts.length - 1];
  }

  install() {
    Tracker.trackEvent('enabled kite');
    this.flow.showCreateAccount(this.parsedEmail);
    this.installPromise = StateController.downloadKiteRelease(this.opts);
    return this.installPromise.catch((err) => {
      Tracker.trackEvent('error downloading to memory', { error: err });
      Logger.error('error installing kite:', err);
    });
  }

  installAndRun(callback) {
    Tracker.trackEvent('saving to disk');
    return (this.installPromise || StateController.downloadKiteRelease(this.opts))
    .then(() => {
      StateController.installKite(this.opts).then(() => {
        Tracker.trackEvent('installed successfully');
        StateController.runKiteAndWait(30, Installer.INTERVAL).then(() => {
          Tracker.trackEvent('app started successfully');
          if (typeof callback === 'function') {
            callback();
          }
        }, (err) => {
          Tracker.trackEvent('error running kite', { error: err });
          Logger.error('error running kite:', err);
          this.kiteCanRun = false;
        });
      }, (err) => {
        Tracker.trackEvent('error saving kite', { error: err });
        Logger.error('error saving kite:', err);
      });
    });
  }

  createAccount() {
    Tracker.trackEvent('creating account');
    try {
      var data = this.flow.createAccountStep.data;
      return AccountManager.createAccount(data, (resp) => {
        Tracker.trackEvent('attempt to create account');
        switch (resp.statusCode) {
          case 200:
            utils.handleResponseData(resp, (raw) => {
              var info = JSON.parse(raw);
              Tracker.props.distinct_id = info.id;
              Tracker.trackEvent('account created');
            });
            if (typeof this.onAuthenticate === 'function') {
              this.onAuthenticate();
            }
            this.flow.showWhitelist({
              email: data.email,
              path: this.path,
            });
            this.installAndRun(() => this.attemptAuthenticate());
            break;
          case 409:
            Tracker.trackEvent('email exists showing login');
            this.flow.showLogin();
            break;
          default:
            Tracker.trackEvent('create account error', { code: resp.statusCode });
            this.flow.createAccountStep.showError('An error occurred');
            break;
        }
      });
    } catch (err) {
      Tracker.trackEvent('error creating account', { error: err.message });
      Logger.error('error creating account:', err);
      return Promise.reject();
    }
  }

  login() {
    Tracker.trackEvent('logging in');
    var handleUnauthorized = (resp) => {
      try {
        var data = JSON.parse(resp);
        if (data.code === 9) {
          Tracker.trackEvent('user needs to set password');
          this.flow.loginStep.showError('To login, set your password first');
        } else {
          Tracker.trackEvent('incorrect credentials');
          this.flow.loginStep.showError('Wrong email/password combination');
        }
      } catch (e) {
        Tracker.trackEvent('error handling unauthorized user');
        this.flow.loginStep.showError('An error occurred');
      }
    };
    try {
      var data = this.flow.loginStep.data;
      return AccountManager.login(data, (resp) => {
        switch (resp.statusCode) {
          case 200:
            utils.handleResponseData(resp, (raw) => {
              var info = JSON.parse(raw);
              Tracker.props.distinct_id = info.id;
              Tracker.trackEvent('login successful');
            });
            if (typeof this.onAuthenticate === 'function') {
              this.onAuthenticate();
            }
            this.flow.showWhitelist({ path: this.path });
            this.installAndRun(() => this.attemptAuthenticate());
            break;
          case 400:
          case 401:
            Tracker.trackEvent('unauthorized login');
            utils.handleResponseData(resp, (raw) => handleUnauthorized(raw));
            break;
          default:
            Tracker.trackEvent('login error', { code: resp.statusCode });
            this.flow.loginStep.showError('An error occurred');
            break;
        }
      });
    } catch (err) {
      Tracker.trackEvent('error logging in', { error: err.message });
      Logger.error('error logging in:', err);
      return Promise.reject();
    }
  }

  resetPassword() {
    Tracker.trackEvent('resetting password');
    try {
      var data = this.flow.loginStep.data;
      return AccountManager.resetPassword(data, (resp) => {
        switch (resp.statusCode) {
          case 200:
            Tracker.trackEvent('sent password reset');
            var msg = "We've sent you an email with instructions " +
            'to reset your password.';
            this.flow.loginStep.showStatus(msg);
            break;
          default:
            Tracker.trackEvent('reset error', { code: resp.statusCode });
            this.flow.loginStep.showError('An error occurred');
            break;
        }
      });
    } catch (err) {
      Tracker.trackEvent('error resetting password', { error: err });
      Logger.error('error resetting password:', err);
      return Promise.reject();
    }
  }

  attemptAuthenticate() {
    Tracker.trackEvent('attempting to authenticate');
    var auth = () => {
      if (!this.kiteCanRun) {
        Tracker.trackEvent("kite can't run - aborting authenticate");
        Logger.error("kite can't run - aborting authenticate");
        return;
      }
      var sessionKey = AccountManager.client.cookies['kite-session'];
      if (sessionKey) {
        StateController.authenticateSessionID(sessionKey.Value).catch((err) => {
          Tracker.trackEvent('error authenticating', { error: err });
          Logger.error('error authenticating:', err);
          this.attemptAuthenticate();
        });
      }
    };
    this.authTimerID = setTimeout(auth, Installer.INTERVAL);
  }

  whitelist() {
    Tracker.trackEvent('whitelisting');
    this.flow.finishWhitelist();
    return StateController.waitForKite(30, Installer.INTERVAL).then(() => {
      this.attemptWhitelist();
    }, (err) => {
      Tracker.trackEvent('error waiting to whitelisting', { error: err });
      Logger.error('error waiting to whitelist:', err);
      this.finish();
    });
  }

  attemptWhitelist() {
    Tracker.trackEvent('attempting to whitelist');
    var whitelist = () => {
      if (!this.kiteCanRun) {
        Tracker.trackEvent("kite can't run - aborting whitelist");
        Logger.error("kite can't run - aborting whitelist");
        return;
      }
      if (!this.path) {
        Tracker.trackEvent('no path to whitelist');
        return;
      }
      StateController.whitelistPath(this.path).then(() => {
        this.finish();
      }, (err) => {
        if (err.type === 'bad_state' &&
            err.data === StateController.STATES.WHITELISTED) {
          this.finish();
          return;
        }
        Tracker.trackEvent('error whitelisting', { error: err });
        Logger.error('error whitelisting:', err);
        this.attemptWhitelist();
      });
    };
    this.whitelistTimerID = setTimeout(() => {
      whitelist();
    }, Installer.INTERVAL);
  }

  skipWhitelist() {
    Tracker.trackEvent('skipped whitelist');
    this.flow.finishWhitelist();
    return StateController.waitForKite(30, Installer.INTERVAL).then(() => {
      this.finish();
    }, (err) => {
      Tracker.trackEvent('error waiting to whitelist:', { error: err });
      Logger.error('error waiting to whitelist:', err);
      this.finish();
    });
  }

  finish() {
    var endProgress = () => {
      this.flow.finishFlow();
      if (typeof this.onFinish === 'function') {
        this.onFinish();
      }
    };
    var prom = AtomHelper.installPackage();
    if (!prom) {
      Tracker.trackEvent('no kite.js - finishing flow');
      endProgress();
    } else {
      prom.then(() => {
        Tracker.trackEvent('installing kite.js and finishing');
        endProgress();
      }, (err) => {
        Tracker.trackEvent('error installing kite.js - finishing', { error: err });
        Logger.error('error refreshing Atom package:', err);
        endProgress();
      });
    }
  }

  getUserEmail() {
    var proc = child_process.spawnSync('git', ['config', 'user.email'], {
      encoding: 'utf8',
    });
    return proc.stdout.trim();
  }

  parseUserEmail() {
    try {
      this.parsedEmail = null;
      var cfg = fs.readFileSync(path.join(os.homedir(), '.gitconfig')).toString();
      var lines = cfg.split('\n');
      for (var i = 0; i < lines.length; i++) {
        var items = lines[i].trim().split('=');
        if (items[0].trim() === 'email') {
          this.parsedEmail = items[1].trim();
          break;
        }
      }
    } catch (err) {
      Tracker.trackEvent('error parsing gitconfig', { error: err.message });
      Logger.error('error parsing gitconfig:', err);
    }
  }
};

module.exports = Installer;
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * Library of common methods for manipulating instances.
 */
/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

var q = require('q');
var persistence = require('../persistence/dispatcher');
var jiveUtil = require('./jiveutil');
var jiveClient = require('./client');

function Instances() {
}

Instances.prototype = Object.create({}, {
    constructor: {
        value: Instances,
        enumerable: false
    }
});

module.exports = Instances;

var returnOne = function(found ) {
    if ( found == null || found.length < 1 ) {
        return null;
    } else {
        // return first one
        return found[0];
    }
};

Instances.prototype.getCollection = function() {
    throw 'Must be subclassed';
};

Instances.prototype.save = function (tileInstance) {
    if (!tileInstance.id) {
        tileInstance.id = jiveUtil.guid();
    }

    return persistence.save(this.getCollection(), tileInstance.id, tileInstance );
};

Instances.prototype.find = function ( keyValues, expectOne ) {
    return persistence.find(this.getCollection(), keyValues).then( function( found ) {
        return expectOne ? returnOne( found ) : found;
    } );
};

Instances.prototype.findByID = function (tileInstanceID) {
    return this.find( { "id" : tileInstanceID }, true );
};

Instances.prototype.findByDefinitionName = function (definitionName) {
    return this.find( { "name": definitionName } );
};

Instances.prototype.findByScope = function (scope) {
    return this.find( { "scope" : scope }, true );
};

Instances.prototype.findAll = function () {
    return this.find( null );
};

Instances.prototype.remove = function (tileInstanceID) {
    return persistence.remove(self.getCollection(), tileInstanceID );
};

Instances.prototype.register = function (client_id, url, config, name, code ) {
    var deferred = q.defer();

    var options = {
        client_id: client_id,
        code: code
    };

    jiveClient.TileInstance.register(options, function (accessTokenResponse) {
        console.log("Reached Access Token Exchange callback", accessTokenResponse);

        var tileInstance = {
            url: url,
            setup: config,
            name: name
        };

        tileInstance['accessToken'] = accessTokenResponse['access_token'];
        tileInstance['expiresIn'] = accessTokenResponse['expires_in'];
        tileInstance['refreshToken'] = accessTokenResponse['refresh_token'];
        tileInstance['scope'] = accessTokenResponse['scope'];

        deferred.resolve( tileInstance );
    });

    return deferred.promise;
};

Instances.prototype.refreshAccessToken = function (client_id, tileInstance) {

    var options = {
        client_id: client_id,
        refresh_token: tileInstance['refreshToken']
    };

    var deferred = q.defer();

    jiveClient.TileInstance.refreshAccessToken(options,
        function (accessTokenResponse) {
            // success
            tileInstance['accessToken'] = accessTokenResponse['access_token'];
            tileInstance['expiresIn'] = accessTokenResponse['expires_in'];
            tileInstance['refreshToken'] = accessTokenResponse['refresh_token'];
            deferred.resolve(tileInstance);
        }, function (result) {
            // failure
            console.log('error refreshing access token for ', tileInstance, result);
            deferred.reject(result);
        }
    );

    return deferred.promise;
};
<commit_msg>Cleanup<commit_after>/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * Library of common methods for manipulating instances.
 */
/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

var q = require('q');
var persistence = require('../persistence/dispatcher');
var jiveUtil = require('./jiveutil');
var jiveClient = require('./client');

function Instances() {
}

Instances.prototype = Object.create({}, {
    constructor: {
        value: Instances,
        enumerable: false
    }
});

module.exports = Instances;

var returnOne = function(found ) {
    if ( found == null || found.length < 1 ) {
        return null;
    } else {
        // return first one
        return found[0];
    }
};

Instances.prototype.getCollection = function() {
    throw 'Must be subclassed';
};

Instances.prototype.save = function (tileInstance) {
    if (!tileInstance.id) {
        tileInstance.id = jiveUtil.guid();
    }

    return persistence.save(this.getCollection(), tileInstance.id, tileInstance );
};

Instances.prototype.find = function ( keyValues, expectOne ) {
    return persistence.find(this.getCollection(), keyValues).then( function( found ) {
        return expectOne ? returnOne( found ) : found;
    } );
};

Instances.prototype.findByID = function (tileInstanceID) {
    return this.find( { "id" : tileInstanceID }, true );
};

Instances.prototype.findByDefinitionName = function (definitionName) {
    return this.find( { "name": definitionName } );
};

Instances.prototype.findByScope = function (scope) {
    return this.find( { "scope" : scope }, true );
};

Instances.prototype.findAll = function () {
    return this.find( null );
};

Instances.prototype.remove = function (tileInstanceID) {
    return persistence.remove(this.getCollection(), tileInstanceID );
};

Instances.prototype.register = function (client_id, url, config, name, code ) {
    var deferred = q.defer();

    var options = {
        client_id: client_id,
        code: code
    };

    jiveClient.TileInstance.register(options, function (accessTokenResponse) {
        console.log("Reached Access Token Exchange callback", accessTokenResponse);

        var tileInstance = {
            url: url,
            setup: config,
            name: name
        };

        tileInstance['accessToken'] = accessTokenResponse['access_token'];
        tileInstance['expiresIn'] = accessTokenResponse['expires_in'];
        tileInstance['refreshToken'] = accessTokenResponse['refresh_token'];
        tileInstance['scope'] = accessTokenResponse['scope'];

        deferred.resolve( tileInstance );
    });

    return deferred.promise;
};

Instances.prototype.refreshAccessToken = function (client_id, tileInstance) {

    var options = {
        client_id: client_id,
        refresh_token: tileInstance['refreshToken']
    };

    var deferred = q.defer();

    jiveClient.TileInstance.refreshAccessToken(options,
        function (accessTokenResponse) {
            // success
            tileInstance['accessToken'] = accessTokenResponse['access_token'];
            tileInstance['expiresIn'] = accessTokenResponse['expires_in'];
            tileInstance['refreshToken'] = accessTokenResponse['refresh_token'];
            deferred.resolve(tileInstance);
        }, function (result) {
            // failure
            console.log('error refreshing access token for ', tileInstance, result);
            deferred.reject(result);
        }
    );

    return deferred.promise;
};
<|endoftext|>


<commit_before>/**
 * Copyright 2015 Mozilla
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

// Import this first so we can use it to wrap other modules we import.
var promisify = require("promisify-node");

var fs = promisify(require('fs'));
var path = require('path');
var gutil = require('gulp-util');

function copyFile(src, dest) {
  return new Promise(function(resolve, reject) {
    var srcStream = fs.createReadStream(src);

    srcStream.pipe(fs.createWriteStream(dest));

    srcStream.on('error', reject);

    srcStream.on('end', function() {
      console.log(gutil.colors.blue(
        'Your app needs to load the script offline-manager.js in order to register the service\n' +
        'worker that offlines your app. To load the script, add this line to your app\'s HTML\n' +
        'page(s)/template(s):\n\n' +
        '\t<script src="' + dest + '"></script>'
      ));

      resolve();
    });
  });
}

module.exports = function(config) {
  var dir = config.dir || './';

  return fs.stat(dir).then(function(stat) {
    if (!stat.isDirectory()) {
      throw new Error(dir + ' isn\'t a directory.');
    }

    return copyFile(path.join(path.dirname(__dirname), 'app', 'scripts', 'offline-manager.js'),
                    path.join(dir, 'offline-manager.js'));
  }, function() {
    throw new Error(dir + ' doesn\'t exist.');
  });
};
<commit_msg>Don't promisify 'fs' because it could cause problems with other code which doesn't promisify it<commit_after>/**
 * Copyright 2015 Mozilla
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

// Import this first so we can use it to wrap other modules we import.
var promisify = require("promisify-node");

var fs = require('fs');
var path = require('path');
var gutil = require('gulp-util');

function copyFile(src, dest) {
  return new Promise(function(resolve, reject) {
    var srcStream = fs.createReadStream(src);

    srcStream.pipe(fs.createWriteStream(dest));

    srcStream.on('error', reject);

    srcStream.on('end', function() {
      console.log(gutil.colors.blue(
        'Your app needs to load the script offline-manager.js in order to register the service\n' +
        'worker that offlines your app. To load the script, add this line to your app\'s HTML\n' +
        'page(s)/template(s):\n\n' +
        '\t<script src="' + dest + '"></script>'
      ));

      resolve();
    });
  });
}

module.exports = function(config) {
  var dir = config.dir || './';

  return new Promise(function(resolve, reject) {
    fs.stat(dir, function(err, stat) {
      if (err) {
        reject(new Error(dir + ' doesn\'t exist or is not accessible.'));
        return;
      }

      if (!stat.isDirectory()) {
        reject(new Error(dir + ' isn\'t a directory.'));
        return;
      }

      copyFile(path.join(path.dirname(__dirname), 'app', 'scripts', 'offline-manager.js'),
               path.join(dir, 'offline-manager.js')).then(resolve, reject);
    });
  });
};
<|endoftext|>


<commit_before>
'use strict';

//
// Module Dependencies
//

var url   = require('url');
var async = require('async');
var _     = require('underscore');

//
// IOStreams provides a grouping and generic linking functions
// for input and output stream connectors/generators
//
var IOStreams = function () {

  this.providers = [];

  return this;
};

//
// A method to add providers to IOStreams
// @param  {Object} provider Should have to callable functions getInputStream(config) and getOutputStream(config)
// @return {Number}          Number of providers now available
//
IOStreams.prototype.use = function(provider) {
  return this.providers.push(provider);
};

//
// Geds a provider that supports a certain protocol
// @param  {String} protocol e.g 'file:', 'http:' or 's3:'
// @return {Object}          A provider object
//
IOStreams.prototype.getProviderByProtocol = function(protocol) {

  var provider = _.find(this.providers, function(provider) {
    return provider.protocol === protocol;
  });

  if(!provider) {
    throw new Error('No provider found supporting the protocol `' + protocol + '`');
  }

  return provider;

};

//
// Parse config into a consistent structure
// @param  {String | Object} config
// @return {Object}
//
IOStreams.prototype.parseConfig = function(config) {
  if(typeof config === 'string') {
    config = url.parse(config);
  }
  return config;
};

//
// Opens a stream from wherever the destined input is
// @param  {String | Object}   config
// @param  {Function} callback (err, inputStream)
// @return {Void}
//
IOStreams.prototype.getInputStream = function(config, callback) {

  config = this.parseConfig(config);

  var provider;

  try {
    provider = this.getProviderByProtocol(config.protocol);
  } catch (err) {
    return callback(err);
  }

  return provider.getInputStream(config, callback);

};

//
// Opens a stream to wherever the destined output is
// @param  {String | Object}   config
// @param  {Function} callback (err, outputStream)
// @return {Void}
//
IOStreams.prototype.getOutputStream = function(config, callback) {

  config = this.parseConfig(config);

  var provider;

  try {
    provider = this.getProviderByProtocol(config.protocol);
  } catch (err) {
    return callback(err);
  }

  return provider.getOutputStream(config, callback);

};

//
// Lazy function to get Input and Output Streams
// @param  {String | Object}   inputConfig
// @param  {String | Object}   outputConfig [description]
// @param  {Function} callback     (err, inputStream, outputStream)
// @return {Void}
//
IOStreams.prototype.getInputOutputStreams = function(inputConfig, outputConfig, callback) {

  var self = this;

  async.parallel([
    function(callback) {
      self.getInputStream(inputConfig, callback);
    },
    function(callback) {
      self.getOutputStream(outputConfig, callback);
    }
  ], function(err, results) {
    callback(err, results[0], results[1]);
  });

};

//
// Create an instance of IOStreams
// @return {IOStreams}
//
var createInstance = function() {
  return new IOStreams();
};

//
// Exports
//

module.exports           = createInstance;
module.exports.IOStreams = IOStreams;<commit_msg>Remove url parsing config<commit_after>
'use strict';

//
// Module Dependencies
//

var url   = require('url');
var async = require('async');
var _     = require('underscore');

//
// IOStreams provides a grouping and generic linking functions
// for input and output stream connectors/generators
//
var IOStreams = function () {

  this.providers = [];

  return this;
};

//
// A method to add providers to IOStreams
// @param  {Object} provider Should have to callable functions getInputStream(config) and getOutputStream(config)
// @return {Number}          Number of providers now available
//
IOStreams.prototype.use = function(provider) {
  return this.providers.push(provider);
};

//
// Geds a provider that supports a certain protocol
// @param  {String} protocol e.g 'file:', 'http:' or 's3:'
// @return {Object}          A provider object
//
IOStreams.prototype.getProviderByProtocol = function(protocol) {

  var provider = _.find(this.providers, function(provider) {
    return provider.protocol === protocol;
  });

  if(!provider) {
    throw new Error('No provider found supporting the protocol `' + protocol + '`');
  }

  return provider;

};

//
// Opens a stream from wherever the destined input is
// @param  {String | Object}   config
// @param  {Function} callback (err, inputStream)
// @return {Void}
//
IOStreams.prototype.getInputStream = function(config, callback) {

  var provider;

  try {
    provider = this.getProviderByProtocol(config.protocol);
  } catch (err) {
    return callback(err);
  }

  return provider.getInputStream(config, callback);

};

//
// Opens a stream to wherever the destined output is
// @param  {String | Object}   config
// @param  {Function} callback (err, outputStream)
// @return {Void}
//
IOStreams.prototype.getOutputStream = function(config, callback) {

  var provider;

  try {
    provider = this.getProviderByProtocol(config.protocol);
  } catch (err) {
    return callback(err);
  }

  return provider.getOutputStream(config, callback);

};

//
// Lazy function to get Input and Output Streams
// @param  {String | Object}   inputConfig
// @param  {String | Object}   outputConfig [description]
// @param  {Function} callback     (err, inputStream, outputStream)
// @return {Void}
//
IOStreams.prototype.getInputOutputStreams = function(inputConfig, outputConfig, callback) {

  var self = this;

  async.parallel([
    function(callback) {
      self.getInputStream(inputConfig, callback);
    },
    function(callback) {
      self.getOutputStream(outputConfig, callback);
    }
  ], function(err, results) {
    callback(err, results[0], results[1]);
  });

};

//
// Create an instance of IOStreams
// @return {IOStreams}
//
var createInstance = function() {
  return new IOStreams();
};

//
// Exports
//

module.exports           = createInstance;
module.exports.IOStreams = IOStreams;<|endoftext|>


<commit_before>import React from 'react';

import mpService from '../../services/mp-service'
import totalService from '../../services/totals-service'
import Mp from '../../widgets/mp'
import List from '../../widgets/list'
import DetailsMenu from '../../widgets/details-menu'

import './styles.css'

let searchInput = ''

const initialLthingsMenuList = [
  {
    name: 'Samtölur',
    url: '/thing/allt',
  }
]

export default class Mps extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      lthing: null,
      mps: [],
      lthings: [],
      searchInput: '',
      sortByParty: false,
    }
  }

  componentWillMount() {
    const lthing = this.props.params.lthing
    this.getData(lthing)
    this.setSorting(this.props)
  }

  componentWillReceiveProps(nextProps) {
    const lthing = nextProps.params.lthing

    this.getData(lthing)
    this.setSorting(this.props)
  }

  getData(lthing) {
    mpService.getMpsByLthing(lthing)
      .then(mps => {
        this.setState(() => ({ mps, lthing }))
      })

    totalService.getLthings()
      .then(lthings => {
        this.setState(() => ({ lthings }))
      })
  }

  handleSearchInput = (evt) => {
    searchInput = evt.target.value
    this.setState({
      searchInput
    })
  }

  searchFilter(mp) {
    const { searchInput } = this.state
    if (searchInput) {
      return (mp.name.toLowerCase().indexOf(searchInput.toLowerCase()) !== -1)
    }
    return mp
  }

  setSorting(props) {
    const { query } = props.location
    const sortByParty = query.rada === 'flokkar'
    this.setState(() => ({ sortByParty, searchInput }))
  }

  sortItem(mp1, mp2) {
    if (this.state.sortByParty) {
      return mp1.party.localeCompare(mp2.partyId)
    }
    return mp1.mpName.localeCompare(mp2.mpName)
  }

  render() {
    const { mps, sortByParty, lthing, lthings } = this.state

    const items = mps.filter(this.searchFilter.bind(this))
        .sort(this.sortItem.bind(this))

    const lthingsFormatted = lthings.map(lthing => ({
      year: lthing.start.split('.')[2],
      thing: lthing.id,
      url: `/thing/${lthing.id}`
    }))

    const lthingsToRender = initialLthingsMenuList.concat(lthingsFormatted)

    return (

Allir þingmenn

        <DetailsMenu menuItems={lthingsToRender}/>
        <List>
          {items.map(mp => (
            <Mp key={mp.id} lthing={lthing} {...mp} />
          ))}
        </List>

    );
  }
}
<commit_msg>Change heading of total things for mps<commit_after>import React from 'react';

import mpService from '../../services/mp-service'
import totalService from '../../services/totals-service'
import Mp from '../../widgets/mp'
import List from '../../widgets/list'
import DetailsMenu from '../../widgets/details-menu'

import './styles.css'

let searchInput = ''

const initialLthingsMenuList = [
  {
    name: 'Öll þing',
    url: '/thing/allt',
  }
]

export default class Mps extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      lthing: null,
      mps: [],
      lthings: [],
      searchInput: '',
      sortByParty: false,
    }
  }

  componentWillMount() {
    const lthing = this.props.params.lthing
    this.getData(lthing)
    this.setSorting(this.props)
  }

  componentWillReceiveProps(nextProps) {
    const lthing = nextProps.params.lthing

    this.getData(lthing)
    this.setSorting(this.props)
  }

  getData(lthing) {
    mpService.getMpsByLthing(lthing)
      .then(mps => {
        this.setState(() => ({ mps, lthing }))
      })

    totalService.getLthings()
      .then(lthings => {
        this.setState(() => ({ lthings }))
      })
  }

  handleSearchInput = (evt) => {
    searchInput = evt.target.value
    this.setState({
      searchInput
    })
  }

  searchFilter(mp) {
    const { searchInput } = this.state
    if (searchInput) {
      return (mp.name.toLowerCase().indexOf(searchInput.toLowerCase()) !== -1)
    }
    return mp
  }

  setSorting(props) {
    const { query } = props.location
    const sortByParty = query.rada === 'flokkar'
    this.setState(() => ({ sortByParty, searchInput }))
  }

  sortItem(mp1, mp2) {
    if (this.state.sortByParty) {
      return mp1.party.localeCompare(mp2.partyId)
    }
    return mp1.mpName.localeCompare(mp2.mpName)
  }

  render() {
    const { mps, sortByParty, lthing, lthings } = this.state

    const items = mps.filter(this.searchFilter.bind(this))
        .sort(this.sortItem.bind(this))

    const lthingsFormatted = lthings.map(lthing => ({
      year: lthing.start.split('.')[2],
      thing: lthing.id,
      url: `/thing/${lthing.id}`
    }))

    const lthingsToRender = initialLthingsMenuList.concat(lthingsFormatted)

    return (

Allir þingmenn

        <DetailsMenu menuItems={lthingsToRender}/>
        <List>
          {items.map(mp => (
            <Mp key={mp.id} lthing={lthing} {...mp} />
          ))}
        </List>

    );
  }
}
<|endoftext|>


<commit_before>/**
 * This function looking array into for searched key.
 *
 * @param {*} element - Searching for this key
 * @returns {Boolean} - If Array contains element the function will return boolean.
 */
Array.prototype.contains = function (element) {
  return this.indexOf(element) > -1;
};

/**
 * This function create csv from object
 *
 * @param  {Object} json - Containing incoming json data.
 * @param  {Function} callback - It's callback and if csv is created successfully
 * it will be return csv type string
 */
module.exports = function (json, callback) {
  if (!callback || typeof callback !== 'function') {
    throw new Error('Callback is required');
  }

  if (!json || typeof json !== 'object') {
    callback('Json is required');
  }

  // If json file is has not parent array push this to an array
  var dataArr = Array.isArray(json) ? json : [json];
  var csvHeader = [],
    csvHeadEachDone = false,
    csvValues = "",
    objIndex = 0,
    fullCsv = "";

  dataArr.forEach(function (value, index) {

    // If csv header pushing done set value to true
    csvHeadEachDone = (index === (dataArr.length - 1));

    // Pushing headers into an array
    for (var prop in value) {

      // Check header if exist in array, don't push
      if (!csvHeader.contains(prop)) {
        csvHeader.push(prop);
      }
    }

    // If Csv Headers Each Done
    if (csvHeadEachDone) {

      // Loop for data array
      for (var obj of dataArr) {

        for (var key of csvHeader) {
          objIndex++;

          // If object key undefined, set this empty
          obj[key] = (typeof obj[key] == "undefined") ? '" "' : obj[key];

          // If string contais comma, take this into double quotes
          obj[key] = (String(obj[key]).indexOf(",") > -1) ? '"'+ obj[key] +'"' : obj[key];

          // Push into a string the values and if line is ending, seperate with comma
          if (objIndex % csvHeader.length == 0) {
            csvValues += obj[key] + " \n";
          } else {
            csvValues += obj[key] + ",";
          }
        }
      }

      // Set full csv as string
      fullCsv = csvHeader + "\n" + csvValues;

    }
  });

  callback(null, fullCsv);
}
<commit_msg>Array.contains function is now return boolean<commit_after>/**
 * This function looking array into for searched key.
 *
 * @param {*} element - Searching for this key
 * @returns {Boolean} - If Array contains element the function will return boolean.
 */
Array.prototype.contains = function (element) {
  return !!this.indexOf(element) > -1;
};

/**
 * This function create csv from object
 *
 * @param  {Object} json - Containing incoming json data.
 * @param  {Function} callback - It's callback and if csv is created successfully
 * it will be return csv type string
 */
module.exports = function (json, callback) {
  if (!callback || typeof callback !== 'function') {
    throw new Error('Callback is required');
  }

  if (!json || typeof json !== 'object') {
    callback('Json is required');
  }

  // If json file is has not parent array push this to an array
  var dataArr = Array.isArray(json) ? json : [json];
  var csvHeader = [],
    csvHeadEachDone = false,
    csvValues = "",
    objIndex = 0,
    fullCsv = "";

  dataArr.forEach(function (value, index) {

    // If csv header pushing done set value to true
    csvHeadEachDone = (index === (dataArr.length - 1));

    // Pushing headers into an array
    for (var prop in value) {

      // Check header if exist in array, don't push
      if (!csvHeader.contains(prop)) {
        csvHeader.push(prop);
      }
    }

    // If Csv Headers Each Done
    if (csvHeadEachDone) {

      // Loop for data array
      for (var obj of dataArr) {

        for (var key of csvHeader) {
          objIndex++;

          // If object key undefined, set this empty
          obj[key] = (typeof obj[key] == "undefined") ? '" "' : obj[key];

          // If string contais comma, take this into double quotes
          obj[key] = (String(obj[key]).indexOf(",") > -1) ? '"'+ obj[key] +'"' : obj[key];

          // Push into a string the values and if line is ending, seperate with comma
          if (objIndex % csvHeader.length == 0) {
            csvValues += obj[key] + " \n";
          } else {
            csvValues += obj[key] + ",";
          }
        }
      }

      // Set full csv as string
      fullCsv = csvHeader + "\n" + csvValues;

    }
  });

  callback(null, fullCsv);
}
<|endoftext|>


<commit_before>import { React, PropTypes, cn, styled, observer, css } from 'vendor';
import { colors } from 'theme';
import Question from 'shared/components/question';

const HomeworkQuestionsWrapper = styled.div`

`;

const QuestionPreview = styled.div`
  border: 1px solid ${colors.neutral.pale};
  margin: 2.4rem 0;
  &:first-of-type {
   .ox-icon-arrow-up { display: none; }
  }
  &:last-of-type {
   .ox-icon-arrow-down { display: none; }
  }
  .frame-wrapper {
    width: 100%;
    min-width: 100%;
    margin: 0;
  }
`;

const QuestionHeader = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: ${colors.neutral.lighter}
  padding: 1rem;
  font-weight: bold;

  ${props => props.variant === 'submission' && css`
    background: ${colors.templates.homework.background};
    font-size: 1.8rem;
    font-weight: normal;
    padding: 1.4rem 2.2rem;
  `}
`;

const Body = styled.div`
  ${props => props.variant === 'submission' && css`
    && {
      background: ${colors.assignments.submissions.background};
      padding: 3.2rem 2.8rem;

      &.card-body .question-stem {
        font-size: 1.8rem;
        font-weight: normal;
        line-height: 3.0rem;
        margin-bottom: 2.2rem;
      }

      .answer-answer {
        margin: 0 0 1.2rem 1.5rem;
        font-size: 1.6rem;
      }
    }

    .review-count {
      align-self: flex-start;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-radius: 25%/50%;
      min-width: 5.6rem;
      padding: 0.1rem;
      font-weight: bold;

      .selected-count {
        display: flex;
        align-items: center;
        justify-content: center;
        min-width: 2.5rem;
        height: 1.9rem;
        margin-right: 0.2rem;
        border-right: 1px solid rgba(0,0,0,0.15);
        font-size: 1.4rem;
      }

      .letter {
        height: 2.5rem;
        width: 2.5rem;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #fff;
        border: 1px solid rgba(0,0,0,0.25);
        border-radius: 100%;
        font-size: 1.2rem;
      }

      &.red {
        background: #FFE6EA;
        .selected-count {
          color:  #C22032;
          border-color: #E9C4CA;
        }
      }
      &.green {
        background: #ECF7D1;
        color:  #3B7800;
        .selected-count {
          border-color: #D7E3B8;
        }
      }
    }

    .letter {
      height: 2.5rem;
      width: 2.5rem;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #fff;
      border: 1px solid rgba(0,0,0,0.25);
      border-radius: 100%;
      font-size: 1.2rem;

      &.red {
        border-color: rgba(194,32,50,0.5);
        color: ${colors.neutral.grayblue};
      }

      &.green {
        background-color: #63A524;
        color: #fff;
        border-color: #4B8315;
      }
    }
  `}
`;

const ExerciseNumber = styled.div`
  font-size: 1.6rem;

  ${props => props.variant === 'submission' && css`
    font-size: 1.8rem;
    font-weight: bold;
  `}
`;

export { Question, QuestionPreview, QuestionHeader, ExerciseNumber };

const ReviewExerciseCard = observer(({
  index, info,
  questionInfoRenderer: QuestionInfo,
  headerContentRenderer: HeaderContent,
  questionType = 'teacher-preview',
  styleVariant = 'points',
}) => (
  <QuestionPreview className="openstax-exercise-preview">
    <QuestionHeader variant={styleVariant} className="question-header">
      <HeaderContent styleVariant={styleVariant} info={info} label={`Question ${index + 1}`} />
    </QuestionHeader>
    <Body className="card-body" variant={styleVariant}>
      <Question
        className="openstax-question-preview"
        question={info.question}
        hideAnswers={false}
        choicesEnabled={false}
        displayFormats={false}
        type={questionType}
      />
      {QuestionInfo && <QuestionInfo info={info} />}
    </Body>
  </QuestionPreview>
));
ReviewExerciseCard.dislayName = 'ReviewExerciseCard';
ReviewExerciseCard.propTypes = {
  headerContentRenderer: PropTypes.func.isRequired,
  questionInfoRenderer: PropTypes.func,
};

const HomeworkQuestions = observer(({
  questionsInfo,
  questionType,
  className,
  headerContentRenderer,
  questionInfoRenderer,
  styleVariant,
}) => (
  <HomeworkQuestionsWrapper className={cn('homework-questions', className)}>
    {questionsInfo.map((info, index) => (
      <ReviewExerciseCard
        info={info}
        index={index}
        questionType={questionType}
        key={info.key}
        headerContentRenderer={headerContentRenderer}
        questionInfoRenderer={questionInfoRenderer}
        styleVariant={styleVariant}
      />
    ))}
  </HomeworkQuestionsWrapper>
));

HomeworkQuestions.displayName = 'HomeworkQuestions';
HomeworkQuestions.propTypes = {
  headerContentRenderer: PropTypes.func.isRequired,
  questionInfoRenderer: PropTypes.func,
  questionType: PropTypes.string,
  questionsInfo: PropTypes.array.isRequired,
  styleVariant: PropTypes.string,
};
export default HomeworkQuestions;
<commit_msg>missing ;<commit_after>import { React, PropTypes, cn, styled, observer, css } from 'vendor';
import { colors } from 'theme';
import Question from 'shared/components/question';

const HomeworkQuestionsWrapper = styled.div`

`;

const QuestionPreview = styled.div`
  border: 1px solid ${colors.neutral.pale};
  margin: 2.4rem 0;
  &:first-of-type {
   .ox-icon-arrow-up { display: none; }
  }
  &:last-of-type {
   .ox-icon-arrow-down { display: none; }
  }
  .frame-wrapper {
    width: 100%;
    min-width: 100%;
    margin: 0;
  }
`;

const QuestionHeader = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: ${colors.neutral.lighter};
  padding: 1rem;
  font-weight: bold;

  ${props => props.variant === 'submission' && css`
    background: ${colors.templates.homework.background};
    font-size: 1.8rem;
    font-weight: normal;
    padding: 1.4rem 2.2rem;
  `}
`;

const Body = styled.div`
  ${props => props.variant === 'submission' && css`
    && {
      background: ${colors.assignments.submissions.background};
      padding: 3.2rem 2.8rem;

      &.card-body .question-stem {
        font-size: 1.8rem;
        font-weight: normal;
        line-height: 3.0rem;
        margin-bottom: 2.2rem;
      }

      .answer-answer {
        margin: 0 0 1.2rem 1.5rem;
        font-size: 1.6rem;
      }
    }

    .review-count {
      align-self: flex-start;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-radius: 25%/50%;
      min-width: 5.6rem;
      padding: 0.1rem;
      font-weight: bold;

      .selected-count {
        display: flex;
        align-items: center;
        justify-content: center;
        min-width: 2.5rem;
        height: 1.9rem;
        margin-right: 0.2rem;
        border-right: 1px solid rgba(0,0,0,0.15);
        font-size: 1.4rem;
      }

      .letter {
        height: 2.5rem;
        width: 2.5rem;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #fff;
        border: 1px solid rgba(0,0,0,0.25);
        border-radius: 100%;
        font-size: 1.2rem;
      }

      &.red {
        background: #FFE6EA;
        .selected-count {
          color:  #C22032;
          border-color: #E9C4CA;
        }
      }
      &.green {
        background: #ECF7D1;
        color:  #3B7800;
        .selected-count {
          border-color: #D7E3B8;
        }
      }
    }

    .letter {
      height: 2.5rem;
      width: 2.5rem;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #fff;
      border: 1px solid rgba(0,0,0,0.25);
      border-radius: 100%;
      font-size: 1.2rem;

      &.red {
        border-color: rgba(194,32,50,0.5);
        color: ${colors.neutral.grayblue};
      }

      &.green {
        background-color: #63A524;
        color: #fff;
        border-color: #4B8315;
      }
    }
  `}
`;

const ExerciseNumber = styled.div`
  font-size: 1.6rem;

  ${props => props.variant === 'submission' && css`
    font-size: 1.8rem;
    font-weight: bold;
  `}
`;

export { Question, QuestionPreview, QuestionHeader, ExerciseNumber };

const ReviewExerciseCard = observer(({
  index, info,
  questionInfoRenderer: QuestionInfo,
  headerContentRenderer: HeaderContent,
  questionType = 'teacher-preview',
  styleVariant = 'points',
}) => (
  <QuestionPreview className="openstax-exercise-preview">
    <QuestionHeader variant={styleVariant} className="question-header">
      <HeaderContent styleVariant={styleVariant} info={info} label={`Question ${index + 1}`} />
    </QuestionHeader>
    <Body className="card-body" variant={styleVariant}>
      <Question
        className="openstax-question-preview"
        question={info.question}
        hideAnswers={false}
        choicesEnabled={false}
        displayFormats={false}
        type={questionType}
      />
      {QuestionInfo && <QuestionInfo info={info} />}
    </Body>
  </QuestionPreview>
));
ReviewExerciseCard.dislayName = 'ReviewExerciseCard';
ReviewExerciseCard.propTypes = {
  headerContentRenderer: PropTypes.func.isRequired,
  questionInfoRenderer: PropTypes.func,
};

const HomeworkQuestions = observer(({
  questionsInfo,
  questionType,
  className,
  headerContentRenderer,
  questionInfoRenderer,
  styleVariant,
}) => (
  <HomeworkQuestionsWrapper className={cn('homework-questions', className)}>
    {questionsInfo.map((info, index) => (
      <ReviewExerciseCard
        info={info}
        index={index}
        questionType={questionType}
        key={info.key}
        headerContentRenderer={headerContentRenderer}
        questionInfoRenderer={questionInfoRenderer}
        styleVariant={styleVariant}
      />
    ))}
  </HomeworkQuestionsWrapper>
));

HomeworkQuestions.displayName = 'HomeworkQuestions';
HomeworkQuestions.propTypes = {
  headerContentRenderer: PropTypes.func.isRequired,
  questionInfoRenderer: PropTypes.func,
  questionType: PropTypes.string,
  questionsInfo: PropTypes.array.isRequired,
  styleVariant: PropTypes.string,
};
export default HomeworkQuestions;
<|endoftext|>