<commit_before>define(
  [
    'jquery',
    'vue',
    'lib/gmaps',
    'text!partials/directions.html'
  ],
  function(
      $,
      Vue,
      gmaps,
      template
  ) {

    Vue.component('directions', {
      template: template,

      data: {
        location: 'Barra Funda',
        destination: 'Pinheiros',
        short: '',
        steps: []
      },

      methods: {
        submit: function(event) {
          this.calcRoute();
          event.stopPropagation();
          event.preventDefault();
        },

        calcRoute: function() {
          var directionsService = new gmaps.DirectionsService();
          var origin = new gmaps.LatLng(-23.647066,-46.63954); // jabaquara
          var destination = new gmaps.LatLng(-23.5554674, -46.6359057); // liberdade
          var request = {
                origin: origin,
                destination: destination,
                travelMode: gmaps.TravelMode.WALKING
          };
          var self = this;
          directionsService.route(request, function(response, status) {
            var steps = [];
            var duration = '';
            var distance = '';
              if (status == google.maps.DirectionsStatus.OK) {
                console.log(response.routes[0]);
                distance = response.routes[0].legs[0].distance.text;
                duration = response.routes[0].legs[0].duration.text;
                self.short = 'Siga pela ' + response.routes[0].summary + ' por aproximadamente ' + duration + ' (total de ' + distance + ')';

                steps = response.routes[0].legs[0].steps;
                self.steps = steps;
              }
            });
        }
      }
    });

  }
);
<commit_msg>Removed old directions module.<commit_after><|endoftext|>


<commit_before>/**
 * The StoriesKeep view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'handlebars',
  'mps',
  'simplePagination',
  'text!static/templates/storiesKeep.handlebars',
], function($,Backbone,underscore,Handlebars,mps,simplePagination, storiesTPL) {

  'use strict';

  var StoriesKeepModel = Backbone.Model.extend({
    defaults: {
      total: null,
      perpage: null,
      page: null
    },
  })

  var StoriesKeepView = Backbone.View.extend({

    el: '#storiesKeepView',

    template: Handlebars.compile(storiesTPL),

    initialize: function() {
      if (!this.$el.length) {
        return
      }
      //CACHE
      this.$htmlbody = $('html, body');
      this.$sideBar = $('#sidebarNavView');
      this.$sourcesBox = $('#sources-box');
      this.$container = $('#crowdsourced-stories');
      this.$spinner = $('#sources-spinner');
      this.$listContainer = $('#storiesKeepList');
      this.$paginationContainer = $('#pagination-container');

      //VARS
      this.model = new StoriesKeepModel({
        total: this.$paginationContainer.data('total'),
        perpage: this.$paginationContainer.data('perpage'),
        page: this.$paginationContainer.data('page')
      });

      this.initPaginate();
    },

    initPaginate: function(){
      // pagination
      this.$paginationContainer.pagination({
        items: this.model.get('total'),
        itemsOnPage : this.model.get('perpage'),
        currentPage : this.model.get('page'),
        displayedPages: 3,
        selectOnClick: false,
        prevText: ' ',
        nextText: ' ',
        onPageClick: _.bind(function(pageNumber, event){
          event.preventDefault();
          this.$paginationContainer.pagination('drawPage', pageNumber);
          this.$spinner.addClass('start');
          this.$container.addClass('start');
          ($(window).width() >= 850 ) ? this.$htmlbody.animate({ scrollTop: this.$sideBar.offset().top }, 500) : this.$sourcesBox.animate({ scrollTop: 0 }, 500);
          this.loadAjaxStories(pageNumber);
          mps.publish('SourceStatic/Silentupdate',[{section: 'crowdsourced-stories', page: pageNumber}]);

        }, this )
      });
    },

    loadAjaxStories: function(page){
      $.ajax({
        url: '/stayinformed-stories.json',
        type: 'GET',
        dataType: 'json',
        data: {
          for_stay: true,
          page: page,
          perpage: this.model.get('perpage')
        },
        success: _.bind(function(data){
          this.parse(data);
        }, this ),
        error: function(err){
          console.log(err);
        }
      })
    },

    parse: function(data){
      this.data = _.map(data, _.bind(function(item){
        var img = (! item.media.length) ? null : item.media[item.media.length -1].preview_url;
        var detail = (item.details.length > 295) ? item.details.substr(0, 295)+'...' : item.details;
        return {
          title: item.title,
          details: detail,
          link: '/stories/'+item.id,
          map: (img) ? 'http://gfw2stories.s3.amazonaws.com/uploads/' + img : 'https://maps.googleapis.com/maps/api/staticmap?center=' + item.lat + ',' + item.lng + '&zoom=2&size=80x80',
        }
      }, this ));

      this.render();
    },

    render: function(){
      this.$spinner.removeClass('start');
      this.$container.removeClass('start');

      this.$listContainer.html(this.template({ stories : this.data }))
    }

  });

  return StoriesKeepView;

});

<commit_msg>Stories loaded via Ajax complete<commit_after>/**
 * The StoriesKeep view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'handlebars',
  'mps',
  'simplePagination',
  'text!static/templates/storiesKeep.handlebars',
], function($,Backbone,underscore,Handlebars,mps,simplePagination, storiesTPL) {

  'use strict';

  var StoriesKeepModel = Backbone.Model.extend({
    defaults: {
      total: null,
      perpage: null,
      page: null
    },
  })

  var StoriesKeepView = Backbone.View.extend({

    el: '#storiesKeepView',

    template: Handlebars.compile(storiesTPL),

    initialize: function() {
      if (!this.$el.length) {
        return
      }
      //CACHE
      this.$htmlbody = $('html, body');
      this.$sideBar = $('#sidebarNavView');
      this.$sourcesBox = $('#sources-box');
      this.$container = $('#crowdsourced-stories');
      this.$spinner = $('#sources-spinner');
      this.$listContainer = $('#storiesKeepList');
      this.$paginationContainer = $('#pagination-container');

      //VARS
      this.model = new StoriesKeepModel({
        total: this.$paginationContainer.data('total'),
        perpage: this.$paginationContainer.data('perpage'),
        page: this.$paginationContainer.data('page')
      });

      this.initPaginate();
    },

    initPaginate: function(){
      // pagination
      this.$paginationContainer.pagination({
        items: this.model.get('total'),
        itemsOnPage : this.model.get('perpage'),
        currentPage : this.model.get('page'),
        displayedPages: 3,
        selectOnClick: false,
        prevText: ' ',
        nextText: ' ',
        onPageClick: _.bind(function(pageNumber, event){
          event.preventDefault();
          this.$paginationContainer.pagination('drawPage', pageNumber);
          this.$spinner.addClass('start');
          this.$container.addClass('start');
          ($(window).width() >= 850 ) ? this.$htmlbody.animate({ scrollTop: this.$sideBar.offset().top }, 500) : this.$sourcesBox.animate({ scrollTop: 0 }, 500);
          this.loadAjaxStories(pageNumber);
          mps.publish('SourceStatic/Silentupdate',[{section: 'crowdsourced-stories', page: pageNumber}]);

        }, this )
      });
    },

    loadAjaxStories: function(page){
      $.ajax({
        url: '/stayinformed-stories.json',
        type: 'GET',
        dataType: 'json',
        data: {
          for_stay: true,
          page: page,
          perpage: this.model.get('perpage')
        },
        success: _.bind(function(data){
          this.parse(data);
        }, this ),
        error: function(err){
          console.log(err);
        }
      })
    },

    parse: function(data){
      this.data = _.map(data, _.bind(function(item){
        var img = (! item.media.length) ? null : item.media[item.media.length -1].preview_url;
        var detail = (item.details.length > 295) ? item.details.substr(0, 295)+'...' : item.details;
        return {
          title: item.title,
          details: detail,
          link: '/stories/'+item.id,
          map: (img) ? 'http://gfw2stories.s3.amazonaws.com/uploads/' + img : 'https://maps.googleapis.com/maps/api/staticmap?center=' + item.lat + ',' + item.lng + '&zoom=2&size=80x80',
        }
      }, this ));

      this.render();
    },

    render: function(){
      this.$spinner.removeClass('start');
      this.$container.removeClass('start');

      this.$listContainer.html(this.template({ stories : this.data }));
      mps.publish('SubItem/change');
    }

  });

  return StoriesKeepView;

});

<|endoftext|>


<commit_before>var util    = require("util");
var helpers = require("../Helpers");

exports.DataTypes = {
    id: 'SERIAL PRIMARY KEY',
    int: 'INTEGER',
    float: 'REAL',
    bool: 'SMALLINT',
    text: 'TEXT'
};

exports.escape = function (query, args) {
	return helpers.escapeQuery(exports, query, args);
}

exports.escapeId = function () {
  var parenthesis = false;

  var escaped = Array.prototype.slice.apply(arguments).map(function (el) {
    if (typeof el == "object") {
      return el.str.replace(/\?:(id|value)/g, function (m) {
        if (m == "?:id") {
          return exports.escapeId(el.escapes.shift());
        }
        // ?:value
        return exports.escapeVal(el.escapes.shift());
      });
    } else if(el.indexOf('.') > -1){
      //JSON field syntax
      parenthesis = true;
      var parts = el.split('.');
      return "\"" + parts[0].replace(/\"/g, "\"\"") + "\"->>'" + parts[1].replace(/'/, '') + "'";
    }
    return el.split(".").map(function (ele) { return "\"" + ele.replace(/\"/g, "\"\"") + "\""; }).join(".");
  }).join(".");

  if(parenthesis){
    escaped = "(" + escaped + ")";
  }
  return escaped;
};

exports.escapeVal = function (val, timeZone) {
	if (val === undefined || val === null) {
		return 'NULL';
	}

	if (Array.isArray(val)) {
		if (val.length === 1 && Array.isArray(val[0])) {
			return "{" + val[0].map(exports.escapeVal.bind(this)) + "}";
		}
		return "{" + val.map(exports.escapeVal.bind(this)).join(", ") + "}";
	}

	if (util.isDate(val)) {
		return "'" + helpers.dateToString(val, timeZone || "local", { dialect: 'postgresql' }) + "'";
	}

	if (Buffer.isBuffer(val)) {
		return "'\\x" + val.toString("hex") + "'";
	}

	switch (typeof val) {
		case "number":
			if (!isFinite(val)) {
				val = val.toString();
				break;
			}
			return val;
		case "boolean":
			return val ? "true" : "false";
		case "function":
			return val(exports);
	}
	// No need to escape backslashes with default PostgreSQL 9.1+ config.
	// Google 'postgresql standard_conforming_strings' for details.
	return "'" + val.replace(/\'/g, "''") + "'";
};

exports.defaultValuesStmt = "DEFAULT VALUES";
<commit_msg>Wrap array literal - waterfield/fdc_backend#546<commit_after>var util    = require("util");
var helpers = require("../Helpers");

exports.DataTypes = {
    id: 'SERIAL PRIMARY KEY',
    int: 'INTEGER',
    float: 'REAL',
    bool: 'SMALLINT',
    text: 'TEXT'
};

exports.escape = function (query, args) {
	return helpers.escapeQuery(exports, query, args);
}

exports.escapeId = function () {
  var parenthesis = false;

  var escaped = Array.prototype.slice.apply(arguments).map(function (el) {
    if (typeof el == "object") {
      return el.str.replace(/\?:(id|value)/g, function (m) {
        if (m == "?:id") {
          return exports.escapeId(el.escapes.shift());
        }
        // ?:value
        return exports.escapeVal(el.escapes.shift());
      });
    } else if(el.indexOf('.') > -1){
      //JSON field syntax
      parenthesis = true;
      var parts = el.split('.');
      return "\"" + parts[0].replace(/\"/g, "\"\"") + "\"->>'" + parts[1].replace(/'/, '') + "'";
    }
    return el.split(".").map(function (ele) { return "\"" + ele.replace(/\"/g, "\"\"") + "\""; }).join(".");
  }).join(".");

  if(parenthesis){
    escaped = "(" + escaped + ")";
  }
  return escaped;
};

exports.escapeVal = function (val, timeZone) {
	if (val === undefined || val === null) {
		return 'NULL';
	}

	if (Array.isArray(val)) {
		if (val.length === 1 && Array.isArray(val[0])) {
			return "'{" + val[0].map(exports.escapeVal.bind(this)) + "}'";
		}
		return "'{" + val.map(exports.escapeVal.bind(this)).join(", ") + "}'";
	}

	if (util.isDate(val)) {
		return "'" + helpers.dateToString(val, timeZone || "local", { dialect: 'postgresql' }) + "'";
	}

	if (Buffer.isBuffer(val)) {
		return "'\\x" + val.toString("hex") + "'";
	}

	switch (typeof val) {
		case "number":
			if (!isFinite(val)) {
				val = val.toString();
				break;
			}
			return val;
		case "boolean":
			return val ? "true" : "false";
		case "function":
			return val(exports);
	}
	// No need to escape backslashes with default PostgreSQL 9.1+ config.
	// Google 'postgresql standard_conforming_strings' for details.
	return "'" + val.replace(/\'/g, "''") + "'";
};

exports.defaultValuesStmt = "DEFAULT VALUES";
<|endoftext|>


<commit_before>(function ($) {

  function Ventana(el, options) {

    //Defaults:
    this.defaults = {};

    //Extending options:
    this.opts = $.extend({}, this.defaults, options);

    //Privates:
    this.$el = $(el);
  }

  // Separate functionality from object creation
  Ventana.prototype = {

    init: function () {
      var _this = this;
      $(_this.$el).find(".edit").after(
      $("Save").click(function (e) {
        value = $(this).parent().find("textarea").val()
        $.ajax({
          type: 'PUT',
          url: '/ventana/editable_contents/' + $(this).parent().data('key'),
          data: {
            value: value
          },
          context: this,
          success: function (resp) {
            $(this).parent().find(".editable").html(resp);
            $(this).parent().find(".editable").show();
            $(this).parent().find(".editor").hide();
            $(this).parent().find(".save").hide();
            $(this).parent().find(".edit").show();
          },
          error: function (a, b) {
            console.log(b)
          }
        })
        $(this).parent().find(".edit").hide();
        e.preventDefault();
      }).hide());

      $(_this.$el).find(".edit").click(function (e) {
        e.preventDefault();
        $(this).parent().find(".save").show();
        editor = $("<textarea class=editor/>")
        editor.width($(this).parent().find(".editable").width());
        $(this).parent().find(".editable").hide();
        editor.css("display","block")
        $(this).parent().find(".editable").after(editor);
        $.ajax({
          type: 'GET',
          url: '/ventana/editable_contents/' + $(this).parent().data('key'),
          context: this,
          success: function (resp) {
            $(this).parent().find('textarea').val(resp);
          }
        });
        $(this).parent().find(".edit").hide();
      });
    }
  };

  // The actual plugin
  $.fn.ventana = function (options) {
    if (this.length) {
      this.each(function () {
        var rev = new Ventana(this, options);
        rev.init();
        $(this).data('ventana', rev);
      });
    }
  };
  $(".ventana-block").ventana();
})(jQuery);
<commit_msg>Run ventana on load<commit_after>(function ($) {

  function Ventana(el, options) {

    //Defaults:
    this.defaults = {};

    //Extending options:
    this.opts = $.extend({}, this.defaults, options);

    //Privates:
    this.$el = $(el);
  }

  // Separate functionality from object creation
  Ventana.prototype = {

    init: function () {
      var _this = this;
      $(_this.$el).find(".edit").after(
      $("Save").click(function (e) {
        value = $(this).parent().find("textarea").val()
        $.ajax({
          type: 'PUT',
          url: '/ventana/editable_contents/' + $(this).parent().data('key'),
          data: {
            value: value
          },
          context: this,
          success: function (resp) {
            $(this).parent().find(".editable").html(resp);
            $(this).parent().find(".editable").show();
            $(this).parent().find(".editor").hide();
            $(this).parent().find(".save").hide();
            $(this).parent().find(".edit").show();
          },
          error: function (a, b) {
            console.log(b)
          }
        })
        $(this).parent().find(".edit").hide();
        e.preventDefault();
      }).hide());

      $(_this.$el).find(".edit").click(function (e) {
        e.preventDefault();
        $(this).parent().find(".save").show();
        editor = $("<textarea class=editor/>")
        editor.width($(this).parent().find(".editable").width());
        $(this).parent().find(".editable").hide();
        editor.css("display","block")
        $(this).parent().find(".editable").after(editor);
        $.ajax({
          type: 'GET',
          url: '/ventana/editable_contents/' + $(this).parent().data('key'),
          context: this,
          success: function (resp) {
            $(this).parent().find('textarea').val(resp);
          }
        });
        $(this).parent().find(".edit").hide();
      });
    }
  };

  // The actual plugin
  $.fn.ventana = function (options) {
    if (this.length) {
      this.each(function () {
        var rev = new Ventana(this, options);
        rev.init();
        $(this).data('ventana', rev);
      });
    }
  };
})(jQuery);
$(function(){
  $(".ventana-block").ventana();
});
<|endoftext|>


<commit_before>CodeKindaSmart.Views.AnnotationsShow = Backbone.View.extend({

  template: JST['annotations/show'],
  tagName: "div",

  initialize: function (options) {
    this.annotationOffset = options.annotationOffset;
    // this.annotations = this.activeAnnotations;
    this.annotations = [options.annotations];
    this.annotationId = options.annotationId;
  },

  events: {
  	"click .button .upvote" : "upVote",
  	"click .button .downvote" : "downVote",
  	"click .edit-annotation" : "editAnnotation",
		"click .save-annotation" : "saveAnnotation",
    "click .delete-annotation" : "deleteAnnotation"
  },

  render: function () {
    // I should move the placement variables to the render function
    // and then call the jquery here, so that I can rerender this when needed
    var content = this.template({
      annotationId: this.annotationId,
      annotations: this.annotations
    });
    this.$el.html(content);
    // $(".activeAnnotations").css("top", "+=" + this.annotationOffset);
    return this;
  },

  upVote: function (event) {
    event.preventDefault()
    currentTarget = event.currentTarget
    parentElement = currentTarget.parentElement
    if(parentElement.classList.contains("my-vote")){
      $(parentElement).removeClass('my-vote');
    } else {
      $(parentElement).addClass('my-vote');
    }
    var that = this;
    var attrs = this.$("form.upvote").serializeJSON();
    var xhReq = new XMLHttpRequest();
    xhReq.open("GET", "/api/annotations/" + this.annotations[0].id + "/upvote", false);
    xhReq.send();

  },

  downVote: function (event) {
    event.preventDefault()
    currentTarget = event.currentTarget
    parentElement = currentTarget.parentElement
    if(parentElement.classList.contains("my-vote")){
      $(parentElement).removeClass('my-vote');
    } else {
      $(parentElement).addClass('my-vote');
    }
    var that = this;
    var attrs = this.$("form.downvote").serializeJSON();
    var xhReq = new XMLHttpRequest();
    xhReq.open("GET", "/api/annotations/" + this.annotations[0].id + "/downvote", false);
    xhReq.send();

  },

  editAnnotation: function (event) {
    event.preventDefault()
    if(CodeKindaSmart.currentUser){
      var view = new CodeKindaSmart.Views.AnnotationsForm({
        annotation: this.annotations[0],
        annotationOffset: this.annotationOffset
      });
      $('.activeAnnotations').addClass('isHidden')
      $('.activeAnnotations').removeClass('activeAnnotations')
      $(".annotation-column").append(view.render().$el);
      $("form.new-annotation").css("top", "+=" + this.annotationOffset);
    }
  },

  deleteAnnotation: function (event) {
    event.preventDefault();
    var attrs = this.$(".form-delete-annotation").serializeJSON();
    var id = attrs.annotation.id
    console.log(id)

    CodeKindaSmart.doc.annotations.get(id).destroy({
      success: function () {
        CodeKindaSmart.doc.fetch()
      }
    })
  }

});<commit_msg>better votes<commit_after>CodeKindaSmart.Views.AnnotationsShow = Backbone.View.extend({

  template: JST['annotations/show'],
  tagName: "div",

  initialize: function (options) {
    this.annotationOffset = options.annotationOffset;
    // this.annotations = this.activeAnnotations;
    this.annotations = [options.annotations];
    this.annotationId = options.annotationId;
  },

  events: {
  	"click .button .upvote" : "upVote",
  	"click .button .downvote" : "downVote",
  	"click .edit-annotation" : "editAnnotation",
		"click .save-annotation" : "saveAnnotation",
    "click .delete-annotation" : "deleteAnnotation"
  },

  render: function () {
    // I should move the placement variables to the render function
    // and then call the jquery here, so that I can rerender this when needed
    var content = this.template({
      annotationId: this.annotationId,
      annotations: this.annotations
    });
    this.$el.html(content);
    // $(".activeAnnotations").css("top", "+=" + this.annotationOffset);
    return this;
  },

  upVote: function (event) {
    event.preventDefault()
    currentTarget = event.currentTarget
    parentElement = currentTarget.parentElement
    if(CodeKindaSmart.currentUser.username){
      if(parentElement.classList.contains("my-vote")){
        $(parentElement).removeClass('my-vote');
      } else {
        $(".downvote p.button").removeClass('my-vote')
        $(parentElement).addClass('my-vote');
      }
    }
    var that = this;
    var attrs = this.$("form.upvote").serializeJSON();
    var xhReq = new XMLHttpRequest();
    xhReq.open("GET", "/api/annotations/" + this.annotations[0].id + "/upvote", false);
    xhReq.send();

  },

  downVote: function (event) {
    event.preventDefault()
    currentTarget = event.currentTarget
    parentElement = currentTarget.parentElement
    if(CodeKindaSmart.currentUser.username){
      if(parentElement.classList.contains("my-vote")){
        $(parentElement).removeClass('my-vote');
      } else {
        $(".upvote p.button").removeClass('my-vote')
        $(parentElement).addClass('my-vote');
      }
    }
    var that = this;
    var attrs = this.$("form.downvote").serializeJSON();
    var xhReq = new XMLHttpRequest();
    xhReq.open("GET", "/api/annotations/" + this.annotations[0].id + "/downvote", false);
    xhReq.send();

  },

  editAnnotation: function (event) {
    event.preventDefault()
    if(CodeKindaSmart.currentUser){
      var view = new CodeKindaSmart.Views.AnnotationsForm({
        annotation: this.annotations[0],
        annotationOffset: this.annotationOffset
      });
      $('.activeAnnotations').addClass('isHidden')
      $('.activeAnnotations').removeClass('activeAnnotations')
      $(".annotation-column").append(view.render().$el);
      $("form.new-annotation").css("top", "+=" + this.annotationOffset);
    }
  },

  deleteAnnotation: function (event) {
    event.preventDefault();
    var attrs = this.$(".form-delete-annotation").serializeJSON();
    var id = attrs.annotation.id
    console.log(id)

    CodeKindaSmart.doc.annotations.get(id).destroy({
      success: function () {
        CodeKindaSmart.doc.fetch()
      }
    })
  }

});<|endoftext|>


<commit_before>"use strict";

const Channel = require("./Channel");
const Collection = require("../util/Collection");
const Member = require("./Member");
const Permission = require("./Permission");
const {Permissions} = require("../Constants");
const PermissionOverwrite = require("./PermissionOverwrite");

/**
* Represents a guild channel. You also probably want to look at CategoryChannel, NewsChannel, StoreChannel, TextChannel, and VoiceChannel. See Channel for extra properties.
* @extends Channel
* @prop {Guild} guild The guild that owns the channel
* @prop {String} id The ID of the channel
* @prop {String} name The name of the channel
* @prop {Boolean} nsfw Whether the channel is an NSFW channel or not
* @prop {String?} parentID The ID of the category this channel belongs to
* @prop {Collection<PermissionOverwrite>} permissionOverwrites Collection of PermissionOverwrites in this channel
* @prop {Number} position The position of the channel
*/
class GuildChannel extends Channel {
    constructor(data, client) {
        super(data, client);
        this.guild = client.guilds.get(data.guild_id) || {
            id: data.guild_id
        };

        this.update(data);
    }

    update(data) {
        if(data.type !== undefined) {
            this.type = data.type;
        }
        if(data.name !== undefined) {
            this.name = data.name;
        }
        if(data.position !== undefined) {
            this.position = data.position;
        }
        if(data.parent_id !== undefined) {
            this.parentID = data.parent_id;
        }
        this.nsfw = (this.name.length === 4 ? this.name === "nsfw" : this.name.startsWith("nsfw-")) || data.nsfw;
        if(data.permission_overwrites) {
            this.permissionOverwrites = new Collection(PermissionOverwrite);
            data.permission_overwrites.forEach((overwrite) => {
                this.permissionOverwrites.add(overwrite);
            });
        }
    }

    /**
    * Delete the channel
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise}
    */
    delete(reason) {
        return this.client.deleteChannel.call(this.client, this.id, reason);
    }

    /**
    * Delete a channel permission overwrite
    * @arg {String} overwriteID The ID of the overwritten user or role
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise}
    */
    deletePermission(overwriteID, reason) {
        return this.client.deleteChannelPermission.call(this.client, this.id, overwriteID, reason);
    }

    /**
    * Edit the channel's properties
    * @arg {Object} options The properties to edit
    * @arg {String} [options.name] The name of the channel
    * @arg {String} [options.topic] The topic of the channel (guild text channels only)
    * @arg {Number} [options.bitrate] The bitrate of the channel (guild voice channels only)
    * @arg {Number} [options.userLimit] The channel user limit (guild voice channels only)
    * @arg {Number} [options.rateLimitPerUser] The time in seconds a user has to wait before sending another message (does not affect bots or users with manageMessages/manageChannel permissions) (guild text channels only)
    * @arg {Boolean} [options.nsfw] The nsfw status of the channel
    * @arg {Number?} [options.parentID] The ID of the parent channel category for this channel (guild text/voice channels only)
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise<CategoryChannel | TextChannel | VoiceChannel | NewsChannel>}
    */
    edit(options, reason) {
        return this.client.editChannel.call(this.client, this.id, options, reason);
    }

    /**
    * Create a channel permission overwrite
    * @arg {String} overwriteID The ID of the overwritten user or role
    * @arg {Number} allow The permissions number for allowed permissions
    * @arg {Number} deny The permissions number for denied permissions
    * @arg {String} type The object type of the overwrite, either "member" or "role"
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise<PermissionOverwrite>}
    */
    editPermission(overwriteID, allow, deny, type, reason) {
        return this.client.editChannelPermission.call(this.client, this.id, overwriteID, allow, deny, type, reason);
    }

    /**
    * Edit the channel's position. Note that channel position numbers are lowest on top and highest at the bottom.
    * @arg {Number} position The new position of the channel
    * @returns {Promise}
    */
    editPosition(position) {
        return this.client.editChannelPosition.call(this.client, this.id, position);
    }

    /**
    * Get the channel-specific permissions of a member
    * @arg {String | Member} memberID The ID of the member or a Member instance
    * @returns {Permission}
    */
    permissionsOf(memberID) {
        const member = memberID instanceof Member ? memberID : this.guild.members.get(memberID);
        let permission = this.guild.permissionsOf(member).allow;
        if(permission & Permissions.administrator) {
            return new Permission(Permissions.all);
        }
        let overwrite = this.permissionOverwrites.get(this.guild.id);
        if(overwrite) {
            permission = (permission & ~overwrite.deny) | overwrite.allow;
        }
        let deny = 0;
        let allow = 0;
        for(const roleID of member.roles) {
            if((overwrite = this.permissionOverwrites.get(roleID))) {
                deny |= overwrite.deny;
                allow |= overwrite.allow;
            }
        }
        permission = (permission & ~deny) | allow;
        overwrite = this.permissionOverwrites.get(member.id);
        if(overwrite) {
            permission = (permission & ~overwrite.deny) | overwrite.allow;
        }
        return new Permission(permission);
    }

    toJSON(props = []) {
        return super.toJSON([
            "name",
            "nsfw",
            "parentID",
            "permissionOverwrites",
            "position",
            ...props
        ]);
    }
}

module.exports = GuildChannel;
<commit_msg>Remove legacy name-based GuildChannel#nsfw check (#1110)<commit_after>"use strict";

const Channel = require("./Channel");
const Collection = require("../util/Collection");
const Member = require("./Member");
const Permission = require("./Permission");
const {Permissions} = require("../Constants");
const PermissionOverwrite = require("./PermissionOverwrite");

/**
* Represents a guild channel. You also probably want to look at CategoryChannel, NewsChannel, StoreChannel, TextChannel, and VoiceChannel. See Channel for extra properties.
* @extends Channel
* @prop {Guild} guild The guild that owns the channel
* @prop {String} id The ID of the channel
* @prop {String} name The name of the channel
* @prop {Boolean} nsfw Whether the channel is an NSFW channel or not
* @prop {String?} parentID The ID of the category this channel belongs to
* @prop {Collection<PermissionOverwrite>} permissionOverwrites Collection of PermissionOverwrites in this channel
* @prop {Number} position The position of the channel
*/
class GuildChannel extends Channel {
    constructor(data, client) {
        super(data, client);
        this.guild = client.guilds.get(data.guild_id) || {
            id: data.guild_id
        };

        this.update(data);
    }

    update(data) {
        if(data.type !== undefined) {
            this.type = data.type;
        }
        if(data.name !== undefined) {
            this.name = data.name;
        }
        if(data.position !== undefined) {
            this.position = data.position;
        }
        if(data.parent_id !== undefined) {
            this.parentID = data.parent_id;
        }
        this.nsfw = data.nsfw;
        if(data.permission_overwrites) {
            this.permissionOverwrites = new Collection(PermissionOverwrite);
            data.permission_overwrites.forEach((overwrite) => {
                this.permissionOverwrites.add(overwrite);
            });
        }
    }

    /**
    * Delete the channel
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise}
    */
    delete(reason) {
        return this.client.deleteChannel.call(this.client, this.id, reason);
    }

    /**
    * Delete a channel permission overwrite
    * @arg {String} overwriteID The ID of the overwritten user or role
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise}
    */
    deletePermission(overwriteID, reason) {
        return this.client.deleteChannelPermission.call(this.client, this.id, overwriteID, reason);
    }

    /**
    * Edit the channel's properties
    * @arg {Object} options The properties to edit
    * @arg {String} [options.name] The name of the channel
    * @arg {String} [options.topic] The topic of the channel (guild text channels only)
    * @arg {Number} [options.bitrate] The bitrate of the channel (guild voice channels only)
    * @arg {Number} [options.userLimit] The channel user limit (guild voice channels only)
    * @arg {Number} [options.rateLimitPerUser] The time in seconds a user has to wait before sending another message (does not affect bots or users with manageMessages/manageChannel permissions) (guild text channels only)
    * @arg {Boolean} [options.nsfw] The nsfw status of the channel
    * @arg {Number?} [options.parentID] The ID of the parent channel category for this channel (guild text/voice channels only)
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise<CategoryChannel | TextChannel | VoiceChannel | NewsChannel>}
    */
    edit(options, reason) {
        return this.client.editChannel.call(this.client, this.id, options, reason);
    }

    /**
    * Create a channel permission overwrite
    * @arg {String} overwriteID The ID of the overwritten user or role
    * @arg {Number} allow The permissions number for allowed permissions
    * @arg {Number} deny The permissions number for denied permissions
    * @arg {String} type The object type of the overwrite, either "member" or "role"
    * @arg {String} [reason] The reason to be displayed in audit logs
    * @returns {Promise<PermissionOverwrite>}
    */
    editPermission(overwriteID, allow, deny, type, reason) {
        return this.client.editChannelPermission.call(this.client, this.id, overwriteID, allow, deny, type, reason);
    }

    /**
    * Edit the channel's position. Note that channel position numbers are lowest on top and highest at the bottom.
    * @arg {Number} position The new position of the channel
    * @returns {Promise}
    */
    editPosition(position) {
        return this.client.editChannelPosition.call(this.client, this.id, position);
    }

    /**
    * Get the channel-specific permissions of a member
    * @arg {String | Member} memberID The ID of the member or a Member instance
    * @returns {Permission}
    */
    permissionsOf(memberID) {
        const member = memberID instanceof Member ? memberID : this.guild.members.get(memberID);
        let permission = this.guild.permissionsOf(member).allow;
        if(permission & Permissions.administrator) {
            return new Permission(Permissions.all);
        }
        let overwrite = this.permissionOverwrites.get(this.guild.id);
        if(overwrite) {
            permission = (permission & ~overwrite.deny) | overwrite.allow;
        }
        let deny = 0;
        let allow = 0;
        for(const roleID of member.roles) {
            if((overwrite = this.permissionOverwrites.get(roleID))) {
                deny |= overwrite.deny;
                allow |= overwrite.allow;
            }
        }
        permission = (permission & ~deny) | allow;
        overwrite = this.permissionOverwrites.get(member.id);
        if(overwrite) {
            permission = (permission & ~overwrite.deny) | overwrite.allow;
        }
        return new Permission(permission);
    }

    toJSON(props = []) {
        return super.toJSON([
            "name",
            "nsfw",
            "parentID",
            "permissionOverwrites",
            "position",
            ...props
        ]);
    }
}

module.exports = GuildChannel;
<|endoftext|>


<commit_before>var util  = require("util"),
    _     = require("underscore"),
    fs    = require("fs");

var Agent = require("./Agent"),
    Food  = require("./Food");

var Server = function (agents, map) {
    this.agentsClasses  = agents;
    this.agents         = [];
    this.tickId         = 0;
    this.map            = map;
    this.lastAgentId    = 0;
    this.tickInterval   = 500;
    this.objects        = [];
    this.displayLogs    = true;
};

Server.prototype.log = function (msg) {
    if (this.displayLogs) {
        util.log(msg);
    }
};

Server.prototype.stop = function () {
    this.log("Server stopped");
    process.exit();
};

Server.prototype.getRandomLocation = function () {
    return {
        "x" : Math.floor(Math.random() * this.map.width),
        "y" : Math.floor(Math.random() * this.map.height)
    };
};

Server.prototype.instantiateAgent = function (agentDefinition) {
    var agent, agentClient, agentIntroduction, coords;

    if (!("agentClass" in agentDefinition)) {
        throw new Error("exports.agentClass not found");
    }

    agentClient = new agentDefinition.agentClass();

    if (typeof agentClient.introduce !== 'function') {
        throw new Error("Agent has no method introduce");
    }
    agentIntroduction = agentClient.introduce();

    if (!(agentIntroduction instanceof Object)) {
        throw new Error("agent.introduce() returned not an object");
    }

    if (!("name" in agentIntroduction)) {
        throw new Error("agent.introduce() doesn't contain name");
    }

    if (!("author" in agentIntroduction)) {
        throw new Error("agent.introduce() doesn't contain author");
    }

    if (!("email" in agentIntroduction)) {
        throw new Error("agent.introduce() doesn't contain email");
    }

    if (typeof agentClient.onNewTick !== 'function') {
        throw new Error("Agent has no method onNewTick");
    }

    if (typeof agentClient.decision !== 'function') {
        throw new Error("Agent has no method decision");
    }

    if (typeof agentClient.onNotification !== 'function') {
        throw new Error("Agent has no method onNotification");
    }

    agent           = Agent.create();
    agent.id        = ++this.lastAgentId;
    agent.client    = agentClient;
    agent.name      = agentIntroduction.name;
    agent.author    = agentIntroduction.author;

    do {
        coords = this.getRandomLocation();
    } while (this.getAgentByXY(coords.x, coords.y) || !agent.canMoveToTerrainType(this.map.getTerrainTypeByXY(coords.x, coords.y)));

    agent.setLocation(coords.x, coords.y);

    // Add food for the newborn agent
    var food = Food.create(10000);
    food.setLocation(agent.x, agent.y);
    this.objects.push(food);
    this.log("Food with richness: " + food.richness + " was generated at x:" + food.x + " y:" + food.y);

    return agent;
};

Server.prototype.initAgents = function () {
    this.agents = [];

    var agent;

    for (var i in this.agentsClasses) {
        agent = this.agentsClasses[i];
        try {
            agent = this.instantiateAgent(agent);
        } catch (e) {
            this.log("Agent(" + i + ") was not created because of error: " + e.message);
            continue;
        }

        this.log(agent.name + "(" + agent.id + ")" + " was born at x:" + agent.x + " y:" + agent.y);
        this.agents.push(agent);
    }
};

Server.prototype.generateFood = function () {
    var food, coords;

    do {
        coords = this.getRandomLocation();
    } while (!_.contains([1, 9, 10, 11, 12, 15, 16, 17, 18], this.map.getTerrainTypeByXY(coords.x, coords.y)));

    food = Food.create(Math.floor(Math.random() * 300) + 100);
    food.setLocation(coords.x, coords.y);
    this.log("Food with richness: " + food.richness + " was generated at x:" + food.x + " y:" + food.y);

    this.objects.push(food);
};

Server.prototype.initFood = function () {
    this.generateFood();
};

Server.prototype.getAgentByXY = function (x, y) {
    var agent;

    for (var i in this.agents) {
        agent = this.agents[i];

        if (agent.x === x && agent.y === y) {
            return agent;
        }
    }

    return null;
};

Server.prototype.getAgentForEnvironmentByXY = function (agent, x, y, shift_x, shift_y) {
    var tmpAgent, agentObj;

    tmpAgent = this.getAgentByXY(x, y);

    // Exclude current agents from agents list
    if (tmpAgent && tmpAgent !== agent) {
        agentObj = {
            "class" : "agent",
            "x"     : shift_x,
            "y"     : shift_y
        };

        return agentObj;
    }

    return null;
}

Server.prototype.getObjectsByXY = function (x, y) {
    return _.filter(this.objects, function (obj) {
        return obj.x === x && obj.y === y;
    });
};

Server.prototype.getObjectsForEnvironmentByXY = function (agent, x, y, shift_x, shift_y) {
    var objects = this.getObjectsByXY(x, y);

    if (objects.length) {
        objects = _.map(objects, function (obj) {
            return {
                "class" : obj.class,
                "x"     : shift_x,
                "y"     : shift_y
            };
        });
    }

    return objects;
}

Server.prototype.getEnvironmentForAgent = function(agent)
{
    var radius = 2, env, coords, terrain, row, agentObj, objects, shift_x, shift_y;
    env = {
        "map"       : [],
        "objects"   : []
    };

    for (shift_y = -radius ; shift_y < radius + 1 ; shift_y++) {
        row = [];

        for (shift_x = -radius ; shift_x < radius + 1 ; shift_x++) {
            coords = this.map.getXYByRel(agent.x, agent.y, shift_x, shift_y);
            terrain = this.map.getTerrainTypeByXY(coords.x, coords.y);

            agentObj = this.getAgentForEnvironmentByXY(agent, coords.x, coords.y, shift_x, shift_y);
            if (agentObj) {
                env.objects.push(agentObj);
            }

            objects = this.getObjectsForEnvironmentByXY(agent, coords.x, coords.y, shift_x, shift_y);
            _.each(objects, function (obj) {
                env.objects.push(obj);
            });

            row.push(terrain);
        }

        env.map.push(row);
    }

    return env;
};

Server.prototype.getAgentStatus = function (agent) {
    var status = {
        "health"  : agent.health,
        "satiety" : agent.satiety,
        "environment" : this.getEnvironmentForAgent(agent)
    };

//    if (agent.id == 1) {
//        console.log(" ");
//        console.log("ID:" + agent.id + " HEALTH:" + agent.health + " SATIETY:" + agent.satiety);
//        console.log(status.environment.map);
//        console.log(status.environment.objects);
//    }
//
    return status;
};

Server.prototype.updateAgentStatus = function (agent) {
    if (agent.satiety == 0) {
        agent.health = agent.health - 1;
    } else {
        agent.satiety--;
    }

    if (!agent.isAlive()) {
        this.log(agent.name + "(" + agent.id + ") [" + agent.health + "/" + agent.satiety +  "] has died at x:" + agent.x + " y:" + agent.y + " on tick " + this.tickId);

        // Create food instead of died agent
        var food = Food.create(2000);
        food.setLocation(agent.x, agent.y);
        this.objects.push(food);
        this.log("Food with richness: " + food.richness + " was created instead of died agent at x:" + food.x + " y:" + food.y);

        // Remove agent from server
        this.agents.splice(this.agents.indexOf(agent), 1);
    }
};

Server.prototype.sanitizeDecision = function (agent, decision) {
    try {
        if (decision !== Object(decision)) {
            throw new Error("decision returned not an object");
        }

        decision.action = parseInt(decision.action);

        if (decision.action === 0) { // Idle

            return {
                "isProcessed" : false,
                "action" : 0
            };

        } else if (decision.action === 1) { // Move
            decision.dir = parseInt(decision.dir);
            if (decision.dir === undefined || !_.contains(this.map.getPossibleDirections(), decision.dir)) {
                throw new Error("decision returned wrong direction code: " + decision.dir);
            }

            return {
                "isProcessed" : false,
                "action" : 1,
                "dir"    : decision.dir
            };

        } else if (decision.action === 2) { // Reserved

            throw new Error("action code: " + decision.action + " is reserved");

        } else if (decision.action === 4) { // Eat food

            decision.dir = parseInt(decision.dir);
            if (decision.dir === undefined || !_.contains(this.map.getPossibleDirections(), decision.dir)) {
                throw new Error("decision returned wrong direction code: " + decision.dir);
            }

            return {
                "isProcessed"   : false,
                "action"        : 4,
                "dir"           : decision.dir
            };

        } else {
            throw new Error("decision returned wrong action code: " + decision.action);
        }

    } catch (e) {
        agent.client.onNotification(1); // Notify agent that its decision has wrong format or params and will skip current tick
        throw e;
    }
};

Server.prototype.processDecisionMove = function (decision) {
    var movementMap = this.map.getDirectionsMap(),
        agent = decision.agent,
        relCoords, coords;

    relCoords = movementMap[decision.dir];
    coords = this.map.getXYByRel(agent.x, agent.y, relCoords.x, relCoords.y);
    if (agent.canMoveToTerrainType(this.map.getTerrainTypeByXY(coords.x, coords.y))) {
        agent.x = coords.x;
        agent.y = coords.y;

        this.log(agent.name + "(" + agent.id + ") [" + agent.health + "/" + agent.satiety + "] moved to x:" + agent.x + " y:" + agent.y);
    } else {
        agent.client.onNotification(21);
    }

    decision.isProcessed = true;
};

Server.prototype.processDecisionEatFood = function (decision) {
    var movementMap = this.map.getDirectionsMap(),
        agent = decision.agent,
        relCoords, coords, food;

    relCoords = movementMap[decision.dir];
    coords = this.map.getXYByRel(agent.x, agent.y, relCoords.x, relCoords.y);
    food = _.first(_.filter(this.getObjectsByXY(coords.x, coords.y), function (obj) {
        return obj.class === "food";
    }));

    if (!food) {
        agent.client.onNotification(31);
    } else if (agent.satiety === 10000) {
        agent.client.onNotification(32);
    } else {
        this.log(agent.name + "(" + agent.id + ") [" + agent.health + "/" + agent.satiety + "] ate food from x:" + coords.x + " y:" + coords.y
            + " satiety: (+" + food.richness + ")");

        agent.satiety = (agent.satiety + food.richness > 10000) ? 10000 : agent.satiety + food.richness;

        // Remove food
        this.objects.splice(this.objects.indexOf(food), 1);
    }

    decision.isProcessed = true;
};

Server.prototype.processDecisions = function (decisions) {
    var decision;

    for (var i in decisions) {
        decision = decisions[i];

        if (decision.action === 1) {
            this.processDecisionMove(decision);
        } else if (decision.action === 4) {
            this.processDecisionEatFood(decision);
        }
    }
};

Server.prototype.tick = function () {
    var decisions = [], decision;

    this.tickId++;
    if (!(this.tickId % 100)) {
        this.generateFood();
    }

    _.each(this.agents, function (agent) {
        // Recalculate agent's characteristics (health, etc.), remove died
        this.updateAgentStatus(agent);
    }, this);

    _.each(this.agents, function (agent) {
        try {

            // Skip if agent is died after the recalculation
            if (!agent.isAlive()) {
                return;
            }

            // Notify the agent that new tick has begun
            agent.client.onNewTick(this.getAgentStatus(agent));

            // Get and validate agent's decision
            decision = agent.client.decision();
            if (!decision) {
                // Skip if idle action
                return;
            }

            decision = this.sanitizeDecision(agent, decision);
            if (!decision.action) {
                // Skip if idle action
                return;
            }

            decision.agent = agent;

            // Collect all decisions
            decisions.push(decision);

        } catch (e) {
            this.log(agent.name + "(" + agent.id + ")" + " skipped on tick " + this.tickId + " because of error: " + e.message);
        }
    }, this);

    this.processDecisions(decisions);

    this.saveServerState();
//    this.printWorld();

    if (!this.agents.length) {
        this.log("All agents died");
        this.stop();
    }

    var self = this;
    setTimeout(function () {
        self.tick.call(self);
    }, this.tickInterval);
};

Server.prototype.saveServerState = function () {
    var state = {
        "tickId" : this.tickId,
        "map"    : {
            "width" : this.map.width,
            "height" : this.map.health,
            "map" : this.map.map
        },
        "agents"  : [],
        "objects" : [],
        "log"     : []
    };

    state.agents = _.map(this.agents, function (agent) {
        return {
            "id"        : agent.id,
            "name"      : agent.name,
            "author"    : agent.author,
            "x"         : agent.x,
            "y"         : agent.y,
            "health"    : agent.health,
            "satiety"   : agent.satiety
        };
    });

    state.objects = _.map(this.objects, function (obj) {
        return {
            "class" : obj.class,
            "x"     : obj.x,
            "y"     : obj.y
        };
    });

    fs.writeFileSync("./var/state.json", JSON.stringify(state));
};

Server.prototype.printWorld = function () {
    for (var y = 0 ; y < this.map.height ; y++) {
        for (var x = 0 ; x < this.map.width ; x++) {
            if (this.getAgentByXY(x, y)) {
                process.stdout.write("@");
            } else if (this.getObjectsByXY(x, y).length) {
                process.stdout.write("#");
            } else {
                process.stdout.write(""+this.map.getTerrainTypeByXY(x, y));
            }
        }
        process.stdout.write("\n");
    }
};

Server.prototype.run = function () {
    this.log("Server started");

    this.initAgents();
    this.initFood();

    var self = this;
    setTimeout(function () {
        self.tick.call(self);
    }, this.tickInterval);
};

exports.Server = Server;
<commit_msg>Fixed notification codes<commit_after>var util  = require("util"),
    _     = require("underscore"),
    fs    = require("fs");

var Agent = require("./Agent"),
    Food  = require("./Food");

var Server = function (agents, map) {
    this.agentsClasses  = agents;
    this.agents         = [];
    this.tickId         = 0;
    this.map            = map;
    this.lastAgentId    = 0;
    this.tickInterval   = 500;
    this.objects        = [];
    this.displayLogs    = true;
};

Server.prototype.log = function (msg) {
    if (this.displayLogs) {
        util.log(msg);
    }
};

Server.prototype.stop = function () {
    this.log("Server stopped");
    process.exit();
};

Server.prototype.getRandomLocation = function () {
    return {
        "x" : Math.floor(Math.random() * this.map.width),
        "y" : Math.floor(Math.random() * this.map.height)
    };
};

Server.prototype.instantiateAgent = function (agentDefinition) {
    var agent, agentClient, agentIntroduction, coords;

    if (!("agentClass" in agentDefinition)) {
        throw new Error("exports.agentClass not found");
    }

    agentClient = new agentDefinition.agentClass();

    if (typeof agentClient.introduce !== 'function') {
        throw new Error("Agent has no method introduce");
    }
    agentIntroduction = agentClient.introduce();

    if (!(agentIntroduction instanceof Object)) {
        throw new Error("agent.introduce() returned not an object");
    }

    if (!("name" in agentIntroduction)) {
        throw new Error("agent.introduce() doesn't contain name");
    }

    if (!("author" in agentIntroduction)) {
        throw new Error("agent.introduce() doesn't contain author");
    }

    if (!("email" in agentIntroduction)) {
        throw new Error("agent.introduce() doesn't contain email");
    }

    if (typeof agentClient.onNewTick !== 'function') {
        throw new Error("Agent has no method onNewTick");
    }

    if (typeof agentClient.decision !== 'function') {
        throw new Error("Agent has no method decision");
    }

    if (typeof agentClient.onNotification !== 'function') {
        throw new Error("Agent has no method onNotification");
    }

    agent           = Agent.create();
    agent.id        = ++this.lastAgentId;
    agent.client    = agentClient;
    agent.name      = agentIntroduction.name;
    agent.author    = agentIntroduction.author;

    do {
        coords = this.getRandomLocation();
    } while (this.getAgentByXY(coords.x, coords.y) || !agent.canMoveToTerrainType(this.map.getTerrainTypeByXY(coords.x, coords.y)));

    agent.setLocation(coords.x, coords.y);

    // Add food for the newborn agent
    var food = Food.create(10000);
    food.setLocation(agent.x, agent.y);
    this.objects.push(food);
    this.log("Food with richness: " + food.richness + " was generated at x:" + food.x + " y:" + food.y);

    return agent;
};

Server.prototype.initAgents = function () {
    this.agents = [];

    var agent;

    for (var i in this.agentsClasses) {
        agent = this.agentsClasses[i];
        try {
            agent = this.instantiateAgent(agent);
        } catch (e) {
            this.log("Agent(" + i + ") was not created because of error: " + e.message);
            continue;
        }

        this.log(agent.name + "(" + agent.id + ")" + " was born at x:" + agent.x + " y:" + agent.y);
        this.agents.push(agent);
    }
};

Server.prototype.generateFood = function () {
    var food, coords;

    do {
        coords = this.getRandomLocation();
    } while (!_.contains([1, 9, 10, 11, 12, 15, 16, 17, 18], this.map.getTerrainTypeByXY(coords.x, coords.y)));

    food = Food.create(Math.floor(Math.random() * 300) + 100);
    food.setLocation(coords.x, coords.y);
    this.log("Food with richness: " + food.richness + " was generated at x:" + food.x + " y:" + food.y);

    this.objects.push(food);
};

Server.prototype.initFood = function () {
    this.generateFood();
};

Server.prototype.getAgentByXY = function (x, y) {
    var agent;

    for (var i in this.agents) {
        agent = this.agents[i];

        if (agent.x === x && agent.y === y) {
            return agent;
        }
    }

    return null;
};

Server.prototype.getAgentForEnvironmentByXY = function (agent, x, y, shift_x, shift_y) {
    var tmpAgent, agentObj;

    tmpAgent = this.getAgentByXY(x, y);

    // Exclude current agents from agents list
    if (tmpAgent && tmpAgent !== agent) {
        agentObj = {
            "class" : "agent",
            "x"     : shift_x,
            "y"     : shift_y
        };

        return agentObj;
    }

    return null;
}

Server.prototype.getObjectsByXY = function (x, y) {
    return _.filter(this.objects, function (obj) {
        return obj.x === x && obj.y === y;
    });
};

Server.prototype.getObjectsForEnvironmentByXY = function (agent, x, y, shift_x, shift_y) {
    var objects = this.getObjectsByXY(x, y);

    if (objects.length) {
        objects = _.map(objects, function (obj) {
            return {
                "class" : obj.class,
                "x"     : shift_x,
                "y"     : shift_y
            };
        });
    }

    return objects;
}

Server.prototype.getEnvironmentForAgent = function(agent)
{
    var radius = 2, env, coords, terrain, row, agentObj, objects, shift_x, shift_y;
    env = {
        "map"       : [],
        "objects"   : []
    };

    for (shift_y = -radius ; shift_y < radius + 1 ; shift_y++) {
        row = [];

        for (shift_x = -radius ; shift_x < radius + 1 ; shift_x++) {
            coords = this.map.getXYByRel(agent.x, agent.y, shift_x, shift_y);
            terrain = this.map.getTerrainTypeByXY(coords.x, coords.y);

            agentObj = this.getAgentForEnvironmentByXY(agent, coords.x, coords.y, shift_x, shift_y);
            if (agentObj) {
                env.objects.push(agentObj);
            }

            objects = this.getObjectsForEnvironmentByXY(agent, coords.x, coords.y, shift_x, shift_y);
            _.each(objects, function (obj) {
                env.objects.push(obj);
            });

            row.push(terrain);
        }

        env.map.push(row);
    }

    return env;
};

Server.prototype.getAgentStatus = function (agent) {
    var status = {
        "health"  : agent.health,
        "satiety" : agent.satiety,
        "environment" : this.getEnvironmentForAgent(agent)
    };

//    if (agent.id == 1) {
//        console.log(" ");
//        console.log("ID:" + agent.id + " HEALTH:" + agent.health + " SATIETY:" + agent.satiety);
//        console.log(status.environment.map);
//        console.log(status.environment.objects);
//    }
//
    return status;
};

Server.prototype.updateAgentStatus = function (agent) {
    if (agent.satiety == 0) {
        agent.health = agent.health - 1;
    } else {
        agent.satiety--;
    }

    if (!agent.isAlive()) {
        this.log(agent.name + "(" + agent.id + ") [" + agent.health + "/" + agent.satiety +  "] has died at x:" + agent.x + " y:" + agent.y + " on tick " + this.tickId);

        // Create food instead of died agent
        var food = Food.create(2000);
        food.setLocation(agent.x, agent.y);
        this.objects.push(food);
        this.log("Food with richness: " + food.richness + " was created instead of died agent at x:" + food.x + " y:" + food.y);

        // Remove agent from server
        this.agents.splice(this.agents.indexOf(agent), 1);
    }
};

Server.prototype.sanitizeDecision = function (agent, decision) {
    try {
        if (decision !== Object(decision)) {
            throw new Error("decision returned not an object");
        }

        decision.action = parseInt(decision.action);

        if (decision.action === 0) { // Idle

            return {
                "isProcessed" : false,
                "action" : 0
            };

        } else if (decision.action === 1) { // Move
            decision.dir = parseInt(decision.dir);
            if (decision.dir === undefined || !_.contains(this.map.getPossibleDirections(), decision.dir)) {
                throw new Error("decision returned wrong direction code: " + decision.dir);
            }

            return {
                "isProcessed" : false,
                "action" : 1,
                "dir"    : decision.dir
            };

        } else if (decision.action === 2) { // Reserved

            throw new Error("action code: " + decision.action + " is reserved");

        } else if (decision.action === 4) { // Eat food

            decision.dir = parseInt(decision.dir);
            if (decision.dir === undefined || !_.contains(this.map.getPossibleDirections(), decision.dir)) {
                throw new Error("decision returned wrong direction code: " + decision.dir);
            }

            return {
                "isProcessed"   : false,
                "action"        : 4,
                "dir"           : decision.dir
            };

        } else {
            throw new Error("decision returned wrong action code: " + decision.action);
        }

    } catch (e) {
        agent.client.onNotification(1); // Notify agent that its decision has wrong format or params and will skip current tick
        throw e;
    }
};

Server.prototype.processDecisionMove = function (decision) {
    var movementMap = this.map.getDirectionsMap(),
        agent = decision.agent,
        relCoords, coords;

    relCoords = movementMap[decision.dir];
    coords = this.map.getXYByRel(agent.x, agent.y, relCoords.x, relCoords.y);
    if (agent.canMoveToTerrainType(this.map.getTerrainTypeByXY(coords.x, coords.y))) {
        agent.x = coords.x;
        agent.y = coords.y;

        this.log(agent.name + "(" + agent.id + ") [" + agent.health + "/" + agent.satiety + "] moved to x:" + agent.x + " y:" + agent.y);
    } else {
        agent.client.onNotification(21);
    }

    decision.isProcessed = true;
};

Server.prototype.processDecisionEatFood = function (decision) {
    var movementMap = this.map.getDirectionsMap(),
        agent = decision.agent,
        relCoords, coords, food;

    relCoords = movementMap[decision.dir];
    coords = this.map.getXYByRel(agent.x, agent.y, relCoords.x, relCoords.y);
    food = _.first(_.filter(this.getObjectsByXY(coords.x, coords.y), function (obj) {
        return obj.class === "food";
    }));

    if (!food) {
        agent.client.onNotification(41);
    } else if (agent.satiety === 10000) {
        agent.client.onNotification(42);
    } else {
        this.log(agent.name + "(" + agent.id + ") [" + agent.health + "/" + agent.satiety + "] ate food from x:" + coords.x + " y:" + coords.y
            + " satiety: (+" + food.richness + ")");

        agent.satiety = (agent.satiety + food.richness > 10000) ? 10000 : agent.satiety + food.richness;

        // Remove food
        this.objects.splice(this.objects.indexOf(food), 1);
    }

    decision.isProcessed = true;
};

Server.prototype.processDecisions = function (decisions) {
    var decision;

    for (var i in decisions) {
        decision = decisions[i];

        if (decision.action === 1) {
            this.processDecisionMove(decision);
        } else if (decision.action === 4) {
            this.processDecisionEatFood(decision);
        }
    }
};

Server.prototype.tick = function () {
    var decisions = [], decision;

    this.tickId++;
    if (!(this.tickId % 100)) {
        this.generateFood();
    }

    _.each(this.agents, function (agent) {
        // Recalculate agent's characteristics (health, etc.), remove died
        this.updateAgentStatus(agent);
    }, this);

    _.each(this.agents, function (agent) {
        try {

            // Skip if agent is died after the recalculation
            if (!agent.isAlive()) {
                return;
            }

            // Notify the agent that new tick has begun
            agent.client.onNewTick(this.getAgentStatus(agent));

            // Get and validate agent's decision
            decision = agent.client.decision();
            if (!decision) {
                // Skip if idle action
                return;
            }

            decision = this.sanitizeDecision(agent, decision);
            if (!decision.action) {
                // Skip if idle action
                return;
            }

            decision.agent = agent;

            // Collect all decisions
            decisions.push(decision);

        } catch (e) {
            this.log(agent.name + "(" + agent.id + ")" + " skipped on tick " + this.tickId + " because of error: " + e.message);
        }
    }, this);

    this.processDecisions(decisions);

    this.saveServerState();
//    this.printWorld();

    if (!this.agents.length) {
        this.log("All agents died");
        this.stop();
    }

    var self = this;
    setTimeout(function () {
        self.tick.call(self);
    }, this.tickInterval);
};

Server.prototype.saveServerState = function () {
    var state = {
        "tickId" : this.tickId,
        "map"    : {
            "width" : this.map.width,
            "height" : this.map.health,
            "map" : this.map.map
        },
        "agents"  : [],
        "objects" : [],
        "log"     : []
    };

    state.agents = _.map(this.agents, function (agent) {
        return {
            "id"        : agent.id,
            "name"      : agent.name,
            "author"    : agent.author,
            "x"         : agent.x,
            "y"         : agent.y,
            "health"    : agent.health,
            "satiety"   : agent.satiety
        };
    });

    state.objects = _.map(this.objects, function (obj) {
        return {
            "class" : obj.class,
            "x"     : obj.x,
            "y"     : obj.y
        };
    });

    fs.writeFileSync("./var/state.json", JSON.stringify(state));
};

Server.prototype.printWorld = function () {
    for (var y = 0 ; y < this.map.height ; y++) {
        for (var x = 0 ; x < this.map.width ; x++) {
            if (this.getAgentByXY(x, y)) {
                process.stdout.write("@");
            } else if (this.getObjectsByXY(x, y).length) {
                process.stdout.write("#");
            } else {
                process.stdout.write(""+this.map.getTerrainTypeByXY(x, y));
            }
        }
        process.stdout.write("\n");
    }
};

Server.prototype.run = function () {
    this.log("Server started");

    this.initAgents();
    this.initFood();

    var self = this;
    setTimeout(function () {
        self.tick.call(self);
    }, this.tickInterval);
};

exports.Server = Server;
<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');
const DashboardPlugin = require('webpack-dashboard/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const PATHS = {
  root: path.resolve(__dirname, '..'),
  nodeModules: path.resolve(__dirname, '../node_modules'),
  src: path.resolve(__dirname, '../src'),
  dist: path.resolve(__dirname, '../dist'),
};

const DEV_SERVER = {
  hot: true,
  hotOnly: true,
  historyApiFallback: true,
  overlay: true,
  // stats: 'verbose',
  // proxy: {
  //   '/api': 'http://localhost:3000'
  // },
};

module.exports = (env = {}) => {
  console.log({ env });
  const isBuild = !!env.build;
  const isDev = !env.build;
  const isSourceMap = !!env.sourceMap || isDev;

  return {
    cache: true,
    devtool: isDev ? 'eval-source-map' : 'source-map',
    devServer: DEV_SERVER,

    context: PATHS.root,

    entry: {
      app: [
        'react-hot-loader/patch',
        './src/index.tsx',
      ],
    },
    output: {
      path: PATHS.dist,
      filename: isDev ? '[name].js' : '[name].[hash].js',
      publicPath: '/',
    },

    resolve: {
      extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
      modules: ['src', 'node_modules'],
    },

    // externals: {
    // },

    module: {
      rules: [
        // awesome-typescript-loader
        {
          test: /\.tsx?$/,
          include: PATHS.src,
          use: (env.awesome ?
            [
              { loader: 'react-hot-loader/webpack' },
              {
                loader: 'awesome-typescript-loader',
                options: {
                  sourceMap: isSourceMap,
                },
              },
            ]
            :
            [
              { loader: 'react-hot-loader/webpack' },
              {
                loader: 'ts-loader',
                options: {
                  transpileOnly: true,
                  compilerOptions: {
                    'target': isDev ? 'es2015' : 'es5',
                    'sourceMap': isSourceMap,
                    'isolatedModules': true,
                    'noEmitOnError': false,
                  },
                },
              },
            ]
          ),
        },
        // json
        {
          test: /\.json$/,
          include: [PATHS.src],
          use: { loader: 'json-loader' },
        },
        // file
        // {
        //   test: /\.(jpg|png|gif)$/,
        //   use: 'file-loader'
        // },
        // url
        // {
        //   test: /\.(woff|woff2|eot|ttf|svg)$/,
        //   use: {
        //     loader: 'url-loader',
        //     options: {
        //       limit: 100000
        //     }
        //   }
        // }
      ],
    },

    plugins: [
      new DashboardPlugin(),
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(isDev ? 'development' : 'production'),
        },
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        minChunks: (module) => module.context && module.context.indexOf('node_modules') !== -1,
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'manifest',
      }),
      ...(isDev ? [
        new webpack.HotModuleReplacementPlugin({
          // multiStep: true, // better performance with many files
        }),
        new webpack.NamedModulesPlugin(),
      ] : []),
      ...(isBuild ? [
        new webpack.optimize.UglifyJsPlugin({
          beautify: false,
          compress: {
            screw_ie8: true
          },
          comments: false,
          sourceMap: isSourceMap,
        }),
        new HtmlWebpackPlugin({
          template: './index.html',
          cache: true,
        }),
      ] : []),
    ]
  };

};
<commit_msg>updated awesome loader config<commit_after>const path = require('path');
const webpack = require('webpack');
const DashboardPlugin = require('webpack-dashboard/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const PATHS = {
  root: path.resolve(__dirname, '..'),
  nodeModules: path.resolve(__dirname, '../node_modules'),
  src: path.resolve(__dirname, '../src'),
  dist: path.resolve(__dirname, '../dist'),
};

const DEV_SERVER = {
  hot: true,
  hotOnly: true,
  historyApiFallback: true,
  overlay: true,
  // stats: 'verbose',
  // proxy: {
  //   '/api': 'http://localhost:3000'
  // },
};

module.exports = (env = {}) => {
  console.log({ env });
  const isBuild = !!env.build;
  const isDev = !env.build;
  const isSourceMap = !!env.sourceMap || isDev;

  return {
    cache: true,
    devtool: isDev ? 'eval-source-map' : 'source-map',
    devServer: DEV_SERVER,

    context: PATHS.root,

    entry: {
      app: [
        'react-hot-loader/patch',
        './src/index.tsx',
      ],
    },
    output: {
      path: PATHS.dist,
      filename: isDev ? '[name].js' : '[name].[hash].js',
      publicPath: '/',
    },

    resolve: {
      extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
      modules: ['src', 'node_modules'],
    },

    // externals: {
    // },

    module: {
      rules: [
        // awesome-typescript-loader
        {
          test: /\.tsx?$/,
          include: PATHS.src,
          use: (env.awesome ?
            [
              { loader: 'react-hot-loader/webpack' },
              {
                loader: 'awesome-typescript-loader',
                options: {
                  transpileOnly: true,
                  useTranspileModule: false,
                  sourceMap: isSourceMap,
                },
              },
            ]
            :
            [
              { loader: 'react-hot-loader/webpack' },
              {
                loader: 'ts-loader',
                options: {
                  transpileOnly: true,
                  compilerOptions: {
                    'sourceMap': isSourceMap,
                    'target': isDev ? 'es2015' : 'es5',
                    'isolatedModules': true,
                    'noEmitOnError': false,
                  },
                },
              },
            ]
          ),
        },
        // json
        {
          test: /\.json$/,
          include: [PATHS.src],
          use: { loader: 'json-loader' },
        },
        // file
        // {
        //   test: /\.(jpg|png|gif)$/,
        //   use: 'file-loader'
        // },
        // url
        // {
        //   test: /\.(woff|woff2|eot|ttf|svg)$/,
        //   use: {
        //     loader: 'url-loader',
        //     options: {
        //       limit: 100000
        //     }
        //   }
        // }
      ],
    },

    plugins: [
      new DashboardPlugin(),
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(isDev ? 'development' : 'production'),
        },
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        minChunks: (module) => module.context && module.context.indexOf('node_modules') !== -1,
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'manifest',
      }),
      ...(isDev ? [
        new webpack.HotModuleReplacementPlugin({
          // multiStep: true, // better performance with many files
        }),
        new webpack.NamedModulesPlugin(),
      ] : []),
      ...(isBuild ? [
        new webpack.optimize.UglifyJsPlugin({
          beautify: false,
          compress: {
            screw_ie8: true
          },
          comments: false,
          sourceMap: isSourceMap,
        }),
        new HtmlWebpackPlugin({
          template: './index.html',
          cache: true,
        }),
      ] : []),
    ]
  };

};
<|endoftext|>


<commit_before>/**
 * Annotation tool Vuex store.
 */

import _ from 'underscore';
import Vue from 'vue';

import AnnotationService from '../../api/annotation';
import ImageService from '../../api/image';
import StudyService from '../../api/study';
import TaskService from '../../api/task';

export const MarkupState = {
    ABSENT: 0.0,
    POSSIBLE: 0.5,
    DEFINITE: 1.0
};

export const SubmissionState = {
    UNSUBMITTED: 'unsubmitted',
    SUBMITTING: 'submitting',
    SUBMITTED: 'submitted',
    FAILED: 'failed',
    FINISHED: 'finished'
};

function initialState() {
    return {
        annotation: null,
        study: null,
        image: null,
        flagStatus: 'ok',
        startTime: null,
        stopTime: null,
        showReview: false,
        markupState: MarkupState.DEFINITE,
        responses: {},
        markups: {},
        activeFeatureId: null,
        submissionState: SubmissionState.UNSUBMITTED
    };
}

export default {
    namespaced: true,
    state: initialState(),
    getters: {
        questions(state) {
            return state.study ? state.study.questions : [];
        },
        features(state) {
            return state.study ? state.study.features : [];
        },
        markedupFeatureIds(state) {
            return Object.keys(state.markups);
        }
    },
    mutations: {
        resetState(state) {
            state = Object.assign(state, initialState());
        },
        setAnnotation(state, annotation) {
            state.annotation = annotation;
        },
        setStudy(state, study) {
            state.study = study;
        },
        setImage(state, image) {
            state.image = image;
        },
        setFlagStatus(state, data) {
            state.flagStatus = data;
        },
        setStartTime(state, data) {
            state.startTime = data;
        },
        setStopTime(state, data) {
            state.stopTime = data;
        },
        setShowReview(state, data) {
            state.showReview = data;
        },
        setMarkupState(state, data) {
            state.markupState = data;
        },
        setResponses(state, data) {
            state.responses = data;
        },
        setResponse(state, { questionId, response }) {
            state.responses[questionId] = response;
        },
        setMarkups(state, data) {
            state.markups = data;
        },
        setMarkup(state, { featureId, values }) {
            if (values) {
                Vue.set(state.markups, featureId, values);
            } else {
                Vue.delete(state.markups, featureId);
            }
        },
        setActiveFeatureId(state, data) {
            state.activeFeatureId = data;
        },
        setSubmissionState(state, data) {
            state.submissionState = data;
        }
    },
    actions: {
        getNextAnnotation({ state, dispatch, commit }, { studyId }) {
            TaskService.getNextAnnotation(studyId)
                .done((resp) => {
                    commit('setAnnotation', resp);
                    commit('setStartTime', Date.now());
                    dispatch('getImage', {id: state.annotation.imageId});
                })
                .fail((resp) => {
                    if (resp.status === 404) {
                        commit('setSubmissionState', SubmissionState.FINISHED);
                    }
                });
        },
        getStudy({ commit }, { id }) {
            StudyService.get(id)
                .done((resp) => commit('setStudy', resp));
        },
        getImage({ commit }, { id }) {
            ImageService.get(id)
                .done((resp) => commit('setImage', resp));
        },
        submitAnnotation({ state, commit }) {
            commit('setSubmissionState', SubmissionState.SUBMITTING);
            commit('setStopTime', Date.now());

            // Submit only responses to questions that user answered
            const responses = _.omit(state.responses, (value) => _.isNull(value));

            const annotation = {
                status: state.flagStatus,
                imageId: state.image._id,
                startTime: state.startTime,
                stopTime: state.stopTime,
                responses: responses,
                markups: state.markups
            };

            AnnotationService.submit(state.annotation._id, annotation)
                .done(() => commit('setSubmissionState', SubmissionState.SUBMITTED))
                .fail(() => commit('setSubmissionState', SubmissionState.FAILED));
        }
    }
};
<commit_msg>Store annotation dates internally as objects<commit_after>/**
 * Annotation tool Vuex store.
 */

import _ from 'underscore';
import Vue from 'vue';

import AnnotationService from '../../api/annotation';
import ImageService from '../../api/image';
import StudyService from '../../api/study';
import TaskService from '../../api/task';

export const MarkupState = {
    ABSENT: 0.0,
    POSSIBLE: 0.5,
    DEFINITE: 1.0
};

export const SubmissionState = {
    UNSUBMITTED: 'unsubmitted',
    SUBMITTING: 'submitting',
    SUBMITTED: 'submitted',
    FAILED: 'failed',
    FINISHED: 'finished'
};

function initialState() {
    return {
        annotation: null,
        study: null,
        image: null,
        flagStatus: 'ok',
        startTime: null,
        stopTime: null,
        showReview: false,
        markupState: MarkupState.DEFINITE,
        responses: {},
        markups: {},
        activeFeatureId: null,
        submissionState: SubmissionState.UNSUBMITTED
    };
}

export default {
    namespaced: true,
    state: initialState(),
    getters: {
        questions(state) {
            return state.study ? state.study.questions : [];
        },
        features(state) {
            return state.study ? state.study.features : [];
        },
        markedupFeatureIds(state) {
            return Object.keys(state.markups);
        }
    },
    mutations: {
        resetState(state) {
            state = Object.assign(state, initialState());
        },
        setAnnotation(state, annotation) {
            state.annotation = annotation;
        },
        setStudy(state, study) {
            state.study = study;
        },
        setImage(state, image) {
            state.image = image;
        },
        setFlagStatus(state, data) {
            state.flagStatus = data;
        },
        setStartTime(state, data) {
            state.startTime = data;
        },
        setStopTime(state, data) {
            state.stopTime = data;
        },
        setShowReview(state, data) {
            state.showReview = data;
        },
        setMarkupState(state, data) {
            state.markupState = data;
        },
        setResponses(state, data) {
            state.responses = data;
        },
        setResponse(state, { questionId, response }) {
            state.responses[questionId] = response;
        },
        setMarkups(state, data) {
            state.markups = data;
        },
        setMarkup(state, { featureId, values }) {
            if (values) {
                Vue.set(state.markups, featureId, values);
            } else {
                Vue.delete(state.markups, featureId);
            }
        },
        setActiveFeatureId(state, data) {
            state.activeFeatureId = data;
        },
        setSubmissionState(state, data) {
            state.submissionState = data;
        }
    },
    actions: {
        getNextAnnotation({ state, dispatch, commit }, { studyId }) {
            TaskService.getNextAnnotation(studyId)
                .done((resp) => {
                    commit('setAnnotation', resp);
                    commit('setStartTime', new Date());
                    dispatch('getImage', {id: state.annotation.imageId});
                })
                .fail((resp) => {
                    if (resp.status === 404) {
                        commit('setSubmissionState', SubmissionState.FINISHED);
                    }
                });
        },
        getStudy({ commit }, { id }) {
            StudyService.get(id)
                .done((resp) => commit('setStudy', resp));
        },
        getImage({ commit }, { id }) {
            ImageService.get(id)
                .done((resp) => commit('setImage', resp));
        },
        submitAnnotation({ state, commit }) {
            commit('setSubmissionState', SubmissionState.SUBMITTING);
            commit('setStopTime', new Date());

            // Submit only responses to questions that user answered
            const responses = _.omit(state.responses, (value) => _.isNull(value));

            const annotation = {
                status: state.flagStatus,
                imageId: state.image._id,
                startTime: state.startTime.getTime(),
                stopTime: state.stopTime.getTime(),
                responses: responses,
                markups: state.markups
            };

            AnnotationService.submit(state.annotation._id, annotation)
                .done(() => commit('setSubmissionState', SubmissionState.SUBMITTED))
                .fail(() => commit('setSubmissionState', SubmissionState.FAILED));
        }
    }
};
<|endoftext|>


<commit_before>// MIT License
//
// Copyright (c) 2017 Jordan Reed
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

function VertexShader() {
  this.uniforms = {};
  this.incoming = {};
  this.main = function() {
    throw "Must override the vertex shader's main function";
  };
}

VertexShader.prototype.findIncomingSourcesLength = function() {
  var length = null;

  for (var propName in this.incoming) {
    if (this.incoming.hasOwnProperty(propName)) {
      var prop = this.incoming[propName];
      if (!prop || prop.constructor != Array) {
        throw {
          message: "Expected incoming source (" + propName + ") to be of type Array",
          source: prop
        };
      }

      var nextLength = prop.length;
      if (length != null && length != nextLength) {
        throw {
          message: "Incoming sources on shader must be the same length",
          incoming: this.incoming
        };
      }
      length = nextLength;
    }
  }

  return length === null ? 0 : length;
};

VertexShader.prototype.getInput = function(index) {
  var input = {};
  for (var propName in this.incoming) {
    if (this.incoming.hasOwnProperty(propName)) {
      input[propName] = this.incoming[propName][index];
    }
  }
  return input;
};

VertexShader.prototype.runMain = function(input) {
  var result = this.main(input);
  if (typeof result != "object" || !result.position || result.position.constructor != vec4) {
    throw {
      message: "Expected vertex shader to return an object with property 'position'",
      returnValue: result
    };
  }
  return result;
};

function FragmentShader() {
  this.uniforms = {};
  this.main = function() {
    throw "Must override the fragment shader's main function";
  };
}

FragmentShader.prototype.runMain = function(input) {
  var result = this.main(input);
  if (!result || result.constructor != vec4) {
    throw {
      message: "Expected fragment shader to return value of type vec4",
      returnValue: result
    };
  }
  return result;
};<commit_msg>Changed a != to !==<commit_after>// MIT License
//
// Copyright (c) 2017 Jordan Reed
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

function VertexShader() {
  this.uniforms = {};
  this.incoming = {};
  this.main = function() {
    throw "Must override the vertex shader's main function";
  };
}

VertexShader.prototype.findIncomingSourcesLength = function() {
  var length = null;

  for (var propName in this.incoming) {
    if (this.incoming.hasOwnProperty(propName)) {
      var prop = this.incoming[propName];
      if (!prop || prop.constructor != Array) {
        throw {
          message: "Expected incoming source (" + propName + ") to be of type Array",
          source: prop
        };
      }

      var nextLength = prop.length;
      if (length != null && length != nextLength) {
        throw {
          message: "Incoming sources on shader must be the same length",
          incoming: this.incoming
        };
      }
      length = nextLength;
    }
  }

  return length === null ? 0 : length;
};

VertexShader.prototype.getInput = function(index) {
  var input = {};
  for (var propName in this.incoming) {
    if (this.incoming.hasOwnProperty(propName)) {
      input[propName] = this.incoming[propName][index];
    }
  }
  return input;
};

VertexShader.prototype.runMain = function(input) {
  var result = this.main(input);
  if (typeof result != "object" || !result.position || result.position.constructor != vec4) {
    throw {
      message: "Expected vertex shader to return an object with property 'position'",
      returnValue: result
    };
  }
  return result;
};

function FragmentShader() {
  this.uniforms = {};
  this.main = function() {
    throw "Must override the fragment shader's main function";
  };
}

FragmentShader.prototype.runMain = function(input) {
  var result = this.main(input);
  if (!result || result.constructor !== vec4) {
    throw {
      message: "Expected fragment shader to return value of type vec4",
      returnValue: result
    };
  }
  return result;
};
<|endoftext|>