<commit_before>/*!
==========================================================================================

The MIT License (MIT)

Copyright (c) 2017 Måns Beckman - www.spatialillusions.com

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.

------------------------------------------------------------------------------------------

For updates and more information go to http://www.spatialillusions.com

==========================================================================================
*/
'use strict';

var ms = new function(){
  this._colorModes = {};
  this._dashArrays = {
    pending: "4,4",
    anticipated: "8,12",
    feintDummy: "8,8"
  };
  this._hqStafLength = 100;
  this._iconCache = {}; // A cache of icn to speed stuff up...
  this._iconParts = [];
  this._labelCache = {}; // A cache of label overrides to speed stuff up...
  this._labelOverrides = {};
  this._letterSIDCicons = [];
  this._numberSIDCicons = [];
  this._STD2525 = true;
  this._svgNS = "http://www.w3.org/2000/svg";
  this._symbolParts = [];

  this.autoSVG = false;
  this.version = '1.0.0';

  if (typeof console === 'object') {
    console.info('milsymbol.js ' + this.version + ' - Copyright (c) 2017 Måns Beckman  http://www.spatialillusions.com');
  }
  if (typeof parseXML === 'undefined') {
    window.parseXML = function (s,doc) {
      doc = doc || document;
      var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
      return doc.adoptNode(doc2.documentElement);
    };
  }
};

ms._scale = function(factor, instruction){
  return {type:'translate',x:(100-factor*100),y:(100-factor*100),draw:[{type:'scale',factor:factor,draw:[instruction]}]};
};
ms._translate = function(x, y, instruction){
  return {type:'translate',x:x,y:y,draw:[instruction]};
};

ms.addIconParts = function(parts) {
  if (typeof parts === 'function') {
    this._iconParts = this._iconParts.concat(parts);
  }
  return ms;
};
ms.addLabelOverrides = function(parts, type){
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty(type)) this._labelOverrides[type] = [];
    this._labelOverrides[type] = this._labelOverrides[type].concat(parts);
  }
  return ms;
};
ms.addSIDCicons = function(parts, type){
  if (typeof parts === 'function') {
    this['_' + type + 'SIDCicons'] = this['_' + type + 'SIDCicons'].concat(parts);
  }
  return ms;
};
ms.addSymbolPart = function(part) {
  if (typeof part === 'function') {
    ms.setSymbolParts(ms.getSymbolParts().concat(part));
  }
  return ms;
};
ms.BBox = require('./ms/bbox.js');
ms.ColorMode = function(civilian, friend, hostile, neutral, unknown) {
  var o = {};
  o.Civilian = civilian;
  o.Friend 	= friend;
  o.Hostile = hostile;
  o.Neutral = neutral;
  o.Unknown = unknown;
  return o;
};
ms.getColorMode = function(mode) {
  var c = this._colorModes[mode];
  // Clone the mode and return the clone
  return new ms.ColorMode(c.Civilian, c.Friend, c.Hostile, c.Neutral, c.Unknown);
};
ms.getDashArrays = function() {
  return this._dashArrays;
};
ms.getHqStafLength = function() {
  return this._hqStafLength;
};
ms.getSymbolParts = function() {
  return this._symbolParts.slice(0);
};
ms.getVersion = function() {return this.version};
ms.outline = function(geom, outline, stroke, color){
  if(Array.isArray(geom)){
    var clone = [];
    for(var i in geom){
      clone.push(ms.outline(geom[i],outline,stroke,color));
    }
  }else{
    var clone = {};
    for (var key in geom){
      if(['fill','fillopacity'].indexOf(key) == -1){
        clone[key] = geom[key];
      }
    }
    if(geom.type == 'translate' || geom.type == 'rotate'  || geom.type == 'scale'){
      clone.draw = [];
      for (var draw in geom.draw){
        clone.draw.push(ms.outline(geom.draw[draw],outline,stroke,color));
      }
    }else{
      clone.strokewidth = clone.stroke != false ? (Number(clone.strokewidth||stroke) + 2*outline) : 2*outline;
      clone.stroke = color;
      clone.fill = false;
      clone.linecap = 'round';
    }
  }
  return clone;
};
ms.setAutoSVG = function(mode) {this.autoSVG = mode; return this.autoSVG;};
ms.setColorMode = function(mode, colorMode) {
  this._colorModes[mode] = {};
  this._colorModes[mode].Hostile 	= colorMode.Hostile;
  this._colorModes[mode].Friend 	= colorMode.Friend;
  this._colorModes[mode].Neutral 	= colorMode.Neutral;
  this._colorModes[mode].Unknown 	= colorMode.Unknown;
  this._colorModes[mode].Civilian = colorMode.Civilian;
  return this._colorModes[mode];
};
ms.setDashArrays = function(pending, anticipated, feintDummy) {
  this._dashArrays.pending = pending;
  this._dashArrays.anticipated = anticipated;
  this._dashArrays.feintDummy = feintDummy;
  return this._dashArrays;
};
ms.setHqStafLength = function(len) {
  this._hqStafLength = len;
  return this._hqStafLength;
};
ms.setSymbolParts = function(parts) {
  this._symbolParts = parts;
  return ms;
};
ms.setStandard = require('./ms/setstandard.js');

// For backward compability
ms.addMarkerParts = function(part) {
  console.log('addMarkerParts() is deprecated and should not be used, use addSymbolPart() instead.');
  ms.addSymbolPart(part);
};
ms.bboxMax = function(box1, box2){
  console.log('bboxMax() is deprecated and should not be used, use BBox.merge() instead.');
  return box1.merge(box2);
};
ms.buildingBlock = function(pre, post, bbox) {
  console.log('buildingBlock() is deprecated and should not be used.');
  if ( pre.length == 1 && Array.isArray(pre[0]) ) pre = pre[0];
  if ( post.length == 1 && Array.isArray(post[0]) ) post = post[0];
  return {pre: pre, post: post, bbox: bbox};
};
ms.addLetterLabelOverrides = function(parts){
  console.log('addLetterLabelOverrides() is deprecated and should not be used, use addLabelOverrides() instead.');
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('letter')) this._labelOverrides['letter'] = [];
      this._labelOverrides['letter'] = this._labelOverrides['letter'].concat(parts);
    }
};
ms.addLetterSIDCicons = function(parts){
  console.log('addLetterSIDCicons() is deprecated and should not be used, use addSIDCicons() instead.');
  if (typeof parts === 'function') {
    this._letterSIDCicons = this._letterSIDCicons.concat(parts);
  }
};
ms.addNumberLabelOverrides = function(parts){
  console.log('addNumberLabelOverrides() is deprecated and should not be used, use addLabelOverrides() instead.');
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('number')) this._labelOverrides['number'] = [];
      this._labelOverrides['number'] = this._labelOverrides['number'].concat(parts);
    }
};
ms.addNumberSIDCicons = function(parts){
  console.log('addNumberSIDCicons() is deprecated and should not be used, use addSIDCicons() instead.');
  if (typeof parts === 'function') {
    this._numberSIDCicons = this._numberSIDCicons.concat(parts);
  }
};

ms.bbox = function(box){
  console.log('bbox() is deprecated and should not be used, use BBox() instead.');
  return ms.BBox(box);
}

ms.colorMode = function(civilian, friend, hostile, neutral, unknown) {
  console.log('colorMode() is deprecated and should not be used, use ColorMode() instead.');
  return ms.ColorMode(civilian, friend, hostile, neutral, unknown);
};

ms.getMarkerParts = function() {
  console.log('getMarkerParts() is deprecated and should not be used, use getSymbolParts() instead.');
  return ms.getSymbolParts();
};

ms.setMarkerParts = function(parts) {
  console.log('setMarkerParts() is deprecated and should not be used, use setSymbolParts() instead.');
  ms.setSymbolParts(parts);
  return ms;
};

module.exports = ms;<commit_msg>Bump version in master branch<commit_after>/*!
==========================================================================================

The MIT License (MIT)

Copyright (c) 2017 Måns Beckman - www.spatialillusions.com

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.

------------------------------------------------------------------------------------------

For updates and more information go to http://www.spatialillusions.com

==========================================================================================
*/
'use strict';

var ms = new function(){
  this._colorModes = {};
  this._dashArrays = {
    pending: "4,4",
    anticipated: "8,12",
    feintDummy: "8,8"
  };
  this._hqStafLength = 100;
  this._iconCache = {}; // A cache of icn to speed stuff up...
  this._iconParts = [];
  this._labelCache = {}; // A cache of label overrides to speed stuff up...
  this._labelOverrides = {};
  this._letterSIDCicons = [];
  this._numberSIDCicons = [];
  this._STD2525 = true;
  this._svgNS = "http://www.w3.org/2000/svg";
  this._symbolParts = [];

  this.autoSVG = false;
  this.version = '1.0.0+';

  if (typeof console === 'object') {
    console.info('milsymbol.js ' + this.version + ' - Copyright (c) 2017 Måns Beckman  http://www.spatialillusions.com');
  }
  if (typeof parseXML === 'undefined') {
    window.parseXML = function (s,doc) {
      doc = doc || document;
      var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
      return doc.adoptNode(doc2.documentElement);
    };
  }
};

ms._scale = function(factor, instruction){
  return {type:'translate',x:(100-factor*100),y:(100-factor*100),draw:[{type:'scale',factor:factor,draw:[instruction]}]};
};
ms._translate = function(x, y, instruction){
  return {type:'translate',x:x,y:y,draw:[instruction]};
};

ms.addIconParts = function(parts) {
  if (typeof parts === 'function') {
    this._iconParts = this._iconParts.concat(parts);
  }
  return ms;
};
ms.addLabelOverrides = function(parts, type){
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty(type)) this._labelOverrides[type] = [];
    this._labelOverrides[type] = this._labelOverrides[type].concat(parts);
  }
  return ms;
};
ms.addSIDCicons = function(parts, type){
  if (typeof parts === 'function') {
    this['_' + type + 'SIDCicons'] = this['_' + type + 'SIDCicons'].concat(parts);
  }
  return ms;
};
ms.addSymbolPart = function(part) {
  if (typeof part === 'function') {
    ms.setSymbolParts(ms.getSymbolParts().concat(part));
  }
  return ms;
};
ms.BBox = require('./ms/bbox.js');
ms.ColorMode = function(civilian, friend, hostile, neutral, unknown) {
  var o = {};
  o.Civilian = civilian;
  o.Friend 	= friend;
  o.Hostile = hostile;
  o.Neutral = neutral;
  o.Unknown = unknown;
  return o;
};
ms.getColorMode = function(mode) {
  var c = this._colorModes[mode];
  // Clone the mode and return the clone
  return new ms.ColorMode(c.Civilian, c.Friend, c.Hostile, c.Neutral, c.Unknown);
};
ms.getDashArrays = function() {
  return this._dashArrays;
};
ms.getHqStafLength = function() {
  return this._hqStafLength;
};
ms.getSymbolParts = function() {
  return this._symbolParts.slice(0);
};
ms.getVersion = function() {return this.version};
ms.outline = function(geom, outline, stroke, color){
  if(Array.isArray(geom)){
    var clone = [];
    for(var i in geom){
      clone.push(ms.outline(geom[i],outline,stroke,color));
    }
  }else{
    var clone = {};
    for (var key in geom){
      if(['fill','fillopacity'].indexOf(key) == -1){
        clone[key] = geom[key];
      }
    }
    if(geom.type == 'translate' || geom.type == 'rotate'  || geom.type == 'scale'){
      clone.draw = [];
      for (var draw in geom.draw){
        clone.draw.push(ms.outline(geom.draw[draw],outline,stroke,color));
      }
    }else{
      clone.strokewidth = clone.stroke != false ? (Number(clone.strokewidth||stroke) + 2*outline) : 2*outline;
      clone.stroke = color;
      clone.fill = false;
      clone.linecap = 'round';
    }
  }
  return clone;
};
ms.setAutoSVG = function(mode) {this.autoSVG = mode; return this.autoSVG;};
ms.setColorMode = function(mode, colorMode) {
  this._colorModes[mode] = {};
  this._colorModes[mode].Hostile 	= colorMode.Hostile;
  this._colorModes[mode].Friend 	= colorMode.Friend;
  this._colorModes[mode].Neutral 	= colorMode.Neutral;
  this._colorModes[mode].Unknown 	= colorMode.Unknown;
  this._colorModes[mode].Civilian = colorMode.Civilian;
  return this._colorModes[mode];
};
ms.setDashArrays = function(pending, anticipated, feintDummy) {
  this._dashArrays.pending = pending;
  this._dashArrays.anticipated = anticipated;
  this._dashArrays.feintDummy = feintDummy;
  return this._dashArrays;
};
ms.setHqStafLength = function(len) {
  this._hqStafLength = len;
  return this._hqStafLength;
};
ms.setSymbolParts = function(parts) {
  this._symbolParts = parts;
  return ms;
};
ms.setStandard = require('./ms/setstandard.js');

// For backward compability
ms.addMarkerParts = function(part) {
  console.log('addMarkerParts() is deprecated and should not be used, use addSymbolPart() instead.');
  ms.addSymbolPart(part);
};
ms.bboxMax = function(box1, box2){
  console.log('bboxMax() is deprecated and should not be used, use BBox.merge() instead.');
  return box1.merge(box2);
};
ms.buildingBlock = function(pre, post, bbox) {
  console.log('buildingBlock() is deprecated and should not be used.');
  if ( pre.length == 1 && Array.isArray(pre[0]) ) pre = pre[0];
  if ( post.length == 1 && Array.isArray(post[0]) ) post = post[0];
  return {pre: pre, post: post, bbox: bbox};
};
ms.addLetterLabelOverrides = function(parts){
  console.log('addLetterLabelOverrides() is deprecated and should not be used, use addLabelOverrides() instead.');
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('letter')) this._labelOverrides['letter'] = [];
      this._labelOverrides['letter'] = this._labelOverrides['letter'].concat(parts);
    }
};
ms.addLetterSIDCicons = function(parts){
  console.log('addLetterSIDCicons() is deprecated and should not be used, use addSIDCicons() instead.');
  if (typeof parts === 'function') {
    this._letterSIDCicons = this._letterSIDCicons.concat(parts);
  }
};
ms.addNumberLabelOverrides = function(parts){
  console.log('addNumberLabelOverrides() is deprecated and should not be used, use addLabelOverrides() instead.');
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('number')) this._labelOverrides['number'] = [];
      this._labelOverrides['number'] = this._labelOverrides['number'].concat(parts);
    }
};
ms.addNumberSIDCicons = function(parts){
  console.log('addNumberSIDCicons() is deprecated and should not be used, use addSIDCicons() instead.');
  if (typeof parts === 'function') {
    this._numberSIDCicons = this._numberSIDCicons.concat(parts);
  }
};

ms.bbox = function(box){
  console.log('bbox() is deprecated and should not be used, use BBox() instead.');
  return ms.BBox(box);
}

ms.colorMode = function(civilian, friend, hostile, neutral, unknown) {
  console.log('colorMode() is deprecated and should not be used, use ColorMode() instead.');
  return ms.ColorMode(civilian, friend, hostile, neutral, unknown);
};

ms.getMarkerParts = function() {
  console.log('getMarkerParts() is deprecated and should not be used, use getSymbolParts() instead.');
  return ms.getSymbolParts();
};

ms.setMarkerParts = function(parts) {
  console.log('setMarkerParts() is deprecated and should not be used, use setSymbolParts() instead.');
  ms.setSymbolParts(parts);
  return ms;
};

module.exports = ms;<|endoftext|>


<commit_before>(function (d, w) {
  'use strict';

  // Constructor for the Wenku library.
  function Wenku(e) {
    var i;
    for (i = 0; i < e.length; i += 1) {
      this[i] = e[i];
    }
    this.length = e.length;
  }

  function wenku(selector) {
    var e,
        isID = /^#(\w+)$/,
        isClass = /^\.(\w+)$/,
        isTag = /^(\w+)$/;

    if (!selector) {
      return this;
    }

    if (typeof selector === 'string') {
      if (isID.test(selector)) {
        e = [d.getElementById(selector.substring(1))];
      } else if (isClass.test(selector)) {
        e = d.getElementsByClassName(selector.substring(1));
      } else if (isTag.test(selector)) {
        e = d.getElementsByTagName(selector);
      } else {
        e = d.querySelectorAll(selector);
      }
    } else if (selector.length) {
      e = selector;
    } else {
      e = [selector];
    }

    return new Wenku(e);
  }

  Wenku.prototype = {
    map: function (callback) {
      var results = [],
          i,
          self = this;

      for (i = 0; i < self.length; i += 1) {
        results.push(callback.call(self, self[i], i));
      }
      return results;
    },
    forEach: function (callback) {
      this.map(callback);
      return this;
    },
    typeOf: function (val) {
      var valType = typeof val;
      if (valType === 'object') {
        if (val) {
          if (Object.prototype.toString.call(val) === '[object Array]') {
            valType = 'array';
          }
        } else {
          valType = 'null';
        }
      }
      return valType;
    },
  };

  w.wenku = wenku;
}(document, window));
<commit_msg>Add class methods, css, and events<commit_after>// Wenku is a very small very simple JavaScript library.
// Author: Bjorn A. Johansen
//
//

(function (d, w) {
  'use strict';

  // Constructor for the Wenku library.
  function Wenku(e) {
    var i;
    for (i = 0; i < e.length; i += 1) {
      this[i] = e[i];
    }
    this.length = e.length;
  }

  function wenku(selector) {
    var e,
        isID = /^#(\w+)$/,
        isClass = /^\.(\w+)$/,
        isTag = /^(\w+)$/;

    if (!selector) {
      return this;
    }

    if (typeof selector === 'string') {
      if (isID.test(selector)) {
        e = [d.getElementById(selector.substring(1))];
      } else if (isClass.test(selector)) {
        e = d.getElementsByClassName(selector.substring(1));
      } else if (isTag.test(selector)) {
        e = d.getElementsByTagName(selector);
      } else {
        e = d.querySelectorAll(selector);
      }
    } else if (selector.length) {
      e = selector;
    } else {
      e = [selector];
    }

    return new Wenku(e);
  }

  Wenku.prototype = {
    map: function (callback) {
      var results = [],
          i,
          self = this;

      for (i = 0; i < self.length; i += 1) {
        results.push(callback.call(self, self[i], i));
      }
      return results;
    },
    forEach: function (callback) {
      this.map(callback);
      return this;
    },
    typeOf: function (val) {
      var valType = typeof val;
      if (valType === 'object') {
        if (val) {
          if (Object.prototype.toString.call(val) === '[object Array]') {
            valType = 'array';
          }
        } else {
          valType = 'null';
        }
      }
      return valType;
    },
    // Adds one or more classes to any given number of elements
    // classes: an array or string of class(es).
    addClass: function (classes) {
      // If we do not have an array, we assign the classes
      // appended a leading space to className.
      // If we do have an array, we join the array elements
      var className = (this.typeOf(classes) !== 'array') ? ' ' + classes : ' ' + classes.join(' ');
      // If element e has a class we add the new classes to that,
      // if not we trim the leading space and add the classes.
      return this.forEach(function (e) {
        e.className += e.className ? className : className.trim();
      });
    },
    //Removes one or more classes from any given number of elemnts.
    // classes: an array or string of classes
    removeClass: function (classes) {
      var remClasses = (this.typeOf(classes) !== 'array') ? classes.split(' ') : classes,
          oldIndex;
      return this.forEach(function (e) {
        e.className = (function remClass(oClass, rClass) {
          oldIndex = oClass.indexOf(rClass);
          return (rClass && oldIndex > -1) ? remClass((function () {
            oClass.splice(oldIndex, 1);
            return oClass;
          }()), remClasses[remClasses.indexOf(rClass) + 1]) : oClass.join(' ');
        }(e.className.split(' '), remClasses[0]));
      });
    },
    // Returns true or false depending on any elements have
    // the class.
    hasClass: function (klass) {
      var classThere = false;
      this.forEach(function (e) {
        if (e.nodeType === 1 && e.className.indexOf(klass) >= 0) {
          classThere = true;
        }
      });
      return classThere;
    },
    // Adds CSS styling to any given number of elements.
    css: function (style) {
      return this.forEach(function (e) {
        e.setAttribute('style', style);
      });
    },
    // Adds eventlistener to any given number of elements
    on: (function () {
      if (d.addEventListener) {
        return function (evt, fn) {
          return this.forEach(function (e) {
            e.addEventListener(evt, fn, false);
          });
        };
      }
      if (d.attachEvent) {
        return function (evt, fn) {
          return this.forEach(function (e) {
            var bound = function () {
              return fn.apply(e, arguments);
            };
            e.attachEvent('on' + evt, bound);
            return bound;
          });
        };
      }
    }()),
    // Removes eventlistener from any given number of elements.
    off: (function () {
      if (d.removeEventListener) {
        return function (e, fn) {
          return this.forEach(function (el) {
            el.removeEventListener(e, fn, false);
          });
        };
      }
      if (d.detachEvent) {
        return function (e, fn) {
          return this.forEach(function (el) {
            el.detachEvent('on' + e, fn);
          });
        };
      }
    }())
  };

  w.wenku = wenku;
}(document, window));
<|endoftext|>


<commit_before>const queryString = require('query-string').parse(window.location.search);
const Infrastructure = require('../models/infrastructure').default;
const RDSInstance = require('../models/rds_instance').default;

const helpers = require('../infrastructures/helper.js');

const alertSuccess = helpers.alert_success;
const alertDanger = helpers.alert_danger;
const alertAndShowInfra = helpers.alert_and_show_infra;

const methods = require('../infrastructures/common-methods');

const checkTag = methods.check_tag;

const modal = require('../modal');

module.exports = Vue.extend({
  template: '#rds-tabpane-template',

  props: {
    physical_id: {
      type: String,
      required: true,
    },
    infra_id: {
      type: Number,
      required: true,
    },
  },

  data() {
    return {
      rds: {},
      serverspec: {},
      rules_summary: null,
      lang: queryString.lang,
      address: null,
      change_scale_type_to: null,
      page: 0,
      dispItemSize: 10,
      filteredLength: null,
      filterKey: '',
      modifying: false,
      loading_groups: '',
      loading_s: false,
    };
  },

  methods: {
    change_scale() {
      const self = this;

      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      rds.change_scale(this.change_scale_type_to)
        .done(self.reload)
        .fail(alertDanger(self.reload));

      $('#change-scale-modal').modal('hide');
    },

    gen_serverspec() {
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      rds.gen_serverspec(this.serverspec).done((msg) => {
        alertSuccess(self.reload)(msg);
        $('#rds-serverspec-modal').modal('hide');
      }).fail((msg) => {
        alertDanger(self.reload)(msg);
        $('#rds-serverspec-modal').modal('hide');
      });
    },

    reload() { this.$parent.show_rds(this.physical_id); },

    view_rules() {
      this.$parent.tabpaneID = 'view-rules';
      this.$parent.sec_group = this.rules_summary;
      this.$parent.instance_type = 'rds';
    },

    submit_groups() {
      if (this.modifying) { return; }
      this.modifying = true;

      const self = this;
      const rds = new RDSInstance(new Infrastructure(this.infra_id), this.physical_id);
      const groupIds = this.rules_summary.filter(t => t.checked).map(t => t.group_id);

      rds.rds_submit_groups(groupIds, self.physical_id)
        .done(alertSuccess(self.reload))
        .fail(alertDanger(self.reload));
    },

    check(i) {
      i.checked = !i.checked;
    },
    showPrev() {
      if (this.isStartPage) return;
      this.page -= 1;
    },
    showNext() {
      if (this.isEndPage) return;
      this.page += 1;
    },
    checkTag(r) {
      checkTag(r);
    },
    has_selected(arg) {
      if (arg) {
        return arg.some(c => c.checked);
      }
      return undefined;
    },
    start_rds() {
      if (this.available) { return; }
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      modal.Confirm(t('infrastructures.infrastructure'), t('infrastructures.msg.confirm_start_rds')).done(() => {
        rds.start_rds().done((data) => {
          self.reload();
          alertSuccess()(data.message);
        }).fail(alertDanger());
      });
    },
    stop_rds() {
      if (this.stopped) { return; }
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      modal.Confirm(t('infrastructures.infrastructure'), t('infrastructures.msg.confirm_stop_rds'), 'warning').done(() => {
        rds.stop_rds().done((data) => {
          self.reload();
          alertSuccess()(data.message);
        }).fail(alertDanger());
      });
    },
    reboot_rds() {
      if (this.stopped) { return; }
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      modal.Confirm(t('infrastructures.infrastructure'), t('infrastructures.msg.confirm_reboot_rds'), 'warning').done(() => {
        rds.reboot_rds().done((data) => {
          self.reload();
          alertSuccess()(data.message);
        }).fail(alertDanger());
      });
    },
    roundup(val) { return (Math.ceil(val)); },
  },
  computed: {
    gen_serverspec_enable() {
      const s = this.serverspec;
      return !!(s.username && s.password && s.database);
    },
    available() { return this.rds.db_instance_status === 'available'; },
    stopped() { return this.rds.db_instance_status === 'stopped'; },
    dispItems() {
      const startPage = this.page * this.dispItemSize;
      if (this.filterKey === '') {
        return this.rules_summary.slice(startPage, startPage + this.dispItemSize);
      }

      return this.rules_summary;
    },

    filterd_dispitems() {
      const self = this;
      const items = this.dispItems.filter((data) => {
        if (self.filterKey === '') {
          return true;
        }
        return JSON.stringify(data).toLowerCase().indexOf(self.filterKey.toLowerCase()) !== -1;
      });
      self.filteredLength = items.length;
      return items;
    },

    isStartPage() { return (this.page === 0); },
    isEndPage() { return ((this.page + 1) * this.dispItemSize >= this.rules_summary.length); },
    rds_button_class() {
      if (this.modifying) {
        return 'disabled';
      }
      if (this.available) {
        return 'btn-success';
      }
      return 'btn-default';
    },
    changing_status() {
      return t(`rds.msg.${this.rds.db_instance_status}`);
    },
  },

  mounted() {
    this.$nextTick(() => {
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      rds.show().done((data) => {
        self.rds = data.rds;
        self.address = self.rds.endpoint.address;
        self.rules_summary = data.security_groups;
        if (self.rds.pending_modified_values.db_instance_class) {
          self.rds.db_instance_status = 'modifying';
        }
        if (self.rds.db_instance_status === 'modifying' || self.rds.db_instance_status === 'stopping' || self.rds.db_instance_status === 'starting') {
          setTimeout(() => {
            self.reload();
          }, 15000);
          self.modifying = true;
        }
        self.$parent.loading = false;
      }).fail(alertAndShowInfra(infra.id));
    });
  },
  filters: {
    count(arr) {
      // record length
      this.$set('filteredLength', arr.length);
      // return it intact
      return arr;
    },
  },
});
<commit_msg>rds-tabpane.jsのリファクタリング(method変更)<commit_after>const queryString = require('query-string').parse(window.location.search);
const Infrastructure = require('../models/infrastructure').default;
const RDSInstance = require('../models/rds_instance').default;

const helpers = require('../infrastructures/helper.js');

const alertSuccess = helpers.alert_success;
const alertDanger = helpers.alert_danger;
const alertAndShowInfra = helpers.alert_and_show_infra;

const methods = require('../infrastructures/common-methods');

const checkTag = methods.check_tag;

const modal = require('../modal');

module.exports = Vue.extend({
  template: '#rds-tabpane-template',

  props: {
    physical_id: {
      type: String,
      required: true,
    },
    infra_id: {
      type: Number,
      required: true,
    },
  },

  data() {
    return {
      rds: {},
      serverspec: {},
      rules_summary: null,
      lang: queryString.lang,
      address: null,
      change_scale_type_to: null,
      page: 0,
      dispItemSize: 10,
      filteredLength: null,
      filterKey: '',
      modifying: false,
      loading_groups: '',
      loading_s: false,
    };
  },

  methods: {
    change_scale() {
      const self = this;

      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      rds.change_scale(this.change_scale_type_to)
        .done(self.reload)
        .fail(alertDanger(self.reload));

      $('#change-scale-modal').modal('hide');
    },

    gen_serverspec() {
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      rds.gen_serverspec(this.serverspec).done((msg) => {
        alertSuccess(self.reload)(msg);
        $('#rds-serverspec-modal').modal('hide');
      }).fail((msg) => {
        alertDanger(self.reload)(msg);
        $('#rds-serverspec-modal').modal('hide');
      });
    },

    reload() { this.$parent.show_rds(this.physical_id); },

    view_rules() {
      this.$parent.tabpaneID = 'view-rules';
      this.$parent.sec_group = this.rules_summary;
      this.$parent.instance_type = 'rds';
    },

    submit_groups() {
      if (this.modifying) { return; }
      this.modifying = true;

      const self = this;
      const rds = new RDSInstance(new Infrastructure(this.infra_id), this.physical_id);
      const groupIds = this.rules_summary.filter(t => t.checked).map(t => t.group_id);

      rds.rds_submit_groups(groupIds, self.physical_id)
        .done(alertSuccess(self.reload))
        .fail(alertDanger(self.reload));
    },

    check(i) {
      i.checked = !i.checked;
    },
    showPrev() {
      if (this.isStartPage) return;
      this.page -= 1;
    },
    showNext() {
      if (this.isEndPage) return;
      this.page += 1;
    },
    check_tag(r) {
      checkTag(r);
    },
    has_selected(arg) {
      if (arg) {
        return arg.some(c => c.checked);
      }
      return undefined;
    },
    start_rds() {
      if (this.available) { return; }
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      modal.Confirm(t('infrastructures.infrastructure'), t('infrastructures.msg.confirm_start_rds')).done(() => {
        rds.start_rds().done((data) => {
          self.reload();
          alertSuccess()(data.message);
        }).fail(alertDanger());
      });
    },
    stop_rds() {
      if (this.stopped) { return; }
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      modal.Confirm(t('infrastructures.infrastructure'), t('infrastructures.msg.confirm_stop_rds'), 'warning').done(() => {
        rds.stop_rds().done((data) => {
          self.reload();
          alertSuccess()(data.message);
        }).fail(alertDanger());
      });
    },
    reboot_rds() {
      if (this.stopped) { return; }
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      modal.Confirm(t('infrastructures.infrastructure'), t('infrastructures.msg.confirm_reboot_rds'), 'warning').done(() => {
        rds.reboot_rds().done((data) => {
          self.reload();
          alertSuccess()(data.message);
        }).fail(alertDanger());
      });
    },
    roundup(val) { return (Math.ceil(val)); },
  },
  computed: {
    gen_serverspec_enable() {
      const s = this.serverspec;
      return !!(s.username && s.password && s.database);
    },
    available() { return this.rds.db_instance_status === 'available'; },
    stopped() { return this.rds.db_instance_status === 'stopped'; },
    dispItems() {
      const startPage = this.page * this.dispItemSize;
      if (this.filterKey === '') {
        return this.rules_summary.slice(startPage, startPage + this.dispItemSize);
      }

      return this.rules_summary;
    },

    filterd_dispitems() {
      const self = this;
      const items = this.dispItems.filter((data) => {
        if (self.filterKey === '') {
          return true;
        }
        return JSON.stringify(data).toLowerCase().indexOf(self.filterKey.toLowerCase()) !== -1;
      });
      self.filteredLength = items.length;
      return items;
    },

    isStartPage() { return (this.page === 0); },
    isEndPage() { return ((this.page + 1) * this.dispItemSize >= this.rules_summary.length); },
    rds_button_class() {
      if (this.modifying) {
        return 'disabled';
      }
      if (this.available) {
        return 'btn-success';
      }
      return 'btn-default';
    },
    changing_status() {
      return t(`rds.msg.${this.rds.db_instance_status}`);
    },
  },

  mounted() {
    this.$nextTick(() => {
      const self = this;
      const infra = new Infrastructure(this.infra_id);
      const rds = new RDSInstance(infra, this.physical_id);
      rds.show().done((data) => {
        self.rds = data.rds;
        self.address = self.rds.endpoint.address;
        self.rules_summary = data.security_groups;
        if (self.rds.pending_modified_values.db_instance_class) {
          self.rds.db_instance_status = 'modifying';
        }
        if (self.rds.db_instance_status === 'modifying' || self.rds.db_instance_status === 'stopping' || self.rds.db_instance_status === 'starting') {
          setTimeout(() => {
            self.reload();
          }, 15000);
          self.modifying = true;
        }
        self.$parent.loading = false;
      }).fail(alertAndShowInfra(infra.id));
    });
  },
  filters: {
    count(arr) {
      // record length
      this.$set('filteredLength', arr.length);
      // return it intact
      return arr;
    },
  },
});
<|endoftext|>


<commit_before><commit_msg>add default pic placeholder, close zh-asoiaf-wiki/zh.asoiaf.wechat#2<commit_after><|endoftext|>


<commit_before>var Anima = Anima || {};

Anima.frequencyBuffer = (function() {
  var frequencyBuffer = [];
  var strokeColor = [255,255,255];
  var strokeOpacity = 255;

  return {
    sampleFromBuffer: function(buffer) {
      frequencyBuffer = buffer;
    },
    setStrokeColor: function(color) {
      strokeColor = color;
    },
    setStrokeOpacity: function(opacity) {
      strokeOpacity = opacity;
    },
    draw: function(processing) {
      var x, y, waves_from_origin = window.innerHeight / 2;

      processing.beginShape();
      for (var i = 0; i < frequencyBuffer.length; ++i) {
        x = window.innerWidth * i / frequencyBuffer.length;
        y = (frequencyBuffer[i] === undefined) ? 0 : frequencyBuffer[i] * 1.5;
        processing.vertex(x, waves_from_origin + y);
      }

      processing.vertex(0, waves_from_origin);
      processing.endShape();
    }
  };
})();
<commit_msg>Fix a bug in how we draw frequency<commit_after>var Anima = Anima || {};

Anima.frequencyBuffer = (function() {
  var frequencyBuffer = [];
  var strokeColor = [255,255,255];
  var strokeOpacity = 255;

  return {
    sampleFromBuffer: function(buffer) {
      frequencyBuffer = buffer;
    },
    setStrokeColor: function(color) {
      strokeColor = color;
    },
    setStrokeOpacity: function(opacity) {
      strokeOpacity = opacity;
    },
    draw: function(processing) {
      var x, y, waves_origin = window.innerHeight / 2;

      processing.beginShape();
      for (var i = 0; i < frequencyBuffer.length; ++i) {
        x = window.innerWidth * i / frequencyBuffer.length;
        y = (frequencyBuffer[i] === undefined) ? 0 : frequencyBuffer[i] * 1.5;
        processing.vertex(x, waves_origin + y);
      }

      processing.vertex(x, waves_origin);
      processing.vertex(0, waves_origin);
      processing.endShape();
    }
  };
})();
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { answerTotals } from './utils';

export default class BarGraph extends Component {
  render() {
    const answers = answerTotals(this.props);
    const totalAnswers = this.props.answers.length;
    return (

        {Object.keys(answers).map((key) => {
          const total = answers[key];
          const width = ((total / totalAnswers) * 100).toFixed(2);
          const widthPercent = isNaN(width) ? '0%' : `${width}%`;
          return (

            {key}

{ `${widthPercent} (${total})` }

);
        })}

    );
  }
}

BarGraph.propTypes = {
  answers: PropTypes.array.isRequired
};
<commit_msg>Style Updates to BarGraph Component<commit_after>import _ from 'lodash';
import React, { Component, PropTypes } from 'react';
import { answerTotals } from './utils';

export default class BarGraph extends Component {
  render() {
    const answers = answerTotals(this.props);
    const totalAnswers = this.props.answers.length;
    return (

        {_.keys(answers).map((key) => {
          const total = answers[key];
          const width = ((total / totalAnswers) * 100).toFixed(2);
          const nullWidth = isNaN(width);
          const widthPercent = nullWidth ? '0%' : `${width}%`;
          const valueOffset = nullWidth || width < 80 ? 2 : 20;
          const barValuePosition = isNaN(width) ? '0%' : `${width - valueOffset}%`;
          const greaterThanZero = !nullWidth && width > 0;
          return (

{key}

                <div className={`results__bar-graph__bar ${(greaterThanZero ? 'active' : '')}`} style={{ height: 20, width: widthPercent, background: '#E5AB28', display: 'inline-block', verticalAlign: 'middle' }}>

                {(greaterThanZero ? {widthPercent} ({total}) : null)}

);
        })}

    );
  }
}

BarGraph.propTypes = {
  answers: PropTypes.array.isRequired
};
<|endoftext|>


<commit_before><commit_msg>tweaks to keyboard-based scrolling<commit_after><|endoftext|>


<commit_before>//= require ./thredded

(() => {
  const isTurbolinks = 'Turbolinks' in window && window.Turbolinks.supported;
  const isTurbolinks5 = isTurbolinks && 'clearCache' in window.Turbolinks;

  let onPageLoadFiredOnce = false;
  const pageLoadCallbacks = [];
  const triggerOnPageLoad = () => {
    pageLoadCallbacks.forEach((callback) => {
      callback();
    });
    onPageLoadFiredOnce = true;
  };

  // Fires the callback on DOMContentLoaded or a Turbolinks page load.
  // If called from an async script on the first page load, and the DOMContentLoad event
  // has already fired, will execute the callback immediately.
  window.Thredded.onPageLoad = (callback) => {
    pageLoadCallbacks.push(callback);
    // With async script loading, a callback may be added after the DOMContentLoaded event has already triggered.
    // This means we will receive neither a DOMContentLoaded event, nor a turbolinks:load event on Turbolinks 5.
    if (!onPageLoadFiredOnce && window.Thredded.DOMContentLoadedFired) {
      callback();
    }
  };

  if (isTurbolinks5) {
    document.addEventListener('turbolinks:load', () => {
      triggerOnPageLoad();
    });
  } else {
    // Turbolinks Classic (with or without jQuery.Turbolinks), or no Turbolinks:
    if (!window.Thredded.DOMContentLoadedFired) {
      document.addEventListener('DOMContentLoaded', () => {
        triggerOnPageLoad();
      });
    }
    if (isTurbolinks) {
      document.addEventListener('page:load', () => {
        triggerOnPageLoad();
      })
    }
  }
})();

<commit_msg>Support Turbolinks 5.0.1<commit_after>//= require ./thredded

(() => {
  const isTurbolinks = 'Turbolinks' in window && window.Turbolinks.supported;
  const isTurbolinks5 = isTurbolinks && 'clearCache' in window.Turbolinks;

  let onPageLoadFiredOnce = false;
  const pageLoadCallbacks = [];
  const triggerOnPageLoad = () => {
    pageLoadCallbacks.forEach((callback) => {
      callback();
    });
    onPageLoadFiredOnce = true;
  };

  // Fires the callback on DOMContentLoaded or a Turbolinks page load.
  // If called from an async script on the first page load, and the DOMContentLoad event
  // has already fired, will execute the callback immediately.
  window.Thredded.onPageLoad = (callback) => {
    pageLoadCallbacks.push(callback);
    // With async script loading, a callback may be added after the DOMContentLoaded event has already triggered.
    // This means we will receive neither a DOMContentLoaded event, nor a turbolinks:load event on Turbolinks 5.
    if (!onPageLoadFiredOnce && window.Thredded.DOMContentLoadedFired) {
      callback();
    }
  };

  if (isTurbolinks5) {
    // In Turbolinks 5.0.1, turbolinks:load may have already fired (before DOMContentLoaded).
    // If so, add our own DOMContentLoaded listener:
    // See: https://github.com/turbolinks/turbolinks/commit/69d353ea73d10ee6b25c2866fc5706879ba403e3
    if (window.Turbolinks.controller.lastRenderedLocation) {
      document.addEventListener('DOMContentLoaded', () => {
        triggerOnPageLoad();
      });
    }
    document.addEventListener('turbolinks:load', () => {
      triggerOnPageLoad();
    });
  } else {
    // Turbolinks Classic (with or without jQuery.Turbolinks), or no Turbolinks:
    if (!window.Thredded.DOMContentLoadedFired) {
      document.addEventListener('DOMContentLoaded', () => {
        triggerOnPageLoad();
      });
    }
    if (isTurbolinks) {
      document.addEventListener('page:load', () => {
        triggerOnPageLoad();
      })
    }
  }
})();

<|endoftext|>


<commit_before>var _1 = {
  color: 'rgb(200,200,100)'
};

var PARAMS = Object.freeze({
  COLLECTION_TIME: 2000,
  MOVE_THRESHOLD: 200
});

document.addEventListener("DOMContentLoaded", function(event) {

  var ctx = document.getElementById('fleet-display').getContext('2d');

  document.getElementById('button-progress').addEventListener('click', function(){
    startGeneration();
  });

  // One half of the basic invader, 6x8.
  // Invaders are symmetrical to a vertical axis, making the final size 11x8 pixels.
  var baseInvader = [
    [0,0,_1,0,0,0],
    [0,0,0,_1,0,0],
    [0,0,_1,_1,_1,_1],
    [0,_1,_1,0,_1,_1],
    [_1,_1,_1,_1,_1,_1],
    [_1,0,_1,_1,_1,_1],
    [_1,0,_1,0,0,0],
    [0,0,0,_1,_1,0],
  ];

  function startGeneration() {
    collectInput(function(inputs){
      var invader = generate(inputs);
      display(invader);
    });
  }

  function collectInput(callback){
    //NB: input seed array's length should equal no. of mutators!
    var inputSeed = [{}];

    var inputArea = document.getElementById('input-area');
    var moveCount = 0;
    var moveCounter = function(){
      moveCount++;
    };

    inputArea.addEventListener('mousemove', moveCounter);

    setTimeout(function(){
      inputArea.removeEventListener('mousemove', moveCounter);
      inputSeed[0].moveCount = moveCount;
      callback(inputSeed);
    }, PARAMS.COLLECTION_TIME);
  }

  function generate(inputSeed){
    return mutateInvader(baseInvader, inputSeed);
  }

  function display(invader){
    drawInvader(ctx,0,0,invader);
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs){
  var invader = deepCopy(base);
  mutators = [antennaMutator/*, weaponMutator, thrusterMutator*/];
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function antennaMutator(invader, input){
  var basePixel = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [basePixel,0,0],
    [0,basePixel,0],
    [basePixel,basePixel,basePixel]
  ];
  //TODO mutate based on input
  return applyPart(invader, part, 2, 0);
}

function getColorString(moveCount){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount);
  //greyscale for now TODO: colorize with RGB bias param?
  return 'rgb('+n+','+n+','+n+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      invader[y+i][x+j] = part[i][j];
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  var pixelSize = 10;
  context.fillStyle = 'rgb(200,200,200)';

  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(x0+x*pixelSize,y0+y*pixelSize,pixelSize,pixelSize);
      }
    }
  }
}<commit_msg>extend mutator list and add collection interval for each mutator<commit_after>var _1 = {
  color: 'rgb(200,200,100)'
};

var PARAMS = Object.freeze({
  COLLECTION_TIME: 1000,
  MOVE_THRESHOLD: 200
});

document.addEventListener("DOMContentLoaded", function(event) {

  var ctx = document.getElementById('fleet-display').getContext('2d');

  document.getElementById('button-progress').addEventListener('click', function(){
    startGeneration();
  });

  // One half of the basic invader, 6x8.
  // Invaders are symmetrical to a vertical axis, making the final size 11x8 pixels.
  var baseInvader = [
    [0,0,_1,0,0,0],
    [0,0,0,_1,0,0],
    [0,0,_1,_1,_1,_1],
    [0,_1,_1,0,_1,_1],
    [_1,_1,_1,_1,_1,_1],
    [_1,0,_1,_1,_1,_1],
    [_1,0,_1,0,0,0],
    [0,0,0,_1,_1,0],
  ];

  //NB: hullMutator should come before antennaMutator, because they overlap
  var mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];

  function startGeneration() {
    collectInput(function(inputs){
      var invader = mutateInvader(baseInvader, inputs, mutators);
      display(invader);
    });
  }

  function collectInput(callback){
    var inputArea = document.getElementById('input-area');
    var inputSeed = [];
    var moveCount = 0;
    var moveCounter = function(){
      moveCount++;
    };

    inputArea.addEventListener('mousemove', moveCounter);

    //Dispatch a timeout for each mutator, with increasing delays. Mouse moves are
    // collected between the callbacks, creating the input seed for each mutator.
    mutators.forEach(function(_, i){
      setTimeout(function(){
        inputSeed.push({ moveCount: moveCount });
        moveCount = 0;
        if(i===mutators.length-1){
          inputArea.removeEventListener('mousemove', moveCounter);
          callback(inputSeed);
        }
      }, PARAMS.COLLECTION_TIME*i+1);
    });
  }

  //TODO: extend this function to display rows (the whole fleet)
  function display(invader){
    drawInvader(ctx,0,0,invader);
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs, mutators){
  var invader = deepCopy(base);
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function antennaMutator(invader, input){
  var basePixel = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [basePixel,0,0],
    [0,basePixel,0],
    [basePixel,basePixel,basePixel]
  ];
  return applyPart(invader, part, 2, 0);
}

function weaponMutator(invader, input){
  var basePixel = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,basePixel],
    [basePixel,basePixel],
    [basePixel,0],
    [basePixel,0]
  ];
  return applyPart(invader, part, 0, 3);
}

function thrusterMutator(invader, input){
  var basePixel = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [basePixel,0,0,0],
    [0,basePixel,basePixel,0]
  ];
  return applyPart(invader, part, 2, 6);
}

function hullMutator(invader, input){
  var basePixel = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,0,0,basePixel], // first three overlaps with antenna
    [basePixel,0,basePixel,basePixel], //2nd empty for "eye"
    [basePixel,basePixel,basePixel,basePixel],
    [basePixel,basePixel,basePixel,basePixel]
  ];
  return applyPart(invader, part, 2, 2);
}

function getColorString(moveCount){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount);
  //greyscale for now TODO: colorize with RGB bias param?
  return 'rgb('+n+','+n+','+n+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      invader[y+i][x+j] = part[i][j];
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  var pixelSize = 10;
  context.fillStyle = 'rgb(200,200,200)';

  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(x0+x*pixelSize,y0+y*pixelSize,pixelSize,pixelSize);
      }
    }
  }
}<|endoftext|>


<commit_before>var PARAMS = Object.freeze({
  COLLECTION_TIME: 1000,
  MAX_COLOR_BIAS: 3,
  MOVE_THRESHOLD: 200,
  MOVE_THRESHOLD_SMALL: 50,
  MOVE_ADJUSTMENT_MULTIPLIER: 2,
  INPUT_WIDTH: 300,
  INPUT_HEIGHT: 250,
  CANVAS_WIDTH: 500,
  CANVAS_HEIGHT: 300,
  PIXEL_SIZE: 10
});

document.addEventListener('DOMContentLoaded', function(){

  var ctx = document.getElementById('fleet-display').getContext('2d');
  var progressButton = document.getElementById('button-progress');
  var clickHandler = function(){ startGeneration(); };
  progressButton.addEventListener('click', clickHandler);

  // Only one half, a 6x8 grid is stored for an invader, because they are
  // symmetrical to the vertical axis (making their final size 11x8 pixels).
  // The half of the "standard" space invader looks like this:
  //[0,0,1,0,0,0],
  //[0,0,0,1,0,0],
  //[0,0,1,1,1,1],
  //[0,1,1,0,1,1],
  //[1,1,1,1,1,1],
  //[1,0,1,1,1,1],
  //[1,0,1,0,0,0],
  //[0,0,0,1,1,0],
  //but it's not necessary to store this, because the mutators recreate it if there's no mouse input

  var baseInvader = [
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
  ];

  var mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];

  function startGeneration() {
    collectInput(function(inputs){
      var invader = mutateInvader(baseInvader, inputs, mutators);
      display(invader);
    });
  }

  function collectInput(callback){
    var inputArea = document.getElementById('input-area');
    var inputWidth = inputArea.getBoundingClientRect().width; //NB this includes borders
    var inputHeight = inputArea.getBoundingClientRect().height;
    var inputSeed = [];
    var moveCount = 0;
    var firstMove;
    var lastMove;
    var moveCounter = function(event){
      moveCount++;
      var X = event.clientX - this.getBoundingClientRect().left;
      var Y = event.clientY - this.getBoundingClientRect().top;
      if(firstMove){
        lastMove = {x: X, y: Y};
      } else {
        firstMove = {x: X, y: Y};
      }
    };

    inputArea.addEventListener('mousemove', moveCounter);

    progressButton.removeEventListener('click', clickHandler);
    progressButton.innerHTML = 'Generating fleet... (0/'+mutators.length+')';

    //Dispatch a timeout for each mutator, with increasing delays. Mouse moves are
    // collected between the callbacks, creating the input seed for each mutator.
    mutators.forEach(function(_, i){
      setTimeout(function(){
        progressButton.innerHTML = 'Generating fleet... ('+(i+1)+'/'+mutators.length+')';
        inputSeed.push({
          moveCount: moveCount,
          firstMove: firstMove,
          lastMove: lastMove
        });
        moveCount = 0;
        firstMove = undefined;
        lastMove = undefined;
        if(i===mutators.length-1){
          inputArea.removeEventListener('mousemove', moveCounter);
          callback(inputSeed);
          progressButton.innerHTML = 'Fleet generated. (Click to restart)';
          progressButton.addEventListener('click', clickHandler);
        }
      }, PARAMS.COLLECTION_TIME*(i+1));
    });

  }

  //TODO: extend this function to display rows (the whole fleet)
  function display(invader){
    drawInvader(ctx,0,0,invader);
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs, mutators){
  var invader = deepCopy(base);
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function hullMutator(invader, input){
  var p = { //base pixel
    color: getColorString(input.moveCount)
  };
  var s = deepCopy(p); //secondary pixel
  if(input.firstMove && input.lastMove){
    var x0 = input.firstMove.x;
    var y0 = input.firstMove.y;
    var x1 = input.lastMove.x;
    var y1 = input.lastMove.y;
    if(Math.abs(x0-x1)<100 && Math.abs(y0-y1)<100){
      s.color = getColorString(input.moveCount, 0.8, 0.8, 1)
    }
  }
  var e = 0; //eye pixel
  if(input.firstMove && input.lastMove){
    //only color eyes if movement was downwards - should be rare due to layout
    if(input.firstMove.y < input.lastMove.y ){
      e = {
        color: input.firstMove.x < input.lastMove.x? 'rgb(200,15,15)' : 'rgb(50,175,20)'
      };
    }
  }
  var part = [
    [0,0,0,s], // antenna will overwrite first 3 anyway
    [s,e,s,p],
    [p,s,p,s],
    [s,p,s,p]
  ];
  return applyPart(invader, part, 2, 2);
}

function antennaMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.firstMove && input.lastMove){
    biasR = input.firstMove.x/PARAMS.INPUT_WIDTH;
    biasG = input.firstMove.y/PARAMS.INPUT_HEIGHT;
    biasB = input.lastMove.x/PARAMS.INPUT_WIDTH;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [p,0,0,0],
    [0,p,0,0],
    [p,p,p,null]
  ];
  var antenna = [[]];
  //tilt antennae based on movement direction:
  if(input.firstMove && input.lastMove){
    var antenna;
    if( Math.abs(input.firstMove.x-input.lastMove.x)<100 ){
      antenna = [
        [0,p],
        [0,p]
      ];
    } else if (input.firstMove.x < input.lastMove.x){
      antenna = [
        [0,0,p],
        [0,p,0]
      ];
    }
  }
  part = applyPart(part, antenna, 0, 0);
  return applyPart(invader, part, 2, 0);
}

function weaponMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p],
    [p,0],
    [p,0],
    [0,0]
  ];
  var weapon = [
    [0,0],
    [0,0],
    [0,0],
    [0,0],
    [0,0]
  ];
  if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
    weapon = [];
    var binArray = input.moveCount.toString(2).split('');
    //normalize and replace 1s with base pixel
    binArray = binArray.map(function(el){
      return el==='1'? p: 0;
    });
    while(binArray.length > 0) {
      weapon.push(binArray.splice(0,2));
    }
  }
  part = applyPart(part, weapon, 0, 0);
  return applyPart(invader, part, 0, 0);
}

function thrusterMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.lastMove){
    var biasR = Math.min(PARAMS.MAX_COLOR_BIAS/2, input.lastMove.x/input.lastMove.y);
    var biasG = input.lastMove.x > input.lastMove.y? 1: 0;
    var biasB = (input.lastMove.x<20 && input.lastMove.y<20)? 0: 1;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [0,0,0,0],
    [0,0,0,0]
  ];
  var thrusters = [
    [p,0,0],
    [0,p,p]
  ];
  if(input.firstMove && input.lastMove){
    if(input.moveCount%3 === 1){
      thrusters = [
        [p,p,p,p],
        [p,0,0,p]
      ];
    } else if(input.moveCount%3 === 2){
      thrusters = [
        [p,p,0,0],
        [0,0,0,0]
      ];
    } else if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
      thrusters = [
        [p,0,p,0],
        [0,p,0,p]
      ]
    }
  }
  part = applyPart(part, thrusters, 0, 0);
  return applyPart(invader, part, 2, 6);
}

function getColorString(moveCount, biasR, biasG, biasB){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount*PARAMS.MOVE_ADJUSTMENT_MULTIPLIER);
  var R = 1;
  var G = 1;
  var B = 1;
  if(biasR) R=biasR;
  if(biasG) G=biasG;
  if(biasB) B=biasB;
  //NB: non-integer values are not valid here!
  return 'rgb('+Math.floor(n*R)+','+Math.floor(n*G)+','+Math.floor(n*B)+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      if(part[i][j] != null){ // null signals ignore, 0 signals overwrite with empty
        invader[y+i][x+j] = part[i][j];
      }
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  context.clearRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);

  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(
          x0+x*PARAMS.PIXEL_SIZE,
          y0+y*PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE
        );
      }
    }
  }
}<commit_msg>fix weapon mutator default to output standard invader<commit_after>var PARAMS = Object.freeze({
  COLLECTION_TIME: 1000,
  MAX_COLOR_BIAS: 3,
  MOVE_THRESHOLD: 200,
  MOVE_THRESHOLD_SMALL: 50,
  MOVE_ADJUSTMENT_MULTIPLIER: 2,
  INPUT_WIDTH: 300,
  INPUT_HEIGHT: 250,
  CANVAS_WIDTH: 500,
  CANVAS_HEIGHT: 300,
  PIXEL_SIZE: 10
});

document.addEventListener('DOMContentLoaded', function(){

  var ctx = document.getElementById('fleet-display').getContext('2d');
  var progressButton = document.getElementById('button-progress');
  var clickHandler = function(){ startGeneration(); };
  progressButton.addEventListener('click', clickHandler);

  // Only one half, a 6x8 grid is stored for an invader, because they are
  // symmetrical to the vertical axis (making their final size 11x8 pixels).
  // The half of the "standard" space invader looks like this:
  //[0,0,1,0,0,0],
  //[0,0,0,1,0,0],
  //[0,0,1,1,1,1],
  //[0,1,1,0,1,1],
  //[1,1,1,1,1,1],
  //[1,0,1,1,1,1],
  //[1,0,1,0,0,0],
  //[0,0,0,1,1,0],
  //but it's not necessary to store this, because the mutators recreate it if there's no mouse input

  var baseInvader = [
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
  ];

  var mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];

  function startGeneration() {
    collectInput(function(inputs){
      var invader = mutateInvader(baseInvader, inputs, mutators);
      display(invader);
    });
  }

  function collectInput(callback){
    var inputArea = document.getElementById('input-area');
    var inputWidth = inputArea.getBoundingClientRect().width; //NB this includes borders
    var inputHeight = inputArea.getBoundingClientRect().height;
    var inputSeed = [];
    var moveCount = 0;
    var firstMove;
    var lastMove;
    var moveCounter = function(event){
      moveCount++;
      var X = event.clientX - this.getBoundingClientRect().left;
      var Y = event.clientY - this.getBoundingClientRect().top;
      if(firstMove){
        lastMove = {x: X, y: Y};
      } else {
        firstMove = {x: X, y: Y};
      }
    };

    inputArea.addEventListener('mousemove', moveCounter);

    progressButton.removeEventListener('click', clickHandler);
    progressButton.innerHTML = 'Generating fleet... (0/'+mutators.length+')';

    //Dispatch a timeout for each mutator, with increasing delays. Mouse moves are
    // collected between the callbacks, creating the input seed for each mutator.
    mutators.forEach(function(_, i){
      setTimeout(function(){
        progressButton.innerHTML = 'Generating fleet... ('+(i+1)+'/'+mutators.length+')';
        inputSeed.push({
          moveCount: moveCount,
          firstMove: firstMove,
          lastMove: lastMove
        });
        moveCount = 0;
        firstMove = undefined;
        lastMove = undefined;
        if(i===mutators.length-1){
          inputArea.removeEventListener('mousemove', moveCounter);
          callback(inputSeed);
          progressButton.innerHTML = 'Fleet generated. (Click to restart)';
          progressButton.addEventListener('click', clickHandler);
        }
      }, PARAMS.COLLECTION_TIME*(i+1));
    });

  }

  //TODO: extend this function to display rows (the whole fleet)
  function display(invader){
    drawInvader(ctx,0,0,invader);
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs, mutators){
  var invader = deepCopy(base);
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function hullMutator(invader, input){
  var p = { //base pixel
    color: getColorString(input.moveCount)
  };
  var s = deepCopy(p); //secondary pixel
  if(input.firstMove && input.lastMove){
    var x0 = input.firstMove.x;
    var y0 = input.firstMove.y;
    var x1 = input.lastMove.x;
    var y1 = input.lastMove.y;
    if(Math.abs(x0-x1)<100 && Math.abs(y0-y1)<100){
      s.color = getColorString(input.moveCount, 0.8, 0.8, 1)
    }
  }
  var e = 0; //eye pixel
  if(input.firstMove && input.lastMove){
    //only color eyes if movement was downwards - should be rare due to layout
    if(input.firstMove.y < input.lastMove.y ){
      e = {
        color: input.firstMove.x < input.lastMove.x? 'rgb(200,15,15)' : 'rgb(50,175,20)'
      };
    }
  }
  var part = [
    [0,0,0,s], // antenna will overwrite first 3 anyway
    [s,e,s,p],
    [p,s,p,s],
    [s,p,s,p]
  ];
  return applyPart(invader, part, 2, 2);
}

function antennaMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.firstMove && input.lastMove){
    biasR = input.firstMove.x/PARAMS.INPUT_WIDTH;
    biasG = input.firstMove.y/PARAMS.INPUT_HEIGHT;
    biasB = input.lastMove.x/PARAMS.INPUT_WIDTH;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [p,0,0,0],
    [0,p,0,0],
    [p,p,p,null]
  ];
  var antenna = [[]];
  //tilt antennae based on movement direction:
  if(input.firstMove && input.lastMove){
    var antenna;
    if( Math.abs(input.firstMove.x-input.lastMove.x)<100 ){
      antenna = [
        [0,p],
        [0,p]
      ];
    } else if (input.firstMove.x < input.lastMove.x){
      antenna = [
        [0,0,p],
        [0,p,0]
      ];
    }
  }
  part = applyPart(part, antenna, 0, 0);
  return applyPart(invader, part, 2, 0);
}

function weaponMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p],
    [p,0],
    [p,0],
    [0,0]
  ];
  var weapon = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p]
  ];
  if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
    weapon = [];
    var binArray = input.moveCount.toString(2).split('');
    //normalize and replace 1s with base pixel
    binArray = binArray.map(function(el){
      return el==='1'? p: 0;
    });
    while(binArray.length > 0) {
      weapon.push(binArray.splice(0,2));
    }
  }
  part = applyPart(part, weapon, 0, 0);
  return applyPart(invader, part, 0, 0);
}

function thrusterMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.lastMove){
    var biasR = Math.min(PARAMS.MAX_COLOR_BIAS/2, input.lastMove.x/input.lastMove.y);
    var biasG = input.lastMove.x > input.lastMove.y? 1: 0;
    var biasB = (input.lastMove.x<20 && input.lastMove.y<20)? 0: 1;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [0,0,0,0],
    [0,0,0,0]
  ];
  var thrusters = [
    [p,0,0],
    [0,p,p]
  ];
  if(input.firstMove && input.lastMove){
    if(input.moveCount%3 === 1){
      thrusters = [
        [p,p,p,p],
        [p,0,0,p]
      ];
    } else if(input.moveCount%3 === 2){
      thrusters = [
        [p,p,0,0],
        [0,0,0,0]
      ];
    } else if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
      thrusters = [
        [p,0,p,0],
        [0,p,0,p]
      ]
    }
  }
  part = applyPart(part, thrusters, 0, 0);
  return applyPart(invader, part, 2, 6);
}

function getColorString(moveCount, biasR, biasG, biasB){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount*PARAMS.MOVE_ADJUSTMENT_MULTIPLIER);
  var R = 1;
  var G = 1;
  var B = 1;
  if(biasR) R=biasR;
  if(biasG) G=biasG;
  if(biasB) B=biasB;
  //NB: non-integer values are not valid here!
  return 'rgb('+Math.floor(n*R)+','+Math.floor(n*G)+','+Math.floor(n*B)+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      if(part[i][j] != null){ // null signals ignore, 0 signals overwrite with empty
        invader[y+i][x+j] = part[i][j];
      }
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  context.clearRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);

  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(
          x0+x*PARAMS.PIXEL_SIZE,
          y0+y*PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE
        );
      }
    }
  }
}<|endoftext|>


<commit_before>var PARAMS = Object.freeze({
  COLLECTION_TIME: 1000,
  MAX_COLOR_BIAS: 3,
  MOVE_THRESHOLD: 200,
  MOVE_THRESHOLD_SMALL: 50,
  MOVE_ADJUSTMENT_MULTIPLIER: 2,
  INPUT_WIDTH: 300,
  INPUT_HEIGHT: 250,
  CANVAS_WIDTH: 500,
  CANVAS_HEIGHT: 300,
  PIXEL_SIZE: 10
});

document.addEventListener('DOMContentLoaded', function(){

  var ctx = document.getElementById('fleet-display').getContext('2d');
  var progressButton = document.getElementById('button-progress');
  var clickHandler = function(){ startGeneration(); };
  progressButton.addEventListener('click', clickHandler);

  // Only one half, a 6x8 grid is stored for an invader, because they are
  // symmetrical to the vertical axis (making their final size 11x8 pixels).
  // The half of the "standard" space invader looks like this:
  //[0,0,1,0,0,0],
  //[0,0,0,1,0,0],
  //[0,0,1,1,1,1],
  //[0,1,1,0,1,1],
  //[1,1,1,1,1,1],
  //[1,0,1,1,1,1],
  //[1,0,1,0,0,0],
  //[0,0,0,1,1,0],
  //but it's not necessary to store this, because the mutators recreate it if there's no mouse input

  var baseInvader = [
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
  ];

  var mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];

  function startGeneration() {
    collectInput(function(inputs){
      var invader = mutateInvader(baseInvader, inputs, mutators);
      display(invader);
    });
  }

  function collectInput(callback){
    var inputArea = document.getElementById('input-area');
    var inputWidth = inputArea.getBoundingClientRect().width; //NB this includes borders
    var inputHeight = inputArea.getBoundingClientRect().height;
    var inputSeed = [];
    var moveCount = 0;
    var firstMove;
    var lastMove;
    var moveCounter = function(event){
      moveCount++;
      var X = event.clientX - this.getBoundingClientRect().left;
      var Y = event.clientY - this.getBoundingClientRect().top;
      if(firstMove){
        lastMove = {x: X, y: Y};
      } else {
        firstMove = {x: X, y: Y};
      }
    };

    inputArea.addEventListener('mousemove', moveCounter);

    progressButton.removeEventListener('click', clickHandler);
    progressButton.innerHTML = 'Generating fleet... (0/'+mutators.length+')';

    //Dispatch a timeout for each mutator, with increasing delays. Mouse moves are
    // collected between the callbacks, creating the input seed for each mutator.
    mutators.forEach(function(_, i){
      setTimeout(function(){
        progressButton.innerHTML = 'Generating fleet... ('+(i+1)+'/'+mutators.length+')';
        inputSeed.push({
          moveCount: moveCount,
          firstMove: firstMove,
          lastMove: lastMove
        });
        moveCount = 0;
        firstMove = undefined;
        lastMove = undefined;
        if(i===mutators.length-1){
          inputArea.removeEventListener('mousemove', moveCounter);
          callback(inputSeed);
          progressButton.innerHTML = 'Fleet generated. (Click to restart)';
          progressButton.addEventListener('click', clickHandler);
        }
      }, PARAMS.COLLECTION_TIME*(i+1));
    });

  }

  //TODO: extend this function to display rows (the whole fleet)
  function display(invader){
    drawInvader(ctx,0,0,invader);
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs, mutators){
  var invader = deepCopy(base);
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function hullMutator(invader, input){
  var p = { //base pixel
    color: getColorString(input.moveCount)
  };
  var s = deepCopy(p); //secondary pixel
  if(input.firstMove && input.lastMove){
    var x0 = input.firstMove.x;
    var y0 = input.firstMove.y;
    var x1 = input.lastMove.x;
    var y1 = input.lastMove.y;
    if(Math.abs(x0-x1)<100 && Math.abs(y0-y1)<100){
      s.color = getColorString(input.moveCount, 0.8, 0.8, 1)
    }
  }
  var e = 0; //eye pixel
  if(input.firstMove && input.lastMove){
    //only color eyes if movement was downwards - should be rare due to layout
    if(input.firstMove.y < input.lastMove.y ){
      e = {
        color: input.firstMove.x < input.lastMove.x? 'rgb(200,15,15)' : 'rgb(50,175,20)'
      };
    }
  }
  var part = [
    [0,0,0,s], // antenna will overwrite first 3 anyway
    [s,e,s,p],
    [p,s,p,s],
    [s,p,s,p]
  ];
  return applyPart(invader, part, 2, 2);
}

function antennaMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.firstMove && input.lastMove){
    biasR = input.firstMove.x/PARAMS.INPUT_WIDTH;
    biasG = input.firstMove.y/PARAMS.INPUT_HEIGHT;
    biasB = input.lastMove.x/PARAMS.INPUT_WIDTH;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [p,0,0,0],
    [0,p,0,0],
    [p,p,p,null]
  ];
  var antenna = [[]];
  //tilt antennae based on movement direction:
  if(input.firstMove && input.lastMove){
    var antenna;
    if( Math.abs(input.firstMove.x-input.lastMove.x)<100 ){
      antenna = [
        [0,p],
        [0,p]
      ];
    } else if (input.firstMove.x < input.lastMove.x){
      antenna = [
        [0,0,p],
        [0,p,0]
      ];
    }
  }
  part = applyPart(part, antenna, 0, 0);
  return applyPart(invader, part, 2, 0);
}

function weaponMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p],
    [p,0],
    [p,0],
    [0,0]
  ];
  var weapon = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p]
  ];
  if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
    weapon = [];
    var binArray = input.moveCount.toString(2).split('');
    //normalize and replace 1s with base pixel
    binArray = binArray.map(function(el){
      return el==='1'? p: 0;
    });
    while(binArray.length > 0) {
      weapon.push(binArray.splice(0,2));
    }
  }
  part = applyPart(part, weapon, 0, 0);
  return applyPart(invader, part, 0, 0);
}

function thrusterMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.lastMove){
    var biasR = Math.min(PARAMS.MAX_COLOR_BIAS/2, input.lastMove.x/input.lastMove.y);
    var biasG = input.lastMove.x > input.lastMove.y? 1: 0;
    var biasB = (input.lastMove.x<20 && input.lastMove.y<20)? 0: 1;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [0,0,0,0],
    [0,0,0,0]
  ];
  var thrusters = [
    [p,0,0],
    [0,p,p]
  ];
  if(input.firstMove && input.lastMove){
    if(input.moveCount%3 === 1){
      thrusters = [
        [p,p,p,p],
        [p,0,0,p]
      ];
    } else if(input.moveCount%3 === 2){
      thrusters = [
        [p,p,0,0],
        [0,0,0,0]
      ];
    } else if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
      thrusters = [
        [p,0,p,0],
        [0,p,0,p]
      ]
    }
  }
  part = applyPart(part, thrusters, 0, 0);
  return applyPart(invader, part, 2, 6);
}

function getColorString(moveCount, biasR, biasG, biasB){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount*PARAMS.MOVE_ADJUSTMENT_MULTIPLIER);
  var R = 1;
  var G = 1;
  var B = 1;
  if(biasR) R=biasR;
  if(biasG) G=biasG;
  if(biasB) B=biasB;
  //NB: non-integer values are not valid here!
  return 'rgb('+Math.floor(n*R)+','+Math.floor(n*G)+','+Math.floor(n*B)+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      if(part[i][j] != null){ // null signals ignore, 0 signals overwrite with empty
        invader[y+i][x+j] = part[i][j];
      }
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  context.clearRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);

  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(
          x0+x*PARAMS.PIXEL_SIZE,
          y0+y*PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE
        );
      }
    }
  }
}<commit_msg>add random mutator<commit_after>var PARAMS = Object.freeze({
  COLLECTION_TIME: 1000,
  MAX_COLOR_BIAS: 3,
  MOVE_THRESHOLD: 200,
  MOVE_THRESHOLD_SMALL: 50,
  MOVE_ADJUSTMENT_MULTIPLIER: 2,
  INPUT_WIDTH: 300,
  INPUT_HEIGHT: 250,
  CANVAS_WIDTH: 500,
  CANVAS_HEIGHT: 300,
  PIXEL_SIZE: 10
});

document.addEventListener('DOMContentLoaded', function(){

  var ctx = document.getElementById('fleet-display').getContext('2d');
  var progressButton = document.getElementById('button-progress');
  var clickHandler = function(){ startGeneration(); };
  progressButton.addEventListener('click', clickHandler);

  // Only one half, a 6x8 grid is stored for an invader, because they are
  // symmetrical to the vertical axis (making their final size 11x8 pixels).
  // The half of the "standard" space invader looks like this:
  //[0,0,1,0,0,0],
  //[0,0,0,1,0,0],
  //[0,0,1,1,1,1],
  //[0,1,1,0,1,1],
  //[1,1,1,1,1,1],
  //[1,0,1,1,1,1],
  //[1,0,1,0,0,0],
  //[0,0,0,1,1,0],
  //but it's not necessary to store this, because the mutators recreate it if there's no mouse input

  var baseInvader = [
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
  ];

  var mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];

  function resetMutators(){
    mutators = [hullMutator, antennaMutator, weaponMutator, thrusterMutator];
  }

  function startGeneration() {
    collectInput(function(inputs){
      // --- add a special random mutator, without a dedicated collection interval
      // it gets the same input as the first mutator
      mutators.push(randomMutator);
      inputs.push(inputs[0]);
      // ----
      var invader = mutateInvader(baseInvader, inputs, mutators);
      display(invader);
    });
  }

  function collectInput(callback){
    var inputArea = document.getElementById('input-area');
    var inputWidth = inputArea.getBoundingClientRect().width; //NB this includes borders
    var inputHeight = inputArea.getBoundingClientRect().height;
    var inputSeed = [];
    var moveCount = 0;
    var firstMove;
    var lastMove;
    var moveCounter = function(event){
      moveCount++;
      var X = event.clientX - this.getBoundingClientRect().left;
      var Y = event.clientY - this.getBoundingClientRect().top;
      if(firstMove){
        lastMove = {x: X, y: Y};
      } else {
        firstMove = {x: X, y: Y};
      }
    };

    inputArea.addEventListener('mousemove', moveCounter);

    progressButton.removeEventListener('click', clickHandler);
    progressButton.innerHTML = 'Generating fleet... (0/'+mutators.length+')';

    //Dispatch a timeout for each mutator, with increasing delays. Mouse moves are
    // collected between the callbacks, creating the input seed for each mutator.
    mutators.forEach(function(_, i){
      setTimeout(function(){
        progressButton.innerHTML = 'Generating fleet... ('+(i+1)+'/'+mutators.length+')';
        inputSeed.push({
          moveCount: moveCount,
          firstMove: firstMove,
          lastMove: lastMove
        });
        moveCount = 0;
        firstMove = undefined;
        lastMove = undefined;
        if(i===mutators.length-1){
          inputArea.removeEventListener('mousemove', moveCounter);
          callback(inputSeed);
          progressButton.innerHTML = 'Fleet generated. (Click to restart)';
          resetMutators();
          progressButton.addEventListener('click', clickHandler);
        }
      }, PARAMS.COLLECTION_TIME*(i+1));
    });

  }

  //TODO: extend this function to display rows (the whole fleet)
  function display(invader){
    drawInvader(ctx,0,0,invader);
  }

});

function deepCopy(obj){
  return JSON.parse(JSON.stringify(obj));
}

function mutateInvader(base, inputs, mutators){
  var invader = deepCopy(base);
  mutators.forEach(function(mutator, i){
    invader = mutator(invader, inputs[i]);
  });
  return invader;
}

function hullMutator(invader, input){
  var p = { //base pixel
    color: getColorString(input.moveCount)
  };
  var s = deepCopy(p); //secondary pixel
  if(input.firstMove && input.lastMove){
    var x0 = input.firstMove.x;
    var y0 = input.firstMove.y;
    var x1 = input.lastMove.x;
    var y1 = input.lastMove.y;
    if(Math.abs(x0-x1)<100 && Math.abs(y0-y1)<100){
      s.color = getColorString(input.moveCount, 0.8, 0.8, 1)
    }
  }
  var e = 0; //eye pixel
  if(input.firstMove && input.lastMove){
    //only color eyes if movement was downwards - should be rare due to layout
    if(input.firstMove.y < input.lastMove.y ){
      e = {
        color: input.firstMove.x < input.lastMove.x? 'rgb(200,15,15)' : 'rgb(50,175,20)'
      };
    }
  }
  var part = [
    [0,0,0,s], // antenna will overwrite first 3 anyway
    [s,e,s,p],
    [p,s,p,s],
    [s,p,s,p]
  ];
  return applyPart(invader, part, 2, 2);
}

function antennaMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.firstMove && input.lastMove){
    biasR = input.firstMove.x/PARAMS.INPUT_WIDTH;
    biasG = input.firstMove.y/PARAMS.INPUT_HEIGHT;
    biasB = input.lastMove.x/PARAMS.INPUT_WIDTH;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [p,0,0,0],
    [0,p,0,0],
    [p,p,p,null]
  ];
  var antenna = [[]];
  //tilt antennae based on movement direction:
  if(input.firstMove && input.lastMove){
    var antenna;
    if( Math.abs(input.firstMove.x-input.lastMove.x)<100 ){
      antenna = [
        [0,p],
        [0,p]
      ];
    } else if (input.firstMove.x < input.lastMove.x){
      antenna = [
        [0,0,p],
        [0,p,0]
      ];
    }
  }
  part = applyPart(part, antenna, 0, 0);
  return applyPart(invader, part, 2, 0);
}

function weaponMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount)
  };
  var part = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p],
    [p,0],
    [p,0],
    [0,0]
  ];
  var weapon = [
    [0,0],
    [0,0],
    [0,0],
    [0,p],
    [p,p]
  ];
  if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
    weapon = [];
    var binArray = input.moveCount.toString(2).split('');
    //normalize and replace 1s with base pixel
    binArray = binArray.map(function(el){
      return el==='1'? p: 0;
    });
    while(binArray.length > 0) {
      weapon.push(binArray.splice(0,2));
    }
  }
  part = applyPart(part, weapon, 0, 0);
  return applyPart(invader, part, 0, 0);
}

function thrusterMutator(invader, input){
  var biasR = 1;
  var biasG = 1;
  var biasB = 1;
  if(input.lastMove){
    var biasR = Math.min(PARAMS.MAX_COLOR_BIAS/2, input.lastMove.x/input.lastMove.y);
    var biasG = input.lastMove.x > input.lastMove.y? 1: 0;
    var biasB = (input.lastMove.x<20 && input.lastMove.y<20)? 0: 1;
  }
  var p = {
    color: getColorString(input.moveCount, biasR, biasG, biasB)
  };
  var part = [
    [0,0,0,0],
    [0,0,0,0]
  ];
  var thrusters = [
    [p,0,0],
    [0,p,p]
  ];
  if(input.firstMove && input.lastMove){
    if(input.moveCount%3 === 1){
      thrusters = [
        [p,p,p,p],
        [p,0,0,p]
      ];
    } else if(input.moveCount%3 === 2){
      thrusters = [
        [p,p,0,0],
        [0,0,0,0]
      ];
    } else if(input.moveCount > PARAMS.MOVE_THRESHOLD_SMALL){
      thrusters = [
        [p,0,p,0],
        [0,p,0,p]
      ]
    }
  }
  part = applyPart(part, thrusters, 0, 0);
  return applyPart(invader, part, 2, 6);
}

function randomMutator(invader, input){
  var p = {
    color: getColorString(input.moveCount, 0.5, 0.5, 0.5)
  };
  var mutation = [
    [0,0],
    [0,0]
  ];
  if(input.moveCount){
    var _ = (input.moveCount%2)? 0 : null; //50% chance to clear
    switch(input.moveCount%5){
      case 0:
        mutation = [
          [_,p],
          [_,p]
        ];
        break;
      case 1:
        mutation = [
          [_,_],
          [p,p]
        ];
        break;
      case 2:
        mutation = [
          [p,_],
          [_,p]
        ];
        break;
      case 3:
        mutation = [
          [_,p],
          [p,_]
        ];
        break;
      case 4:
        mutation = [
          [_,p],
          [p,p]
        ];
        break;
    }
  }
  // +4 offset ensures that it does not clear anything from the standard invader
  // if there was no input (clears between antennae)
  // The min call ensures that we don't override cells outside of the invader boundary
  var x = Math.min( (input.moveCount+4) % invader[0].length, invader[0].length-mutation[0].length );
  var y = Math.min( (input.moveCount*101) % invader.length, invader.length-mutation.length);
  return applyPart(invader, mutation, x, y);
}

function getColorString(moveCount, biasR, biasG, biasB){
  var n = 256-Math.min(PARAMS.MOVE_THRESHOLD,moveCount*PARAMS.MOVE_ADJUSTMENT_MULTIPLIER);
  var R = 1;
  var G = 1;
  var B = 1;
  if(biasR) R=biasR;
  if(biasG) G=biasG;
  if(biasB) B=biasB;
  //NB: non-integer values are not valid here!
  return 'rgb('+Math.floor(n*R)+','+Math.floor(n*G)+','+Math.floor(n*B)+')';
}

function applyPart(base, part, x, y){
  var invader = deepCopy(base);
  for(var i=0;i<part.length;i++){
    for(var j=0;j<part[i].length;j++){
      if(part[i][j] != null){ // null signals ignore, 0 signals overwrite with empty
        invader[y+i][x+j] = part[i][j];
      }
    }
  }
  return invader;
}

function drawInvader(context, x0, y0, invader){
  context.clearRect(0,0,PARAMS.CANVAS_WIDTH,PARAMS.CANVAS_HEIGHT);

  for(var y=0;y<invader.length;y++){
    var len = invader[y].length;
    //we're mirroring every column but the last
    for(var x=0;x<len*2-1;x++){
      var xPos = x>=len? x-(x-len+1)*2 : x;
      if(invader[y][xPos]){
        context.fillStyle = invader[y][xPos].color;
        context.fillRect(
          x0+x*PARAMS.PIXEL_SIZE,
          y0+y*PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE,
          PARAMS.PIXEL_SIZE
        );
      }
    }
  }
}<|endoftext|>


<commit_before>import { Component } from 'react'
import h from 'react-hyperscript'
import {Link} from 'react-router-dom'
import styled from 'styled-components'
import { StageDisplayNames, Stage } from '../../../constants.js'

const ItemFrame = styled('div')`
  border:2px solid ${props => props.userActionRequired ? props.theme.yellow : props.theme.dark};
  padding: 0.5em 1em;
  margin: 0.2em 0;
  background-color:${props => props.theme.light};
  text-align:left;
`

const Box = styled('div')`
  display:inline-block;
  margin-right:3em;
`

const ConceptName = styled('div')`
  color:${props => props.theme.dark};
  font-size:1.8em;
`

const AssesseeAddress = styled('a')`
  color:${props => props.theme.dark};
  font-size:0.8em;
`

// Meeting Point

const MeetingBox = styled('div')`
  background-color:${props => props.theme.veryLight};
  padding: 0.5em 1em;
  display:inline-block;
`
const MeetingCaption = styled('div')`
  color:${props => props.theme.dark};
`
const MeetingAddress = styled('a')`
  color:${props => props.theme.blue};
  font-size:0.8em;
`

// assessee/assessor badges

const AssesseeBadge = styled('div')`
  background-color:${props => props.theme.lightblue};
  border-radius:0.3em;
  padding:0.1em 0.3em;
`
const AssessorBadge = styled('div')`
  background-color:orange;
  border-radius:0.3em;
  padding:0.1em 0.3em;
`

// link to action/assessmentView

const LinkBox = styled('div')`
  float: right;
  margin-right:1.2em;
`

const LinkUnstyled = styled(Link)`
  text-decoration:none;
`

const LinkButton = styled('div')`
  display:block;
  background-color:green;
  color:${props => props.theme.lightgrey};
  text-decoration:none;
  padding: ${(props) => props.stage === Stage.Done ? '0.5em' : '1em'} 1.5em;
  width:4em;
  text-align:center;
  border: ${(props) => props.userActionRequired ? '1px solid ' + props.theme.yellow : 'none'}
`

const LinkSubtitle = styled('div')`
  color:${props => props.theme.lightgrey};
  font-size:0.6em;
  text-align:center;
`

export class AssessmentItem extends Component {
  render () {
    const assessment = this.props.assessment
    let userStage = assessment.userStage
    let stage = assessment.stage

    // set assessee/assessor view
    let RoleBadge = h(AssessorBadge, 'Assessor')
    let isAssessee = ''
    if (this.props.userAddress === assessment.assessee) {
      RoleBadge = h(AssesseeBadge, 'Assessee')
      isAssessee = ' (you)'
    }
    if (stage === Stage.None) {
      RoleBadge = null
    }

    // set meeting point component
    let MeetingPoint = ' NoMeetingPointSet '
    if (assessment.data) {
      MeetingPoint = h(MeetingAddress, {
        href: assessment.data,
        target: '_blank'
      }, assessment.data)
    }

    // look if user is required to make an action
    let userActionRequired = true
    let actionText = StageDisplayNames[userStage]
    if (stage < userStage ||
      userStage === 0 ||
      userStage === 4 ||
      userStage === 5) {
      userActionRequired = false
    }
    if (stage < userStage) {
      actionText = 'Waiting...'
    }
    // if assessment stage is finished, set good message (an assessee would have userStage===0)
    if (stage === Stage.Done) {
      // display score for assessee and payout for assessor
      if (!isAssessee) {
        actionText = h('div', [
          h('div', 'Payout :'),
          h('div', '+5 AHA')
        ])
      } else {
        actionText = h('div', [
          h('div', 'Score :'),
          h('div', assessment.finalScore + ' %')
        ])
      }
    }
    if (stage === Stage.Burned) {
      actionText = 'Canceled'
    }
    return (
      h(ItemFrame, {userActionRequired}, [
        h(Box, [
          h(ConceptName, assessment.conceptData),
          h(AssesseeAddress, {
            href: 'https://' + (this.props.networkID === 4 ? 'rinkeby.' : '') + 'etherscan.io/address/' + assessment.assessee,
            target: '_blank',
            title: 'est'
          }, 'assessee: ' + assessment.assessee.substring(0, 8) + '...' + assessment.assessee.substring(30, 42) + isAssessee)
        ]),
        h(Box, [
          RoleBadge
        ]),
        h(MeetingBox, [
          h(MeetingCaption, 'Meet Assessee at:'),
          MeetingPoint
        ]
        ),
        h(LinkBox, [
          h(LinkSubtitle, 'click here for details'),
          h(LinkUnstyled, { to: 'assessment/' + assessment.address },
            h(LinkButton, { userActionRequired, stage },
              actionText
            )
          )
        ])
      ])
    )
  }
}

export default AssessmentItem
<commit_msg>renamed meeting caption<commit_after>import { Component } from 'react'
import h from 'react-hyperscript'
import {Link} from 'react-router-dom'
import styled from 'styled-components'
import { StageDisplayNames, Stage } from '../../../constants.js'

const ItemFrame = styled('div')`
  border:2px solid ${props => props.userActionRequired ? props.theme.yellow : props.theme.dark};
  padding: 0.5em 1em;
  margin: 0.2em 0;
  background-color:${props => props.theme.light};
  text-align:left;
`

const Box = styled('div')`
  display:inline-block;
  margin-right:3em;
`

const ConceptName = styled('div')`
  color:${props => props.theme.dark};
  font-size:1.8em;
`

const AssesseeAddress = styled('a')`
  color:${props => props.theme.dark};
  font-size:0.8em;
`

// Meeting Point

const MeetingBox = styled('div')`
  background-color:${props => props.theme.veryLight};
  padding: 0.5em 1em;
  display:inline-block;
`
const MeetingCaption = styled('div')`
  color:${props => props.theme.dark};
`
const MeetingAddress = styled('a')`
  color:${props => props.theme.blue};
  font-size:0.8em;
`

// assessee/assessor badges

const AssesseeBadge = styled('div')`
  background-color:${props => props.theme.lightblue};
  border-radius:0.3em;
  padding:0.1em 0.3em;
`
const AssessorBadge = styled('div')`
  background-color:orange;
  border-radius:0.3em;
  padding:0.1em 0.3em;
`

// link to action/assessmentView

const LinkBox = styled('div')`
  float: right;
  margin-right:1.2em;
`

const LinkUnstyled = styled(Link)`
  text-decoration:none;
`

const LinkButton = styled('div')`
  display:block;
  background-color:green;
  color:${props => props.theme.lightgrey};
  text-decoration:none;
  padding: ${(props) => props.stage === Stage.Done ? '0.5em' : '1em'} 1.5em;
  width:4em;
  text-align:center;
  border: ${(props) => props.userActionRequired ? '1px solid ' + props.theme.yellow : 'none'}
`

const LinkSubtitle = styled('div')`
  color:${props => props.theme.lightgrey};
  font-size:0.6em;
  text-align:center;
`

export class AssessmentItem extends Component {
  render () {
    const assessment = this.props.assessment
    let userStage = assessment.userStage
    let stage = assessment.stage

    // set assessee/assessor view
    let RoleBadge = h(AssessorBadge, 'Assessor')
    let isAssessee = ''
    if (this.props.userAddress === assessment.assessee) {
      RoleBadge = h(AssesseeBadge, 'Assessee')
      isAssessee = ' (you)'
    }
    if (stage === Stage.None) {
      RoleBadge = null
    }

    // set meeting point component
    let MeetingPoint = ' NoMeetingPointSet '
    if (assessment.data) {
      MeetingPoint = h(MeetingAddress, {
        href: assessment.data,
        target: '_blank'
      }, assessment.data)
    }

    // look if user is required to make an action
    let userActionRequired = true
    let actionText = StageDisplayNames[userStage]
    if (stage < userStage ||
      userStage === 0 ||
      userStage === 4 ||
      userStage === 5) {
      userActionRequired = false
    }
    if (stage < userStage) {
      actionText = 'Waiting...'
    }
    // if assessment stage is finished, set good message (an assessee would have userStage===0)
    if (stage === Stage.Done) {
      // display score for assessee and payout for assessor
      if (!isAssessee) {
        actionText = h('div', [
          h('div', 'Payout :'),
          h('div', '+5 AHA')
        ])
      } else {
        actionText = h('div', [
          h('div', 'Score :'),
          h('div', assessment.finalScore + ' %')
        ])
      }
    }
    if (stage === Stage.Burned) {
      actionText = 'Canceled'
    }
    return (
      h(ItemFrame, {userActionRequired}, [
        h(Box, [
          h(ConceptName, assessment.conceptData),
          h(AssesseeAddress, {
            href: 'https://' + (this.props.networkID === 4 ? 'rinkeby.' : '') + 'etherscan.io/address/' + assessment.assessee,
            target: '_blank',
            title: 'est'
          }, 'assessee: ' + assessment.assessee.substring(0, 8) + '...' + assessment.assessee.substring(30, 42) + isAssessee)
        ]),
        h(Box, [
          RoleBadge
        ]),
        h(MeetingBox, [
          h(MeetingCaption, 'Meet at:'),
          MeetingPoint
        ]
        ),
        h(LinkBox, [
          h(LinkSubtitle, 'click here for details'),
          h(LinkUnstyled, { to: 'assessment/' + assessment.address },
            h(LinkButton, { userActionRequired, stage },
              actionText
            )
          )
        ])
      ])
    )
  }
}

export default AssessmentItem
<|endoftext|>