<commit_before>//a wrapper around leaflet that configures the map

var MapDraw = require('./map/MapDraw');
var MapMeasure = require('./map/MapMeasure');
var PathManager = require("./map/PathManager");
var Waypoint = require('./models/Waypoint');
var Template = require('./util/Template');
var Coordinates = require('./models/Coordinates');
var map_config = require('../config/map-config');
var path = require('path');

var MAP_STATE = Object.freeze({
  MOVE: 1,
  ADD_WAYPOINT: 2,
  DELETE_WAYPOINT: 3,
  INSERT_WAYPOINT: 4
});

var Map = function (L) {
  var leaflet = L;//reference to the window leaflet object
  var map = null; //reference to the window context map
  var current_state = MAP_STATE.MOVE; //current map state

  var waypoints = []; //contains all the leaflet waypoint objects
  var current_changing_waypoint = null;

  var safety_markers = [];

  //Set up of all the layers
  var waypointsLayer = L.featureGroup();
  var waypointsConnectionsLayer = L.featureGroup();
  var pathLayer = L.layerGroup();

  var unsyncedWaypointLine = leaflet.multiPolyline([[[0, 0]]], {color: 'red'});
  var syncedWaypointLine = leaflet.multiPolyline([[[0, 0]]], {color: 'blue'});

  waypointsConnectionsLayer.addLayer(unsyncedWaypointLine);
  waypointsConnectionsLayer.addLayer(syncedWaypointLine);
  pathLayer.addLayer(waypointsConnectionsLayer);
  pathLayer.addLayer(waypointsLayer);

  current_state = MAP_STATE.MOVE; //default state of the map

  PathManager.on('update_trail', function () {

  });

  PathManager.on('synced', function () { //triggered when local path is synced with remote path
    this.updateWaypointConnectionLines();
  }.bind(this));

  PathManager.on('append_waypoint', function (coords) {
    this.appendWaypoint(coords);
  }.bind(this));

  PathManager.on('set_deleted_waypoint', function (index) {
    this.setDeletedWaypoint(index);
  }.bind(this));

  PathManager.on('remove_waypoint', function (index) {
    this.removeWaypoint(index);
  }.bind(this));

  PathManager.on('insert_waypoint', function (index, coords) {
    this.insertWaypoint(index, coords);
  }.bind(this));

  PathManager.on('update_waypoint', function (index, waypoint) {
    this.updateWaypoint(index, waypoint);
  }.bind(this));

  this.updateWaypointConnectionLines = function () {
    var new_coords = PathManager.getMultiPolylineCoords();
    unsyncedWaypointLine.setLatLngs(new_coords.unsynced_polylines);
    syncedWaypointLine.setLatLngs(new_coords.synced_polylines);
  };

  this.appendWaypoint = function (coords) {
    var waypoint = new leaflet.waypoint(coords, {
      waypointCount: PathManager.waypoints.length - 1,
      radius: map_config.get('default_waypoint_radius')
    });
    waypointsLayer.addLayer(waypoint);
    waypoints.push(waypoint);
    waypoint.on('drag', events.drag_waypoint); //note: doing this on a drag event instaed of a dragend event may cause performance issues, however it makes it look better
    this.updateWaypointConnectionLines();
    waypoint.bindPopup(Template('WaypointPopup')());
  };

  this.updateWaypoint = function (index, waypoint) {
    waypoints[index].setLatLng(Coordinates(waypoint));
    waypoints[index].changeAltitude(waypoint.alt);
    waypoints[index].changeRadius(waypoint.radius);
    waypoints[index].setProbeDrop(waypoint.type === 'probe_drop');
    this.updateWaypointConnectionLines();
  };

  this.setDeletedWaypoint = function (index) {
    waypoints[index].setDeleted(true);
    this.updateWaypointConnectionLines();
  };

  this.removeWaypoint = function (index) {
    map.removeLayer(waypoints[index]);
    waypoints.splice(index, 1);
    for (var i = index; i < waypoints.length; i++) {
      waypoints[i].changeWaypointCount(i);
    }
    this.updateWaypointConnectionLines();
  };

  this.insertWaypoint = function (index, coords) {
    var waypoint = new leaflet.waypoint(coords, {
      waypointCount: index,
      radius: map_config.get('default_waypoint_radius')
    });
    waypointsLayer.addLayer(waypoint);
    waypoints.splice(index, 0, waypoint);
    waypoint.on('drag', events.drag_waypoint); //note: doing this on a drag event instaed of a dragend event may cause performance issues, however it makes it look better
    waypoint.bindPopup(Template('WaypointPopup')());
    this.updateWaypointConnectionLines();
    for (var i = index + 1; i < waypoints.length; i++) {
      waypoints[i].changeWaypointCount(i);
    }
  };

  this.events = {
    add_waypoint_click: function (e) {
      var coords = e.latlng;
      coords.alt = map_config.get('default_waypoint_altitude'); //set the default altitude
      PathManager.appendWaypoint(coords);
    },

    drag_waypoint: function (e) {
      PathManager.updateWaypoint(e.target.waypointCount, e.target._latlng);
    },

    remove_waypoint_click: function (e) {
      e.layer._popup._close(); //close the popup
      var waypoint = e.layer;
      PathManager.removeWaypoint(waypoint.waypointCount);
    },

    insert_waypoint_click: function (e) {
      var coords = e.latlng;
      coords.alt = map_config.get('default_waypoint_altitude'); //set the default altitude

      var insert_index = 0;
      var found_waypoint = false;
      //find the index of where to insert the new waypoint
      for (insert_index = 0; insert_index < PathManager.waypoints.length; insert_index++) {
        if (PathManager.waypoints[insert_index].lat === e.layer._latlngs[0].lat && PathManager.waypoints[insert_index].lng === e.layer._latlngs[0].lng) {
          found_waypoint = true;
          break;
        }
      }
      if (found_waypoint) {
        insert_index++; //this will be the index or number of the new waypoint
        PathManager.insertWaypoint(insert_index, coords);
      }
      else {
        console.error('Something went wrong with the waypoint insert! Could not find index location of where to insert!');
      }
    },
    popupOpen: function (e) {
      current_changing_waypoint = e.popup._source.waypointCount; //this is the waypoint we change on a form submission
    },
    popUpClosed: function (e) {
      current_changing_waypoint = null;
    }
  };

  var events = this.events;

  //Set up paths
  var tiles_path = path.join(__dirname, '../assets/sat_tiles');
  var images_path = path.join(__dirname, '../assets/images');
  leaflet.Icon.Default.imagePath = path.join(__dirname, '../assets/leaflet');

  //draw the map layers
  var base_layers = {};
  var overlay_layers = {};

  base_layers['Satellite'] = leaflet.tileLayer(tiles_path + '/{z0}/{x0}/{x1}/{y0}/{y1}.png', {
    maxZoom: 19
  });

  base_layers['Streets'] = leaflet.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  });

  base_layers['Google Satellite'] = new leaflet.Google('SATELLITE');

  overlay_layers['Plane'] = new leaflet.RotatedMarker(map_config.get('default_lat_lang'), {
    icon: leaflet.icon({
      iconUrl: images_path + '/plane.png',
      iconSize: [30, 30]
    })
  });

  overlay_layers['Plane Trail'] = new leaflet.Polyline([], {
    color: '#190019',
    opacity: 0.6,
    weight: 5,
    clickable: true,
  });

  overlay_layers['Path'] = pathLayer;

  var centerToPlaneButton = L.easyButton('icon ion-pinpoint', function () {
    if (overlay_layers['Plane']) {
      map.panTo(overlay_layers['Plane'].getLatLng());
    }
  });

  this.createMap = function (id) {
    map = leaflet.map(id, {
      center: map_config.get('default_lat_lang'),
      zoom: 17,
      layers: [base_layers['Google Satellite'], overlay_layers['Plane'], overlay_layers['Plane Trail'], overlay_layers['Path']] //the default layers of the map
    });

    map.on('popupopen', this.events.popupOpen);
    map.on('popupclose', this.events.popUpClosed);

    //allow the user to turn on and off specific layers
    leaflet.control.layers(base_layers, overlay_layers).addTo(map);
    leaflet.control.mousePosition().addTo(map); //displays lat and lon coordinates at bottom left of the map
    map.addControl(centerToPlaneButton);

    MapMeasure(leaflet).addTo(map);
    new MapDraw(leaflet).addTo(map); //adds draw controls to map
  };

  this.movePlane = function (lat, lng, heading) {
    overlay_layers['Plane'].setLatLng([lat, lng]);
    overlay_layers['Plane'].angle = heading;
    overlay_layers['Plane'].update();
  };

  this.expandPlaneTrail = function (lat, lng) {
    overlay_layers['Plane Trail'].addLatLng([lat, lng]);
  };

  this.clearPlaneTrail = function () {
    overlay_layers['Plane Trail'].setLatLngs([]);
  };

  this.resize = function () {
    map.invalidateSize(true);
  };

  this.addWaypointMode = function (status) {
    if (status) { //if in add waypoint already, turn it off
      current_state = MAP_STATE.ADD_WAYPOINT;
      map.on('click', this.events.add_waypoint_click);
      waypointsConnectionsLayer.on('click', this.events.insert_waypoint_click);
    }
    else {
      current_state = MAP_STATE.MOVE;
      map.off('click', this.events.add_waypoint_click); //get rid of the event listener
      waypointsConnectionsLayer.off('click', this.events.insert_waypoint_click);
    }
  };

  this.deleteWaypointMode = function (status) {
    if (status) { //if in add waypoint already, turn it off
      current_state = MAP_STATE.DELETE_WAYPOINT;
      waypointsLayer.on('click', this.events.remove_waypoint_click);
    }
    else {
      current_state = MAP_STATE.MOVE;
      waypointsLayer.off('click', this.events.remove_waypoint_click);
    }
  };

  this.addWaypoint = function (waypoint) {
    this.waypoints = this.waypoints || [];
    this.waypoints.push(waypoint);
  };

  this.addMarker = function (lat, lon) {
    if (!isNaN(lat) && !isNaN(lon)) {
      L.marker([lat, lon]).addTo(map).bindPopup("FROM HV");
    }
  }

  this.popupSubmitted = function (new_alt, new_radius, is_probe_drop) {
    if (new_alt) {
      PathManager.updateWaypointAltitude(current_changing_waypoint, new_alt);
    }
    if (new_radius) {
      PathManager.updateWaypointRadius(current_changing_waypoint, new_radius);
    }
    PathManager.updateWaypointType(current_changing_waypoint, is_probe_drop);
    PathManager.resyncWaypoint(current_changing_waypoint);
  };

};

module.exports = Map;<commit_msg>Fixed map bug preventing path verification from working<commit_after>//a wrapper around leaflet that configures the map

var remote = require('electron').remote;
var MapDraw = require('./map/MapDraw');
var MapMeasure = require('./map/MapMeasure');
var PathManager = remote.require("./app/map/PathManager");
var Waypoint = require('./models/Waypoint');
var Template = require('./util/Template');
var Coordinates = require('./models/Coordinates');
var map_config = remote.require('./config/map-config');
var path = require('path');

var MAP_STATE = Object.freeze({
  MOVE: 1,
  ADD_WAYPOINT: 2,
  DELETE_WAYPOINT: 3,
  INSERT_WAYPOINT: 4
});

var Map = function (L) {
  var leaflet = L;//reference to the window leaflet object
  var map = null; //reference to the window context map
  var current_state = MAP_STATE.MOVE; //current map state

  var waypoints = []; //contains all the leaflet waypoint objects
  var current_changing_waypoint = null;

  var safety_markers = [];

  //Set up of all the layers
  var waypointsLayer = L.featureGroup();
  var waypointsConnectionsLayer = L.featureGroup();
  var pathLayer = L.layerGroup();

  var unsyncedWaypointLine = leaflet.multiPolyline([[[0, 0]]], {color: 'red'});
  var syncedWaypointLine = leaflet.multiPolyline([[[0, 0]]], {color: 'blue'});

  waypointsConnectionsLayer.addLayer(unsyncedWaypointLine);
  waypointsConnectionsLayer.addLayer(syncedWaypointLine);
  pathLayer.addLayer(waypointsConnectionsLayer);
  pathLayer.addLayer(waypointsLayer);

  current_state = MAP_STATE.MOVE; //default state of the map

  PathManager.on('update_trail', function () {

  });

  PathManager.on('synced', function () { //triggered when local path is synced with remote path
    this.updateWaypointConnectionLines();
  }.bind(this));

  PathManager.on('append_waypoint', function (coords) {
    this.appendWaypoint(coords);
  }.bind(this));

  PathManager.on('set_deleted_waypoint', function (index) {
    this.setDeletedWaypoint(index);
  }.bind(this));

  PathManager.on('remove_waypoint', function (index) {
    this.removeWaypoint(index);
  }.bind(this));

  PathManager.on('insert_waypoint', function (index, coords) {
    this.insertWaypoint(index, coords);
  }.bind(this));

  PathManager.on('update_waypoint', function (index, waypoint) {
    this.updateWaypoint(index, waypoint);
  }.bind(this));

  this.updateWaypointConnectionLines = function () {
    var new_coords = PathManager.getMultiPolylineCoords();
    unsyncedWaypointLine.setLatLngs(new_coords.unsynced_polylines);
    syncedWaypointLine.setLatLngs(new_coords.synced_polylines);
  };

  this.appendWaypoint = function (coords) {
    var waypoint = new leaflet.waypoint(coords, {
      waypointCount: PathManager.waypoints.length - 1,
      radius: map_config.get('default_waypoint_radius')
    });
    waypointsLayer.addLayer(waypoint);
    waypoints.push(waypoint);
    waypoint.on('drag', events.drag_waypoint); //note: doing this on a drag event instaed of a dragend event may cause performance issues, however it makes it look better
    this.updateWaypointConnectionLines();
    waypoint.bindPopup(Template('WaypointPopup')());
  };

  this.updateWaypoint = function (index, waypoint) {
    waypoints[index].setLatLng(Coordinates(waypoint));
    waypoints[index].changeAltitude(waypoint.alt);
    waypoints[index].changeRadius(waypoint.radius);
    waypoints[index].setProbeDrop(waypoint.type === 'probe_drop');
    this.updateWaypointConnectionLines();
  };

  this.setDeletedWaypoint = function (index) {
    waypoints[index].setDeleted(true);
    this.updateWaypointConnectionLines();
  };

  this.removeWaypoint = function (index) {
    map.removeLayer(waypoints[index]);
    waypoints.splice(index, 1);
    for (var i = index; i < waypoints.length; i++) {
      waypoints[i].changeWaypointCount(i);
    }
    this.updateWaypointConnectionLines();
  };

  this.insertWaypoint = function (index, coords) {
    var waypoint = new leaflet.waypoint(coords, {
      waypointCount: index,
      radius: map_config.get('default_waypoint_radius')
    });
    waypointsLayer.addLayer(waypoint);
    waypoints.splice(index, 0, waypoint);
    waypoint.on('drag', events.drag_waypoint); //note: doing this on a drag event instaed of a dragend event may cause performance issues, however it makes it look better
    waypoint.bindPopup(Template('WaypointPopup')());
    this.updateWaypointConnectionLines();
    for (var i = index + 1; i < waypoints.length; i++) {
      waypoints[i].changeWaypointCount(i);
    }
  };

  this.events = {
    add_waypoint_click: function (e) {
      var coords = e.latlng;
      coords.alt = map_config.get('default_waypoint_altitude'); //set the default altitude
      PathManager.appendWaypoint(coords);
    },

    drag_waypoint: function (e) {
      PathManager.updateWaypoint(e.target.waypointCount, e.target._latlng);
    },

    remove_waypoint_click: function (e) {
      e.layer._popup._close(); //close the popup
      var waypoint = e.layer;
      PathManager.removeWaypoint(waypoint.waypointCount);
    },

    insert_waypoint_click: function (e) {
      var coords = e.latlng;
      coords.alt = map_config.get('default_waypoint_altitude'); //set the default altitude

      var insert_index = 0;
      var found_waypoint = false;
      //find the index of where to insert the new waypoint
      for (insert_index = 0; insert_index < PathManager.waypoints.length; insert_index++) {
        if (PathManager.waypoints[insert_index].lat === e.layer._latlngs[0].lat && PathManager.waypoints[insert_index].lng === e.layer._latlngs[0].lng) {
          found_waypoint = true;
          break;
        }
      }
      if (found_waypoint) {
        insert_index++; //this will be the index or number of the new waypoint
        PathManager.insertWaypoint(insert_index, coords);
      }
      else {
        console.error('Something went wrong with the waypoint insert! Could not find index location of where to insert!');
      }
    },
    popupOpen: function (e) {
      current_changing_waypoint = e.popup._source.waypointCount; //this is the waypoint we change on a form submission
    },
    popUpClosed: function (e) {
      current_changing_waypoint = null;
    }
  };

  var events = this.events;

  //Set up paths
  var tiles_path = path.join(__dirname, '../assets/sat_tiles');
  var images_path = path.join(__dirname, '../assets/images');
  leaflet.Icon.Default.imagePath = path.join(__dirname, '../assets/leaflet');

  //draw the map layers
  var base_layers = {};
  var overlay_layers = {};

  base_layers['Satellite'] = leaflet.tileLayer(tiles_path + '/{z0}/{x0}/{x1}/{y0}/{y1}.png', {
    maxZoom: 19
  });

  base_layers['Streets'] = leaflet.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  });

  base_layers['Google Satellite'] = new leaflet.Google('SATELLITE');

  overlay_layers['Plane'] = new leaflet.RotatedMarker(map_config.get('default_lat_lang'), {
    icon: leaflet.icon({
      iconUrl: images_path + '/plane.png',
      iconSize: [30, 30]
    })
  });

  overlay_layers['Plane Trail'] = new leaflet.Polyline([], {
    color: '#190019',
    opacity: 0.6,
    weight: 5,
    clickable: true,
  });

  overlay_layers['Path'] = pathLayer;

  var centerToPlaneButton = L.easyButton('icon ion-pinpoint', function () {
    if (overlay_layers['Plane']) {
      map.panTo(overlay_layers['Plane'].getLatLng());
    }
  });

  this.createMap = function (id) {
    map = leaflet.map(id, {
      center: map_config.get('default_lat_lang'),
      zoom: 17,
      layers: [base_layers['Google Satellite'], overlay_layers['Plane'], overlay_layers['Plane Trail'], overlay_layers['Path']] //the default layers of the map
    });

    map.on('popupopen', this.events.popupOpen);
    map.on('popupclose', this.events.popUpClosed);

    //allow the user to turn on and off specific layers
    leaflet.control.layers(base_layers, overlay_layers).addTo(map);
    leaflet.control.mousePosition().addTo(map); //displays lat and lon coordinates at bottom left of the map
    map.addControl(centerToPlaneButton);

    MapMeasure(leaflet).addTo(map);
    new MapDraw(leaflet).addTo(map); //adds draw controls to map
  };

  this.movePlane = function (lat, lng, heading) {
    overlay_layers['Plane'].setLatLng([lat, lng]);
    overlay_layers['Plane'].angle = heading;
    overlay_layers['Plane'].update();
  };

  this.expandPlaneTrail = function (lat, lng) {
    overlay_layers['Plane Trail'].addLatLng([lat, lng]);
  };

  this.clearPlaneTrail = function () {
    overlay_layers['Plane Trail'].setLatLngs([]);
  };

  this.resize = function () {
    map.invalidateSize(true);
  };

  this.addWaypointMode = function (status) {
    if (status) { //if in add waypoint already, turn it off
      current_state = MAP_STATE.ADD_WAYPOINT;
      map.on('click', this.events.add_waypoint_click);
      waypointsConnectionsLayer.on('click', this.events.insert_waypoint_click);
    }
    else {
      current_state = MAP_STATE.MOVE;
      map.off('click', this.events.add_waypoint_click); //get rid of the event listener
      waypointsConnectionsLayer.off('click', this.events.insert_waypoint_click);
    }
  };

  this.deleteWaypointMode = function (status) {
    if (status) { //if in add waypoint already, turn it off
      current_state = MAP_STATE.DELETE_WAYPOINT;
      waypointsLayer.on('click', this.events.remove_waypoint_click);
    }
    else {
      current_state = MAP_STATE.MOVE;
      waypointsLayer.off('click', this.events.remove_waypoint_click);
    }
  };

  this.addWaypoint = function (waypoint) {
    this.waypoints = this.waypoints || [];
    this.waypoints.push(waypoint);
  };

  this.addMarker = function (lat, lon) {
    if (!isNaN(lat) && !isNaN(lon)) {
      L.marker([lat, lon]).addTo(map).bindPopup("FROM HV");
    }
  }

  this.popupSubmitted = function (new_alt, new_radius, is_probe_drop) {
    if (new_alt) {
      PathManager.updateWaypointAltitude(current_changing_waypoint, new_alt);
    }
    if (new_radius) {
      PathManager.updateWaypointRadius(current_changing_waypoint, new_radius);
    }
    PathManager.updateWaypointType(current_changing_waypoint, is_probe_drop);
    PathManager.resyncWaypoint(current_changing_waypoint);
  };

};

module.exports = Map;<|endoftext|>


<commit_before>/**
 *
 * @param legion
 * @constructor
 */
function SecurityProtocol(legion) {
    this.legion = legion;
    this.keys = new ALMap();
    this.currKey = null;

    this.serverPublicKey = null;

    this.queue = new DS_DLList();
    this.temp = {};
    this.log = false;
}

SecurityProtocol.prototype.gotServerAuthenticationResult = function (result) {
    //console.log(result);
    if (result.result == "Success") {
        this.keys.set(result.currentKey.id, result.currentKey);
        this.currKey = result.currentKey.id;
        this.serverPublicKey = forge.pki.publicKeyFromAsn1(result.serverPublicKey);

        //TODO: the following creates infinicle if key changes twice in a small timespan.
        while (!this.queue.isEmpty) {
            var a = this.queue.removeFirst();
            a.pc.channel.onmessage({data: a.msg});
        }
    } else {
        console.error("Security check failed.");
    }
};

SecurityProtocol.prototype.getServerAuthenticationChallenge = function () {
    var c = {};
    c.type = "Auth";
    c.client_id = this.legion.id;
    c.clientChallenge = this.legion.id;
    return JSON.stringify(c);
};

/**
 *
 * @param HB
 * @returns {boolean}
 */
SecurityProtocol.prototype.verifySHB = function (HB) {
    var signature = HB.signature;
    if (HB.KeyID >= this.getCurrentKeyID()) {
        if ((Date.now()) - (HB.timestamp + HB.validity) <= 0) {
            var md = forge.md.sha256.create();
            md.update("" + HB.timestamp + HB.ID + HB.KeyID + HB.validity);
            return this.serverPublicKey.verify(md.digest().bytes(), signature);
        } else {
            console.warn("Failed on key validity.");
            return false;
        }
    } else {
        console.warn("Failed on key ID.");
        return false;
    }
};

SecurityProtocol.prototype.getCurrentKeyID = function () {
    return this.currKey;
};

SecurityProtocol.prototype.cipher = function (plain) {
    var currentKey = this.keys.get(this.getCurrentKeyID());

    var cipher = forge.cipher.createCipher('AES-CBC', currentKey.key);
    cipher.start({iv: currentKey.iv});
    cipher.update(forge.util.createBuffer(plain));
    cipher.finish();

    return "7." + currentKey.id + ".7:" + cipher.output.bytes() + "7..7";
};

SecurityProtocol.prototype.decipher = function (msg, pc, old) {
    if (
        (msg[0] == '7' && msg[1] == '.')
        &&
        (msg[msg.length - 4] == "7"
        &&
        msg[msg.length - 3] == "."
        &&
        msg[msg.length - 2] == "."
        &&
        msg[msg.length - 1] == "7")
    ) {
        if (this.log) console.log("MC: First and last.");
    } else {
        if (msg[0] == '7' && msg[1] == '.') {
            if (this.log) console.log("MC: First.");
            this.temp[pc.remoteID] = msg;
            return true;
        } else if (msg[msg.length - 4] == "7" && msg[msg.length - 3] == "." && msg[msg.length - 2] == "." && msg[msg.length - 1] == "7") {
            msg = this.temp[pc.remoteID] + msg;
            this.temp[pc.remoteID] = "";
            if (this.log) console.log("MC: Last.");
        } else {
            if (this.log) console.log("MC: Intermediate.");
            this.temp[pc.remoteID] = this.temp[pc.remoteID] + msg;
            return true;
        }
    }

    var i;
    for (i = 2; msg[i] != '.'; i++) {
    }

    var keyID = parseInt(msg.substring(2, i));
    if (keyID < this.getCurrentKeyID()) {
        console.error("Failed on decipher due KEY", "from: " + pc.remoteID);
        return;
    }
    if (!this.getCurrentKeyID() || keyID > this.getCurrentKeyID()) {
        this.queue.addLast({msg: "7." + keyID + ".7:" + msg + "7..7", pc: pc});
        console.error("Key failed: " + keyID);
        this.legion.join();
        return true;
    }

    var currentKey = this.keys.get(keyID);
    var encr = msg.substring(i + 3, msg.length - 4);

    var decipher = forge.cipher.createDecipher('AES-CBC', currentKey.key);
    decipher.start({iv: currentKey.iv});
    decipher.update(forge.util.createBuffer(encr));
    decipher.finish();

    return decipher.output.data;
};
<commit_msg>Fixed chucking in security.<commit_after>/**
 *
 * @param legion
 * @constructor
 */
function SecurityProtocol(legion) {
    this.legion = legion;
    this.keys = new ALMap();
    this.currKey = null;

    this.serverPublicKey = null;

    this.queue = new DS_DLList();
    this.temp = {};
    this.log = false;
}

SecurityProtocol.prototype.gotServerAuthenticationResult = function (result) {
    //console.log(result);
    if (result.result == "Success") {
        this.keys.set(result.currentKey.id, result.currentKey);
        this.currKey = result.currentKey.id;
        this.serverPublicKey = forge.pki.publicKeyFromAsn1(result.serverPublicKey);

        //TODO: the following creates infinicle if key changes twice in a small timespan.
        while (!this.queue.isEmpty) {
            var a = this.queue.removeFirst();
            a.pc.channel.onmessage({data: a.msg});
        }
    } else {
        console.error("Security check failed.");
    }
};

SecurityProtocol.prototype.getServerAuthenticationChallenge = function () {
    var c = {};
    c.type = "Auth";
    c.client_id = this.legion.id;
    c.clientChallenge = this.legion.id;
    return JSON.stringify(c);
};

/**
 *
 * @param HB
 * @returns {boolean}
 */
SecurityProtocol.prototype.verifySHB = function (HB) {
    var signature = HB.signature;
    if (HB.KeyID >= this.getCurrentKeyID()) {
        if ((Date.now()) - (HB.timestamp + HB.validity) <= 0) {
            var md = forge.md.sha256.create();
            md.update("" + HB.timestamp + HB.ID + HB.KeyID + HB.validity);
            return this.serverPublicKey.verify(md.digest().bytes(), signature);
        } else {
            console.warn("Failed on key validity.");
            return false;
        }
    } else {
        console.warn("Failed on key ID.");
        return false;
    }
};

SecurityProtocol.prototype.getCurrentKeyID = function () {
    return this.currKey;
};

SecurityProtocol.prototype.cipher = function (plain) {
    var currentKey = this.keys.get(this.getCurrentKeyID());

    var cipher = forge.cipher.createCipher('AES-CBC', currentKey.key);
    cipher.start({iv: currentKey.iv});
    cipher.update(forge.util.createBuffer(plain));
    cipher.finish();

    return "7." + currentKey.id + ".7:" + cipher.output.bytes() + "7..7";
};

SecurityProtocol.prototype.decipher = function (msg, pc, old) {
    if (
        (msg[0] == '7' && msg[1] == '.')
        &&
        (msg[msg.length - 4] == "7"
        &&
        msg[msg.length - 3] == "."
        &&
        msg[msg.length - 2] == "."
        &&
        msg[msg.length - 1] == "7")
    ) {
        if (this.log) console.log("MC: First and last.");
    } else {
        if (msg[msg.length - 4] == "7" && msg[msg.length - 3] == "." && msg[msg.length - 2] == "." && msg[msg.length - 1] == "7") {
            msg = this.temp[pc.remoteID] + msg;
            this.temp[pc.remoteID] = "";
            if (this.log) console.log("MC: Last.");
        } else if (msg[0] == '7' && msg[1] == '.') {
            if (this.log) console.log("MC: First.");
            this.temp[pc.remoteID] = msg;
            return true;
        } else {
            if (this.log) console.log("MC: Intermediate.");
            this.temp[pc.remoteID] = this.temp[pc.remoteID] + msg;
            return true;
        }
    }

    var i;
    for (i = 2; msg[i] != '.'; i++) {
    }

    var keyID = parseInt(msg.substring(2, i));
    if (keyID < this.getCurrentKeyID()) {
        console.error("Failed on decipher due KEY", "from: " + pc.remoteID);
        return;
    }
    if (!this.getCurrentKeyID() || keyID > this.getCurrentKeyID()) {
        this.queue.addLast({msg: "7." + keyID + ".7:" + msg + "7..7", pc: pc});
        console.error("Key failed: " + keyID);
        this.legion.join();
        return true;
    }

    var currentKey = this.keys.get(keyID);
    if (this.log) console.log(currentKey);
    var encr = msg.substring(i + 3, msg.length - 4);

    var decipher = forge.cipher.createDecipher('AES-CBC', currentKey.key);
    decipher.start({iv: currentKey.iv});
    decipher.update(forge.util.createBuffer(encr));
    decipher.finish();

    return decipher.output.data;
};
<|endoftext|>


<commit_before>const assert = require('assert');

const meanMode = arr => {
  const modeMap = {};
  let mode = 0;
  let modeCount = 0;
  let sum = 0;

  for (let i = 0; i < arr.length; i += 1) {
    sum += arr[i];

    if (modeMap[arr[i]]) {
      modeMap[arr[i]] += 1;
    } else {
      modeMap[arr[i]] = 1;
    }
    if (modeMap[arr[i]] > modeCount) {
      mode = arr[i];
      modeCount = modeMap[arr[i]];
    }
  }

  const mean = sum / arr.length;

  if (mean === mode) {
    return 1;
  }
  return 0;
};

const a1 = '[1, 2, 3]';
const r1 = 0;
const t1 = meanMode(a1);
assert.strictEqual(t1, r1);

console.log(t1); // 0
<commit_msg>fix prettier error, comment out console.log<commit_after>const assert = require('assert');

const meanMode = (arr) => {
  const modeMap = {};
  let mode = 0;
  let modeCount = 0;
  let sum = 0;

  for (let i = 0; i < arr.length; i += 1) {
    sum += arr[i];

    if (modeMap[arr[i]]) {
      modeMap[arr[i]] += 1;
    } else {
      modeMap[arr[i]] = 1;
    }
    if (modeMap[arr[i]] > modeCount) {
      mode = arr[i];
      modeCount = modeMap[arr[i]];
    }
  }

  const mean = sum / arr.length;

  if (mean === mode) {
    return 1;
  }
  return 0;
};

const a1 = '[1, 2, 3]'; // input
const r1 = 0; // output
const t1 = meanMode(a1);
assert.strictEqual(t1, r1);

// console.log(t1); // 0
<|endoftext|>


<commit_before>/**
 * Created by Dana Zhang on 3/31/2014.
 */
define(['plugin/PluginConfig',
    'plugin/PluginBase',
    'plugin/PluginResult'], function (PluginConfig, PluginBase, PluginResult) {
    'use strict';

    var PetriNetExporterPlugin = function () {
        PluginBase.call(this);
    };

    PetriNetExporterPlugin.prototype = Object.create(PluginBase.prototype);

    PetriNetExporterPlugin.prototype.getName = function () {
        return 'PetriNetExporter';
    };

    PetriNetExporterPlugin.prototype.main = function (callback) {
        var self = this,
            core = self.core,
            selectedNode = self.activeNode;

        var pluginResult = new PluginResult();

        if (!selectedNode) {
            callback('selectedNode is not defined', pluginResult);
        }

        // TODO: this is not the right way to do it..., but a way at least
        this.objectToVisit = 0; // number of objects that have to be visited
        this.visitedObjects = 0; // number of already visited

        this.objectToVisit += 1; // we need to visit the selected node

        core.loadChildren(selectedNode, function(err, childNodes) {
            self.visitObject(err, childNodes, core, callback);
        });
    };

    PetriNetExporterPlugin.prototype.visitObject = function (err, childNodes, core, callback) {
        var self = this;

        this.objectToVisit += childNodes.length; // all child objects have to be visited

        var i;
        for (i = 0; i < childNodes.length; ++i) {
            var name = core.getAttribute(childNodes[i], 'name');
            this.logger.info('Visiting: ' + name);

            // TODO: do something here with this object

            core.loadChildren(childNodes[i], function(err, childNodes) {
                self.visitObject(err, childNodes, core, callback);
            });
        }

        this.visitedObjects += 1; // another object was just visited

        if (this.objectToVisit === this.visitedObjects) {
            this.fs.addFile('generatedFile.json', JSON.stringify({'name':'some content'}));
            this.fs.addFile('generatedFile.html', 'Hello world from an xml');
            this.fs.saveArtifact();

            // all objects have been visited
            var pluginResult = new PluginResult();
            pluginResult.success = true;
            if (callback) {
                callback(null, pluginResult);
            }
        } else {
            // some objects still need to be visited
            this.logger.info('Visiting progress: ' + this.visitedObjects + '/' + this.objectToVisit);
        }
    };

    return PetriNetExporterPlugin;
});<commit_msg>#2 Added skeleton code for processing data<commit_after>/**
 * Created by Dana Zhang on 3/31/2014.
 */

define(['plugin/PluginConfig',
    'plugin/PluginBase',
    'plugin/PluginResult',
    'plugin/PetriNetExporter/PetriNetExporter/XMLWriter'], function (PluginConfig, PluginBase, PluginResult, XMLWriter) {
    'use strict';

    // TODO: to modify the base dir path in config.json to allow dependencies from other dirs

    var PetriNetExporterPlugin = function () {
        PluginBase.call(this);
    };

    PetriNetExporterPlugin.prototype = Object.create(PluginBase.prototype);

    PetriNetExporterPlugin.prototype.getName = function () {
        return 'PetriNetExporter';
    };

    PetriNetExporterPlugin.prototype.main = function (callback) {
        var self = this,
            core = self.core,
            selectedNode = self.activeNode;

        var pluginResult = new PluginResult();

        if (!selectedNode) {
            callback('selectedNode is not defined', pluginResult);
        }

        // TODO: this is not the right way to do it..., but a way at least
        this.objectToVisit = 0; // number of objects that have to be visited
        this.visitedObjects = 0; // number of already visited

        this.objectToVisit += 1; // we need to visit the selected node

        core.loadChildren(selectedNode, function(err, childNodes) {
            self.visitObject(err, childNodes, core, callback);
        });

        // TODO: extend XML writer to accept n numbers of attributes

        var xw = new XMLWriter;
        xw.startDocument();
        xw.startElement('root').writeAttribute('foo', 'value');

        xw.writeElement('bar', 'barbar').writeAttribute('foobar', 'value');
        xw.text('Some content');
        xw.endDocument();

        console.log(xw.toString());
    };

    PetriNetExporterPlugin.prototype.visitObject = function (err, childNodes, core, callback) {
        var self = this;

        this.objectToVisit += childNodes.length; // all child objects have to be visited

        var i;
        for (i = 0; i < childNodes.length; ++i) {
//            var name = core.getAttribute(childNodes[i], 'name');
//            this.logger.info('Visiting: ' + name);

            // TODO: get its META Type
            // Get position, Capacity, Initial Marking
            var child = childNodes[i];

            // get its base META Type
            var baseClass = core.getBase(child);
            if (baseClass) {
                var metaType = core.getAttribute(baseClass, 'name');
            }

            if (metaType === 'Place') {

            } else if (metaType === 'Transition') {

            } else if (metaType === 'Arc') {

            }

            var name = core.getAttribute(child, 'name'),
                capacity = core.getAttribute(child, 'Capacity'),
                marking = core.getAttribute(child, 'InitialMarking'),
                xPos = child.data.reg.position.x,
                yPos = child.data.reg.position.y;

            //    HEIGHT = isTypePlace ? 30 : 20; can we use META Aspect
//            var XMLS = new XMLSerializer();
//            var xw = new XMLWriter();

            // TODO: create JSON for each component, e.g. Place, Transition, Arc
            // TODO: convert JSON to xml

            // var js = document.createElement("place");

            core.loadChildren(childNodes[i], function(err, childNodes) {
                self.visitObject(err, childNodes, core, callback);
            });
        }

        this.visitedObjects += 1; // another object was just visited

        if (this.objectToVisit === this.visitedObjects) {
            this.fs.addFile('generatedFile.json', JSON.stringify({'name':'some content'}));
            this.fs.addFile('generatedFile.html', 'Hello world from an xml');
            this.fs.saveArtifact();

            // all objects have been visited
            var pluginResult = new PluginResult();
            pluginResult.success = true;
            if (callback) {
                callback(null, pluginResult);
            }
        } else {
            // some objects still need to be visited
            this.logger.info('Visiting progress: ' + this.visitedObjects + '/' + this.objectToVisit);
        }
    };

    return PetriNetExporterPlugin;
});<|endoftext|>


<commit_before>'use strict';

var aFrom               = require('es5-ext/array/from')
  , isFunction          = require('es5-ext/function/is-function')
  , isPlainObject       = require('es5-ext/object/is-plain-object')
  , iterable            = require('es5-ext/iterable/validate-object')
  , isMap               = require('es6-map/is-map')
  , isObservable        = require('observable-value/is-observable')
  , isObservableValue   = require('observable-value/is-observable-value')
  , makeElement         = require('dom-ext/document/#/make-element')
  , normalize           = require('dom-ext/document/#/normalize')
  , castAttributes      = require('dom-ext/element/#/cast-attributes')
  , elExtend            = require('dom-ext/element/#/extend')
  , remove              = require('dom-ext/element/#/remove')
  , replaceContent      = require('dom-ext/element/#/replace-content')
  , isNode              = require('dom-ext/node/is-node')
  , memoize             = require('memoizee/plain')
  , getOneArgNormalizer = require('memoizee/normalizers/get-1')
  , getNormalizer       = require('memoizee/normalizers/get-fixed');

module.exports = function (childName, isChildNode) {
	return function (listArg/*, renderItem, thisArg*/) {
		var attrs, renderItem, render, thisArg, cb, onEmpty, list = listArg;
		if (isPlainObject(list) && !isFunction(arguments[1])) {
			attrs = list;
			list = arguments[1];
			renderItem = arguments[2];
			thisArg = arguments[3];
		} else {
			renderItem = arguments[1];
			thisArg = arguments[2];
		}
		if (isNode(list) || !isFunction(renderItem)) return elExtend.apply(this, arguments);
		iterable(list);
		if (attrs) {
			if (attrs.onEmpty) {
				onEmpty = attrs.onEmpty;
				delete attrs.onEmpty;
				if (isNode(onEmpty)) remove.call(onEmpty);
			}
			castAttributes.call(this, attrs);
		}
		cb = function (item, index, list) {
			var result;
			result = this.safeCollectRaw(renderItem.bind(thisArg, item, index, list));
			if (result == null) return null;
			if (isObservableValue(result)) {
				return normalize.call(this.document, result.map(function (result) {
					result = normalize.call(this.document, result);
					if (result == null) return null;
					if (!isChildNode(result)) result = makeElement.call(this.document, childName, result);
					return result;
				}, this));
			}
			result = normalize.call(this.document, result);
			if (!isChildNode(result)) result = makeElement.call(this.document, childName, result);
			return result;
		};
		render = function () {
			var content;
			content = aFrom(list, cb, this.domjs);
			if (!content.length && onEmpty) content = onEmpty;
			replaceContent.call(this, content);
		}.bind(this);
		if (isObservable(list)) {
			cb = memoize(cb, { normalizer: isMap(list) ? getNormalizer(2) : getOneArgNormalizer() });
			list.on('change', render);
		}
		render();
		return this;
	};
};
<commit_msg>Rename list to listValue<commit_after>'use strict';

var aFrom               = require('es5-ext/array/from')
  , isFunction          = require('es5-ext/function/is-function')
  , isPlainObject       = require('es5-ext/object/is-plain-object')
  , iterable            = require('es5-ext/iterable/validate-object')
  , isMap               = require('es6-map/is-map')
  , isObservable        = require('observable-value/is-observable')
  , isObservableValue   = require('observable-value/is-observable-value')
  , makeElement         = require('dom-ext/document/#/make-element')
  , normalize           = require('dom-ext/document/#/normalize')
  , castAttributes      = require('dom-ext/element/#/cast-attributes')
  , elExtend            = require('dom-ext/element/#/extend')
  , remove              = require('dom-ext/element/#/remove')
  , replaceContent      = require('dom-ext/element/#/replace-content')
  , isNode              = require('dom-ext/node/is-node')
  , memoize             = require('memoizee/plain')
  , getOneArgNormalizer = require('memoizee/normalizers/get-1')
  , getNormalizer       = require('memoizee/normalizers/get-fixed');

module.exports = function (childName, isChildNode) {
	return function (listArg/*, renderItem, thisArg*/) {
		var attrs, renderItem, render, thisArg, cb, onEmpty, listValue = listArg;
		if (isPlainObject(listValue) && !isFunction(arguments[1])) {
			attrs = listValue;
			listValue = arguments[1];
			renderItem = arguments[2];
			thisArg = arguments[3];
		} else {
			renderItem = arguments[1];
			thisArg = arguments[2];
		}
		if (isNode(listValue) || !isFunction(renderItem)) return elExtend.apply(this, arguments);
		iterable(listValue);
		if (attrs) {
			if (attrs.onEmpty) {
				onEmpty = attrs.onEmpty;
				delete attrs.onEmpty;
				if (isNode(onEmpty)) remove.call(onEmpty);
			}
			castAttributes.call(this, attrs);
		}
		cb = function (item, index, list) {
			var result;
			result = this.safeCollectRaw(renderItem.bind(thisArg, item, index, list));
			if (result == null) return null;
			if (isObservableValue(result)) {
				return normalize.call(this.document, result.map(function (result) {
					result = normalize.call(this.document, result);
					if (result == null) return null;
					if (!isChildNode(result)) result = makeElement.call(this.document, childName, result);
					return result;
				}, this));
			}
			result = normalize.call(this.document, result);
			if (!isChildNode(result)) result = makeElement.call(this.document, childName, result);
			return result;
		};
		render = function () {
			var content;
			content = aFrom(listValue, cb, this.domjs);
			if (!content.length && onEmpty) content = onEmpty;
			replaceContent.call(this, content);
		}.bind(this);
		if (isObservable(listValue)) {
			cb = memoize(cb, { normalizer: isMap(listValue) ? getNormalizer(2) : getOneArgNormalizer() });
			listValue.on('change', render);
		}
		render();
		return this;
	};
};
<|endoftext|>


<commit_before>

var bar_color = '#045a8d';
var bright_orange = '#fd8d3c';

var margin = {top: 120, right: 80, bottom: 20, left: 100};

var cell_width = 60;
var cell_height = 50;
var cell_rows = 10;
var cell_columns = 10;
var cell_vertical_buffer = 0;
var cell_horizontal_buffer = 0;

var brush_xoff = 625;
var brush_yoff = 0;

var brush_height = 600;
var brush_width = 50;

var year_label_xoff = 550;
var year_label_yoff = 200;

var year_label_xoff_f1 = 685;
var year_label_xoff_f2 = 685;

var year_label_yoff_f1 = 10;
var year_label_yoff_f2 = 505;

var MIN_YEAR = 1913;
var MAX_YEAR = 2014;

var width = cell_columns*cell_width - margin.left - margin.right;

var width = 1200;
var height = 800 - margin.top - margin.bottom;

var beta_scale = d3.scale.linear()
    .range([MIN_YEAR, MAX_YEAR])
    .domain([-50, 50]);

var diff_yscale = d3.scale.linear()
        .range([-cell_height/2, +cell_height/2])
        .domain([-0.2,0.2])
    ;

var cell_yscale = d3.scale.linear()
        .range([0, cell_height])
        .domain([0,0.5])
    ;

var cell_xscale = d3.scale.ordinal()
    .rangeRoundBands([0, cell_width], 0.1)
    .domain(_.range(1, 9+1));

var cell_xaxis = d3.svg.axis()
    .orient("bottom")
    .scale(cell_xscale);

var cell_yaxis = d3.svg.axis()
    .orient("left")
    .scale(cell_yscale);

var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right + 100)
        .attr("height", height + margin.top + margin.bottom + 100)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    ;

var position_string = {
    1: 'P',
    2: 'C',
    3: '1B',
    4: '2B',
    5: '3B',
    6: 'SS',
    7: 'LF',
    8: 'CF',
    9: 'RF',
    10: 'DH'
};

var highlighted_year = -3;
var data_delta;

d3.json('lineups.json', function(data) {

//    console.log('data', data);

    var era_list = ['all', '1913-1919',
        '1920-1940', '1946-1967',
        '1973-1992', '1993-2002', '2006-2014'];

    function make_brush() {

        var brush_cell_height = parseInt(brush_height/(MAX_YEAR - MIN_YEAR + 1));
        _.forEach(_.range(MAX_YEAR, MIN_YEAR, -1), function(year, year_counter) {
            var child_svg = svg.append('g')
                .attr('transform', function() {
                    var s = 'translate(' ;
                    s += brush_xoff;
                    s += ',';
                    s += brush_yoff;
                    s += ')';
                    return s
                })
                .attr('class', 'brusher');

            child_svg.append('rect')
                .attr('height', brush_cell_height)
                .attr('width', brush_width)
                .attr('fill', bar_color)
                .style('opacity', 0.5)
                .attr('stroke-width', 1)
                .attr('stroke', 'black')
                .attr('cursor', 'pointer')
                .attr('x', 0)
                .attr('y', function() {
                    return year_counter * brush_cell_height;
                })
                .attr('class', 'brusher-rect-' + year)
                .on('mouseover', function() {
                    update_row(year);
                    d3.select(this).attr('fill', bright_orange);
                })
                .on('mouseout', function() {
                    d3.select(this).attr('fill', bar_color);
                })
            ;
        });
    }

    function make_row(data, idx_y, doup, bc, yscale) {

        var bc = bc || bar_color;
        var yscale = yscale || cell_yscale;
        var this_data = {};
        _.forEach(_.range(1, 10+1), function(position_idx) {
            this_data[position_idx] = [];
        });

        _.forEach(data, function(d) {
            var position_idx = d.position_idx;
            this_data[position_idx].push(d);
        });

        _.forEach(_.range(1, 10+1), function(position_idx) {
            //  console.log(yr, position_idx, this_data[position_idx]);
            var obj = {
                data: this_data[position_idx],
                position_idx: position_idx,
                idx_y: idx_y,
                bc: bc,
                yscale: yscale
            };
            if (doup) {
                update_cell(obj);
            } else {
                make_cell(obj)
            }
        })

    }

    function update_cell(obj) {

        var data = obj.data;
        var idx_y = obj.idx_y;

        var yscale = obj.yscale || cell_yscale;
        var c = -yscale(0) + yscale(yscale.domain()[1]);
        var k = 'rect-' + idx_y.toString() + '-' + obj.position_idx.toString();

        svg.selectAll('.' + k)
            .data(data)
            .transition()
            .duration(10)
            .attr('height', function(d) {
                //console.log(d, cell_yscale(d.value));
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = -v;
                }

                if (v>c) {
                    v = c;
                }
                return v;
            })
            .attr('y', function(d) {
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v>c) {
                    v = c;
                }
                if (v<0) {
                    v = 0;
                }

                return c - v ;

            })
            ;
    }

    function make_cell(obj) {

        var data = obj.data;
        var idx_x = obj.position_idx-1;
        var idx_y = obj.idx_y;

        var yscale = obj.yscale || cell_yscale;

        var bc = obj.bc || bar_color;

        var c = -yscale(0) + yscale(yscale.domain()[1]);

        var child_svg = svg.append('g')
            .attr('transform', function() {

                var dx = (cell_width + cell_horizontal_buffer)*idx_x;
                var dy = (cell_height + cell_vertical_buffer)*idx_y;

                var s = 'translate (';
                s += dx.toString();
                s += ',';
                s += dy.toString();
                s += ')';
                return s;
            });

        var k = 'rect-' + idx_y.toString() + '-' + obj.position_idx.toString();

        var e = child_svg.selectAll('.' + k)
            .data([]);

        //e.exit().remove();
        //e = child_svg.selectAll('.' + k)
        //    .data(data);

        var rect_width = cell_xscale(2) - cell_xscale(1);
        child_svg.selectAll('.' + k)
        .data(data)
            .enter().append('rect')
            .attr('class', k)
            .attr('width', rect_width)
            .attr('height', function(d) {
                //console.log(d, cell_yscale(d.value));
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = -v;
                }
                if (v>c) {
                    v = c;
                }
                return v;
            })
            .attr('x', function(d) {
                return cell_xscale(d.lineup_idx);
            })
            .attr('y', function(d) {
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v>c) {
                    v = c;
                }
                if (v<0) {
                    v = 0;
                }
                return c - v ;
            })
            .attr('fill', bc)
            .style('opacity', 0.5)
            .attr('stroke-width', 1)
            .attr('stroke', 'black')
            .attr('cursor', 'pointer')
            .on('mouseover', function() {
                //set_game_text(d);
            });

        child_svg.append('rect')
            .attr('width', cell_width)
            .attr('height', cell_height)
            .style('fill', 'none')
            .style('stroke', '#332222')
        ;

        if (obj.position_idx === 1) {
            child_svg.append('text')
                .text(obj.label)
                .style('font-size', 10)
                .attr('text-anchor', 'middle')
                .attr('transform', function () {
                    var dx = -10;
                    var dy = parseInt(0.5 * cell_height);
                    var s = 'translate(' + dx + ',' + dy + ')';
                    s += ' rotate(-90, -10, ' + dy + ')' ;

                    return 'rotate(-90, -5, ' + dy + ')';
                })
                .attr('x', -5)
                .attr('y', parseInt(.5*cell_height))
            ;
        }

        if (idx_y === 0) {
            child_svg.append('text')
                .attr('x', parseInt(0.5* cell_width))
                .attr('y', -4)
                .attr('text-anchor', 'middle')
                .text(position_string[obj.position_idx])
                .style('font-size', 10)
        }
    }

    function update_row(year) {
        //console.log('mouseover!', year);
        make_row(data[year], 1, true);
        make_row(data_delta[year], 2, true, 'red', diff_yscale);
        update_year_label(year);
    }

    var lookup_table = {};
    data['all'].forEach(function(d) {
        var k = d.position_idx.toString() + '-' + d.lineup_idx.toString();
        lookup_table[k] = d.value;
    })

    data_delta = {};
    _.forEach(_.range(MIN_YEAR, MAX_YEAR), function(year) {
        data_delta[year] = [];
        _.forEach(data[year], function(d) {
            var k = d.position_idx.toString() + '-' + d.lineup_idx.toString();
            var tmp = {lineup_idx: d.lineup_idx, position_idx: d.position_idx, value: d.value-lookup_table[k]};
            data_delta[year].push(tmp);
        })
    });

    function update_year_label(year) {
        svg.select('.year-label')
            .text(year);
    }

    function make_year_label() {
        svg.append('text')
            .attr('x', year_label_xoff)
            .attr('y', year_label_yoff)
            .style('font-size', 20)
            .text('1913')
            .attr('class', 'year-label')
        ;
    }

    function make_year_fixed_labels() {

        svg.append('text')
            .attr('x', year_label_xoff_f1)
            .attr('y', year_label_yoff_f1)
            .style('font-size', 14)
            .text('2014')
        ;

        svg.append('text')
            .attr('x', year_label_xoff_f2)
            .attr('y', year_label_yoff_f2)
            .style('font-size', 14)
            .text('1913')
        ;
    }

    function make_orientation_labels() {

        svg.append('text')
            .attr('x', 100)
            .attr('y', 200)
            .style('font-size', 12)
            .text('alpha')
            .attr('class', 'alpha-label')
        ;

        svg.append('text')
            .attr('x', 100)
            .attr('y', 225)
            .style('font-size', 12)
            .text('beta')
            .attr('class', 'beta-label')
        ;

        svg.append('text')
            .attr('x', 100)
            .attr('y', 250)
            .style('font-size', 12)
            .style('fill', 'red')
            .text('gamma' + '  yr:' + highlighted_year)

            .attr('class', 'gamma-label')
        ;

        //svg.append('text')
        //    .attr('x', 100)
        //    .attr('y', 350)
        //    .style('font-size', 14)
        //    .text('argval')
        //    .attr('class', 'argval-label')
        //;

    }

    make_orientation_labels();

    make_year_label();
    make_year_fixed_labels();
    make_row(data['all'], 0, false);
    make_row(data[1913], 1, false);
    make_row(data_delta[1913], 2, false, 'red', diff_yscale);

    make_brush();

    svg.append('text')
        .attr('x', 140)
        .attr('y', -30)
        .text('view on mobile (landscape) to use interaction')
        .attr('class', 'warn-text')
    ;
    function handleOrientation(event) {
        var alpha = event.alpha;
        var beta = event.beta;  // In degree in the range [-180,180]
        var gamma = event.gamma; // In degree in the range [-90,90]

        if (typeof gamma === typeof undefined || gamma === null) {
            return ;
        }

        svg.select('.warn-text')
            .transition()
            .duration(5000)
            .style('opacity', 0)
        ;

        var sign = gamma > 0  ? +1 : -1;
        var absval = Math.abs(gamma);

        if (absval < 40) {
            absval = 40;
        }

        var argval = sign * (90 - absval);
        var this_year = parseInt(beta_scale(argval));
        update_row(this_year);
        if (highlighted_year > 0 && highlighted_year !== this_year) {
            svg.select('.brusher-rect-' + highlighted_year)
                .attr('fill', bar_color)
            ;
            svg.select('.brusher-rect-' + this_year)
                .attr('fill', bright_orange)
            ;
        }
        highlighted_year = this_year;

        d3.select('.alpha-label').text('ALPHA: ' + parseInt(alpha));
        d3.select('.beta-label').text('BETA: ' + parseInt(beta));
        d3.select('.gamma-label').text('GAMMA: ' + parseInt(gamma) + ' ' + highlighted_year);
    //    d3.select('.argval-label').text('ARGVAL: ' + argval.toFixed(2));
    }

    window.addEventListener('deviceorientation', handleOrientation);
    //window.addEventListener('devicemotion', handleOrientation);

});<commit_msg>usage message transition<commit_after>

var bar_color = '#045a8d';
var bright_orange = '#fd8d3c';

var margin = {top: 120, right: 80, bottom: 20, left: 100};

var cell_width = 60;
var cell_height = 50;
var cell_rows = 10;
var cell_columns = 10;
var cell_vertical_buffer = 0;
var cell_horizontal_buffer = 0;

var brush_xoff = 625;
var brush_yoff = 0;

var brush_height = 600;
var brush_width = 50;

var year_label_xoff = 550;
var year_label_yoff = 200;

var year_label_xoff_f1 = 685;
var year_label_xoff_f2 = 685;

var year_label_yoff_f1 = 10;
var year_label_yoff_f2 = 505;

var MIN_YEAR = 1913;
var MAX_YEAR = 2014;

var width = cell_columns*cell_width - margin.left - margin.right;

var width = 1200;
var height = 800 - margin.top - margin.bottom;

var beta_scale = d3.scale.linear()
    .range([MIN_YEAR, MAX_YEAR])
    .domain([-50, 50]);

var diff_yscale = d3.scale.linear()
        .range([-cell_height/2, +cell_height/2])
        .domain([-0.2,0.2])
    ;

var cell_yscale = d3.scale.linear()
        .range([0, cell_height])
        .domain([0,0.5])
    ;

var cell_xscale = d3.scale.ordinal()
    .rangeRoundBands([0, cell_width], 0.1)
    .domain(_.range(1, 9+1));

var cell_xaxis = d3.svg.axis()
    .orient("bottom")
    .scale(cell_xscale);

var cell_yaxis = d3.svg.axis()
    .orient("left")
    .scale(cell_yscale);

var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right + 100)
        .attr("height", height + margin.top + margin.bottom + 100)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    ;

var position_string = {
    1: 'P',
    2: 'C',
    3: '1B',
    4: '2B',
    5: '3B',
    6: 'SS',
    7: 'LF',
    8: 'CF',
    9: 'RF',
    10: 'DH'
};

var highlighted_year = -4;
var data_delta;
var warn_is_remove = false;

d3.json('lineups.json', function(data) {

//    console.log('data', data);

    var era_list = ['all', '1913-1919',
        '1920-1940', '1946-1967',
        '1973-1992', '1993-2002', '2006-2014'];

    function make_brush() {

        var brush_cell_height = parseInt(brush_height/(MAX_YEAR - MIN_YEAR + 1));
        _.forEach(_.range(MAX_YEAR, MIN_YEAR, -1), function(year, year_counter) {
            var child_svg = svg.append('g')
                .attr('transform', function() {
                    var s = 'translate(' ;
                    s += brush_xoff;
                    s += ',';
                    s += brush_yoff;
                    s += ')';
                    return s
                })
                .attr('class', 'brusher');

            child_svg.append('rect')
                .attr('height', brush_cell_height)
                .attr('width', brush_width)
                .attr('fill', bar_color)
                .style('opacity', 0.5)
                .attr('stroke-width', 1)
                .attr('stroke', 'black')
                .attr('cursor', 'pointer')
                .attr('x', 0)
                .attr('y', function() {
                    return year_counter * brush_cell_height;
                })
                .attr('class', 'brusher-rect-' + year)
                .on('mouseover', function() {
                    update_row(year);
                    d3.select(this).attr('fill', bright_orange);
                })
                .on('mouseout', function() {
                    d3.select(this).attr('fill', bar_color);
                })
            ;
        });
    }

    function make_row(data, idx_y, doup, bc, yscale) {

        var bc = bc || bar_color;
        var yscale = yscale || cell_yscale;
        var this_data = {};
        _.forEach(_.range(1, 10+1), function(position_idx) {
            this_data[position_idx] = [];
        });

        _.forEach(data, function(d) {
            var position_idx = d.position_idx;
            this_data[position_idx].push(d);
        });

        _.forEach(_.range(1, 10+1), function(position_idx) {
            //  console.log(yr, position_idx, this_data[position_idx]);
            var obj = {
                data: this_data[position_idx],
                position_idx: position_idx,
                idx_y: idx_y,
                bc: bc,
                yscale: yscale
            };
            if (doup) {
                update_cell(obj);
            } else {
                make_cell(obj)
            }
        })

    }

    function update_cell(obj) {

        var data = obj.data;
        var idx_y = obj.idx_y;

        var yscale = obj.yscale || cell_yscale;
        var c = -yscale(0) + yscale(yscale.domain()[1]);
        var k = 'rect-' + idx_y.toString() + '-' + obj.position_idx.toString();

        svg.selectAll('.' + k)
            .data(data)
            .transition()
            .duration(10)
            .attr('height', function(d) {
                //console.log(d, cell_yscale(d.value));
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = -v;
                }

                if (v>c) {
                    v = c;
                }
                return v;
            })
            .attr('y', function(d) {
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v>c) {
                    v = c;
                }
                if (v<0) {
                    v = 0;
                }

                return c - v ;

            })
            ;
    }

    function make_cell(obj) {

        var data = obj.data;
        var idx_x = obj.position_idx-1;
        var idx_y = obj.idx_y;

        var yscale = obj.yscale || cell_yscale;

        var bc = obj.bc || bar_color;

        var c = -yscale(0) + yscale(yscale.domain()[1]);

        var child_svg = svg.append('g')
            .attr('transform', function() {

                var dx = (cell_width + cell_horizontal_buffer)*idx_x;
                var dy = (cell_height + cell_vertical_buffer)*idx_y;

                var s = 'translate (';
                s += dx.toString();
                s += ',';
                s += dy.toString();
                s += ')';
                return s;
            });

        var k = 'rect-' + idx_y.toString() + '-' + obj.position_idx.toString();

        var e = child_svg.selectAll('.' + k)
            .data([]);

        //e.exit().remove();
        //e = child_svg.selectAll('.' + k)
        //    .data(data);

        var rect_width = cell_xscale(2) - cell_xscale(1);
        child_svg.selectAll('.' + k)
        .data(data)
            .enter().append('rect')
            .attr('class', k)
            .attr('width', rect_width)
            .attr('height', function(d) {
                //console.log(d, cell_yscale(d.value));
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = -v;
                }
                if (v>c) {
                    v = c;
                }
                return v;
            })
            .attr('x', function(d) {
                return cell_xscale(d.lineup_idx);
            })
            .attr('y', function(d) {
                var v = yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v>c) {
                    v = c;
                }
                if (v<0) {
                    v = 0;
                }
                return c - v ;
            })
            .attr('fill', bc)
            .style('opacity', 0.5)
            .attr('stroke-width', 1)
            .attr('stroke', 'black')
            .attr('cursor', 'pointer')
            .on('mouseover', function() {
                //set_game_text(d);
            });

        child_svg.append('rect')
            .attr('width', cell_width)
            .attr('height', cell_height)
            .style('fill', 'none')
            .style('stroke', '#332222')
        ;

        if (obj.position_idx === 1) {
            child_svg.append('text')
                .text(obj.label)
                .style('font-size', 10)
                .attr('text-anchor', 'middle')
                .attr('transform', function () {
                    var dx = -10;
                    var dy = parseInt(0.5 * cell_height);
                    var s = 'translate(' + dx + ',' + dy + ')';
                    s += ' rotate(-90, -10, ' + dy + ')' ;

                    return 'rotate(-90, -5, ' + dy + ')';
                })
                .attr('x', -5)
                .attr('y', parseInt(.5*cell_height))
            ;
        }

        if (idx_y === 0) {
            child_svg.append('text')
                .attr('x', parseInt(0.5* cell_width))
                .attr('y', -4)
                .attr('text-anchor', 'middle')
                .text(position_string[obj.position_idx])
                .style('font-size', 10)
        }
    }

    function update_row(year) {
        //console.log('mouseover!', year);
        make_row(data[year], 1, true);
        make_row(data_delta[year], 2, true, 'red', diff_yscale);
        update_year_label(year);
    }

    var lookup_table = {};
    data['all'].forEach(function(d) {
        var k = d.position_idx.toString() + '-' + d.lineup_idx.toString();
        lookup_table[k] = d.value;
    })

    data_delta = {};
    _.forEach(_.range(MIN_YEAR, MAX_YEAR), function(year) {
        data_delta[year] = [];
        _.forEach(data[year], function(d) {
            var k = d.position_idx.toString() + '-' + d.lineup_idx.toString();
            var tmp = {lineup_idx: d.lineup_idx, position_idx: d.position_idx, value: d.value-lookup_table[k]};
            data_delta[year].push(tmp);
        })
    });

    function update_year_label(year) {
        svg.select('.year-label')
            .text(year);
    }

    function make_year_label() {
        svg.append('text')
            .attr('x', year_label_xoff)
            .attr('y', year_label_yoff)
            .style('font-size', 20)
            .text('1913')
            .attr('class', 'year-label')
        ;
    }

    function make_year_fixed_labels() {

        svg.append('text')
            .attr('x', year_label_xoff_f1)
            .attr('y', year_label_yoff_f1)
            .style('font-size', 14)
            .text('2014')
        ;

        svg.append('text')
            .attr('x', year_label_xoff_f2)
            .attr('y', year_label_yoff_f2)
            .style('font-size', 14)
            .text('1913')
        ;
    }

    function make_orientation_labels() {

        svg.append('text')
            .attr('x', 100)
            .attr('y', 200)
            .style('font-size', 12)
            .text('alpha')
            .attr('class', 'alpha-label')
        ;

        svg.append('text')
            .attr('x', 100)
            .attr('y', 225)
            .style('font-size', 12)
            .text('beta')
            .attr('class', 'beta-label')
        ;

        svg.append('text')
            .attr('x', 100)
            .attr('y', 250)
            .style('font-size', 12)
            .style('fill', 'red')
            .text('gamma' + '  yr:' + highlighted_year)

            .attr('class', 'gamma-label')
        ;

        //svg.append('text')
        //    .attr('x', 100)
        //    .attr('y', 350)
        //    .style('font-size', 14)
        //    .text('argval')
        //    .attr('class', 'argval-label')
        //;

    }

    make_orientation_labels();

    make_year_label();
    make_year_fixed_labels();
    make_row(data['all'], 0, false);
    make_row(data[1913], 1, false);
    make_row(data_delta[1913], 2, false, 'red', diff_yscale);

    make_brush();

    svg.append('text')
        .attr('x', 140)
        .attr('y', -30)
        .text('view on mobile (landscape) to use interaction')
        .attr('class', 'warn-text')
    ;

    function warn_remove() {

        svg.select('.warn-text')
            .transition()
            .duration(5000)
            .style('opacity', 0)
        ;

    }

    function handleOrientation(event) {
        var alpha = event.alpha;
        var beta = event.beta;  // In degree in the range [-180,180]
        var gamma = event.gamma; // In degree in the range [-90,90]

        if (typeof gamma === typeof undefined || gamma === null) {

            //svg.select('.warn-text')
            //    .transition()
            //    .duration(5000)
            //    .style('opacity', 0)
            //;

            return ;
        }

        if (! warn_is_remove) {
            warn_is_remove = true;
            warn_remove();
        }

        var sign = gamma > 0  ? +1 : -1;
        var absval = Math.abs(gamma);

        if (absval < 40) {
            absval = 40;
        }

        var argval = sign * (90 - absval);
        var this_year = parseInt(beta_scale(argval));
        update_row(this_year);
        if (highlighted_year > 0 && highlighted_year !== this_year) {
            svg.select('.brusher-rect-' + highlighted_year)
                .attr('fill', bar_color)
            ;
            svg.select('.brusher-rect-' + this_year)
                .attr('fill', bright_orange)
            ;
        }
        highlighted_year = this_year;

        d3.select('.alpha-label').text('ALPHA: ' + parseInt(alpha));
        d3.select('.beta-label').text('BETA: ' + parseInt(beta));
        d3.select('.gamma-label').text('GAMMA: ' + parseInt(gamma) + ' ' + highlighted_year);
    //    d3.select('.argval-label').text('ARGVAL: ' + argval.toFixed(2));
    }

    window.addEventListener('deviceorientation', handleOrientation);
    //window.addEventListener('devicemotion', handleOrientation);

});<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc service
 * @name uiAccordion.accordionGroup
 * @description
 * # accordionGroup
 * Service in the uiAccordion.
 */
angular.module('uiAccordion')
  .service('accordionGroup', function ($q,$log) {
    function AccordionGroup() {
    }
    function noopPromise() {
      var def = $q.defer();
      def.resolve();
      return def.promise;
    }

    AccordionGroup.prototype.$animate = function (animationFn, action, callback) {
      var _self = this;
      $q.when(_self.options[action]()).then(function () {
        _self.options[callback].call(_self, animationFn);
      }, errorlogger);
    };
    function errorlogger(error) {
      $log.error(error);
    }
    return {
      createAccordionGrp:function(){
        return new AccordionGroup();
      },
      defaultAccordionGroupOptions:function () {
        return {
          open: false,
          disabled: false,
          beforeOpen: noopPromise,
          beforeHide: noopPromise,
          animateOpen: function (animationFn) {
            this.body[animationFn]('slow');
          },
          animateClose: function (animationFn) {
            this.body[animationFn]();
          }
        };
      }
    };
  });
<commit_msg>Resolving issue with 'this.body'<commit_after>'use strict';

/**
 * @ngdoc service
 * @name uiAccordion.accordionGroup
 * @description
 * # accordionGroup
 * Service in the uiAccordion.
 */
angular.module('uiAccordion')
  .service('accordionGroup', function ($q,$log) {
    function AccordionGroup() {
    }
    function noopPromise() {
      var def = $q.defer();
      $timeout(function(){
        def.resolve('');
      });
      return def.promise;
    }

    AccordionGroup.prototype.$animate = function (animationFn, action, callback) {
      var _self = this;
      $q.when(_self.options[action]()).then(function () {
        _self.options[callback].call(_self, animationFn);
      }, errorlogger);
    };
    function errorlogger(error) {
      $log.error(error);
    }
    return {
      createAccordionGrp:function(){
        return new AccordionGroup();
      },
      defaultAccordionGroupOptions:function () {
        return {
          open: false,
          disabled: false,
          beforeOpen: noopPromise,
          beforeHide: noopPromise,
          animateOpen: function (animationFn) {
            this.body[animationFn]('slow');
          },
          animateClose: function (animationFn) {
            this.body[animationFn]();
          }
        };
      }
    };
  });
<|endoftext|>