<commit_before>UI.body.helpers({
  spacebarState: function() {
    return Session.get('spacebarToggleState') ? 'true' : 'false';
  },
  mouseXState: function() {
    return Session.get('mouseX') * 10 || '0';
  },
  mouseYState: function() {
    return Session.get('mouseY') * 10 || '0';
  },
  reticleState: function() {
    return Session.get('spacebarToggleState') ? 'active' : '';
  }
});

UI.body.rendered = function() {
  // The global application namespace.
  window.App = window.App || {};

  // Grab the main game container.
  App.container = $(document);

  // Initialize listeners for keyboard events.
  App.keyInit();

  // Another namespace to hold all the graphics stuff.
  App.three = App.three || App.THREEinit();

  // App.player is a THREE group containing the ship, the reticle,
  // and the camera.
  App.player = new THREE.Object3D();
  App.player.camera = App.three.camera;
  App.player.add(App.player.camera);

  App.three.scene.add(new THREE.AxisHelper(20));

  App.player.move = function(direction) {
    var distance = 0.1;

    var dir;

    switch(direction) {
    case 'left':
      dir = new THREE.Vector3(distance, 0, 0);
      break;
    case 'right':
      dir = new THREE.Vector3(-distance, 0, 0);
      break;
    case 'up':
      dir = new THREE.Vector3(0, 0, distance);
      break;
    case 'down':
      dir = new THREE.Vector3(0, 0, -distance);
      break;
    }

    var matrix = new THREE.Matrix4();
    matrix.extractRotation(this.matrix);

    dir = dir.applyProjection(matrix);

    this.position.x += dir.x;
    this.position.y += dir.y;
    this.position.z += dir.z;

    this.update();
  };

  App.player.update = function() {
    playerStream.emit('updatePlayerPosition', this.position);
    App.triggerEvent('playerChanged', this.position);
  };

  App.player.reset = function() {
    this.position = new THREE.Vector3();
  };

  playerStream.on('updatePlayerPosition', function(position) {
    App.player.position = position;

    App.triggerEvent('playerChanged', position);
  });

  playerStream.on('updatePlayerRotation', function(cacat) {
    App.player.rotate(cacat.direction, cacat.angle);
  });

  App.player.rotate = function(direction, angle) {
    var axis;

    switch(direction) {
    case 'left':
    case 'right':
      axis = new THREE.Vector3(0, 1, 0);
      break;
    case 'up':
    case 'down':
      axis = new THREE.Vector3(1, 0, 0);
      break;
    }

    this.rotateOnAxis(axis, angle);
  };

  // Initialize easter egg.
  App.easterEgg.init();

  // Initialize touchscreen gestures.
  App.hammerInit();

  Players.find().observe({
    added: function(player) {
      App.player._id = player._id;
      App.player.position = player.position;

      App.triggerEvent('playerAdded', App.player);

      THREEx.SpaceShips.loadSpaceFighter03(function(object3d) {
        var ship = object3d;

        App.player.ship = ship;
        App.player.add(ship);

        App.player.camera.position.x = ship.position.x + 0;
        App.player.camera.position.y = ship.position.y + 2.3;
        App.player.camera.position.z = ship.position.z - 3.5;

        App.player.reticle = new THREE.Mesh(
          new THREE.RingGeometry(0.1, 0.12, 20),
          new THREE.MeshBasicMaterial({
            color: 0xffffff,
            side: THREE.DoubleSide
          })
        );

        App.player.reticle.position.x = ship.position.x;
        App.player.reticle.position.y = ship.position.y;
        App.player.reticle.position.z = ship.position.z + 2.0;

        App.player.reticle.lookAt(App.player.camera.position);
        App.player.camera.lookAt(App.player.reticle.position);

        App.player.add(App.player.reticle);

        App.three.scene.add(App.player);

        App.triggerEvent('playerLoaded', App.player);

        setInterval(function() {
          var player = _.pick(App.player, '_id', 'position');
          Players.update(player._id, player);
        }, 500);
      });
    }
  });

  App.three.onRenderFcts.push(function() {
    if (App.player.ship) {
      if (App.keyState('left') || App.keyState('a')) {
        App.player.move('left');
      }

      if (App.keyState('right') || App.keyState('d')) {
        App.player.move('right');
      }

      if (App.keyState('up') || App.keyState('w')) {
        App.player.move('up');
      }

      if (App.keyState('down') || App.keyState('s')) {
        App.player.move('down');
      }
    }
  });

  // Camera Controls.
  var mouse = {
    x: 0,
    y: 0
  };

  document.addEventListener('mousemove', function(event) {
    mouse.x = (event.clientX / window.innerWidth) - 0.5;
    Session.set('mouseX', mouse.x);

    mouse.y = (event.clientY / window.innerHeight) - 0.5;
    Session.set('mouseY', mouse.y);
  }, false);

  App.three.onRenderFcts.push(function() {
    if (App.player.ship) {
      if (App.keyToggleState('spacebar')) {
        var x = Session.get('mouseX');

        var angle = (Math.PI / 180) * (Math.abs(x) * 5);

        if (x < 0) {
          App.player.rotate('left', angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: angle, direction: 'left' }
          );
        } else {
          App.player.rotate('right', -angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: angle, direction: 'right' }
          );
        }

        var y = Session.get('mouseY');

        angle = (Math.PI / 180) * (Math.abs(y) * 5);

        if (y < 0) {
          App.player.rotate('up', -angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: angle, direction: 'up' }
          );
        } else {
          App.player.rotate('down', angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: angle, direction: 'down' }
          );
        }
      } else {
        // TODO: While the space key is not held down, slowly transition
        // the ship back to horizontal orientation.
      }
    }
  });
};
<commit_msg>Fix rotation angles.<commit_after>UI.body.helpers({
  spacebarState: function() {
    return Session.get('spacebarToggleState') ? 'true' : 'false';
  },
  mouseXState: function() {
    return Session.get('mouseX') * 10 || '0';
  },
  mouseYState: function() {
    return Session.get('mouseY') * 10 || '0';
  },
  reticleState: function() {
    return Session.get('spacebarToggleState') ? 'active' : '';
  }
});

UI.body.rendered = function() {
  // The global application namespace.
  window.App = window.App || {};

  // Grab the main game container.
  App.container = $(document);

  // Initialize listeners for keyboard events.
  App.keyInit();

  // Another namespace to hold all the graphics stuff.
  App.three = App.three || App.THREEinit();

  // App.player is a THREE group containing the ship, the reticle,
  // and the camera.
  App.player = new THREE.Object3D();
  App.player.camera = App.three.camera;
  App.player.add(App.player.camera);

  App.three.scene.add(new THREE.AxisHelper(20));

  App.player.move = function(direction) {
    var distance = 0.1;

    var dir;

    switch(direction) {
    case 'left':
      dir = new THREE.Vector3(distance, 0, 0);
      break;
    case 'right':
      dir = new THREE.Vector3(-distance, 0, 0);
      break;
    case 'up':
      dir = new THREE.Vector3(0, 0, distance);
      break;
    case 'down':
      dir = new THREE.Vector3(0, 0, -distance);
      break;
    }

    var matrix = new THREE.Matrix4();
    matrix.extractRotation(this.matrix);

    dir = dir.applyProjection(matrix);

    this.position.x += dir.x;
    this.position.y += dir.y;
    this.position.z += dir.z;

    this.update();
  };

  App.player.update = function() {
    playerStream.emit('updatePlayerPosition', this.position);
    App.triggerEvent('playerChanged', this.position);
  };

  App.player.reset = function() {
    this.position = new THREE.Vector3();
  };

  playerStream.on('updatePlayerPosition', function(position) {
    App.player.position = position;

    App.triggerEvent('playerChanged', position);
  });

  playerStream.on('updatePlayerRotation', function(cacat) {
    App.player.rotate(cacat.direction, cacat.angle);
  });

  App.player.rotate = function(direction, angle) {
    var axis;

    switch(direction) {
    case 'left':
    case 'right':
      axis = new THREE.Vector3(0, 1, 0);
      break;
    case 'up':
    case 'down':
      axis = new THREE.Vector3(1, 0, 0);
      break;
    }

    this.rotateOnAxis(axis, angle);
  };

  // Initialize easter egg.
  App.easterEgg.init();

  // Initialize touchscreen gestures.
  App.hammerInit();

  Players.find().observe({
    added: function(player) {
      App.player._id = player._id;
      App.player.position = player.position;

      App.triggerEvent('playerAdded', App.player);

      THREEx.SpaceShips.loadSpaceFighter03(function(object3d) {
        var ship = object3d;

        App.player.ship = ship;
        App.player.add(ship);

        App.player.camera.position.x = ship.position.x + 0;
        App.player.camera.position.y = ship.position.y + 2.3;
        App.player.camera.position.z = ship.position.z - 3.5;

        App.player.reticle = new THREE.Mesh(
          new THREE.RingGeometry(0.1, 0.12, 20),
          new THREE.MeshBasicMaterial({
            color: 0xffffff,
            side: THREE.DoubleSide
          })
        );

        App.player.reticle.position.x = ship.position.x;
        App.player.reticle.position.y = ship.position.y;
        App.player.reticle.position.z = ship.position.z + 2.0;

        App.player.reticle.lookAt(App.player.camera.position);
        App.player.camera.lookAt(App.player.reticle.position);

        App.player.add(App.player.reticle);

        App.three.scene.add(App.player);

        App.triggerEvent('playerLoaded', App.player);

        setInterval(function() {
          var player = _.pick(App.player, '_id', 'position');
          Players.update(player._id, player);
        }, 500);
      });
    }
  });

  App.three.onRenderFcts.push(function() {
    if (App.player.ship) {
      if (App.keyState('left') || App.keyState('a')) {
        App.player.move('left');
      }

      if (App.keyState('right') || App.keyState('d')) {
        App.player.move('right');
      }

      if (App.keyState('up') || App.keyState('w')) {
        App.player.move('up');
      }

      if (App.keyState('down') || App.keyState('s')) {
        App.player.move('down');
      }
    }
  });

  // Camera Controls.
  var mouse = {
    x: 0,
    y: 0
  };

  document.addEventListener('mousemove', function(event) {
    mouse.x = (event.clientX / window.innerWidth) - 0.5;
    Session.set('mouseX', mouse.x);

    mouse.y = (event.clientY / window.innerHeight) - 0.5;
    Session.set('mouseY', mouse.y);
  }, false);

  App.three.onRenderFcts.push(function() {
    if (App.player.ship) {
      if (App.keyToggleState('spacebar')) {
        var x = Session.get('mouseX');

        var angle = (Math.PI / 180) * (Math.abs(x) * 5);

        if (x < 0) {
          App.player.rotate('left', angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: angle, direction: 'left' }
          );
        } else {
          App.player.rotate('right', -angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: -angle, direction: 'right' }
          );
        }

        var y = Session.get('mouseY');

        angle = (Math.PI / 180) * (Math.abs(y) * 5);

        if (y < 0) {
          App.player.rotate('up', -angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: -angle, direction: 'up' }
          );
        } else {
          App.player.rotate('down', angle);
          playerStream.emit(
            'updatePlayerRotation',
            { angle: angle, direction: 'down' }
          );
        }
      } else {
        // TODO: While the space key is not held down, slowly transition
        // the ship back to horizontal orientation.
      }
    }
  });
};
<|endoftext|>


<commit_before>var main = function () {
    "use strict";

    document.cookie="paul's cookie is here";
    runPrelude();

    function runPrelude () {
        var root = new RootObject();
        root.htmlObject().createPreludeHolder();
        $(".prelude_holder button").on("click", function() {
            root.setMyName($(".prelude_holder input").val());
            root.setLanguageUsed($(".prelude_holder select").val());
            console.log("runPrelude() ", "name=" + root.myName() + " language=" + root.languageUsed());
            if (root.myName()) {
                root.ajaxObject().setupLink(setupLinkCallback, root);
            }
        });
    }

    function setupLinkCallback (root_val) {
        var session = new SessionObject(root_val);
        root_val.ajaxObject().getNameList(getNameListCallback, session);
    }

    function getNameListCallback (session_val) {
        runCreateSession(session_val);
    }

    function runCreateSession (session_val) {
        session_val.rootObject().htmlObject().createSessionHolders(session_val.rootObject());
        $(".peer_paragraph button").on("click", function() {
            session_val.setHisName($(".peer_section select").val());
            console.log("runCreateSession() ", "peer_name=" + session_val.hisName());
            session_val.ajaxObject().getNameList(getNameListCallback, session_val);
        });
        $(".peer_connect_section button").on("click", function() {
            session_val.setHisName($(".peer_section select").val());
            console.log("runCreateSession() ", "peer_name=" + session_val.hisName());
            session_val.ajaxObject().initiateSessionConnection(setupSessionCallback, session_val);
        });
    }

    function setupSessionCallback (session_val) {
        var container = new GoContainerObject(session_val);
        runGoConfig(container);
    }

    function runGoConfig (container_val) {
        var config = container_val.configObject();
        container_val.rootObject().htmlObject().createConfigHolders();
        $(".config_holder button").on("click", function() {
            config.setBoardSize($(".board_size_section select").val());
            config.setMyColor($(".play_color_section select").val());
            config.setKomiPoint($(".komi_section select").val());
            config.setHandicapPoint($(".handicap_section select").val());
            console.log("runConfig() ", " board_size=" + config.boardSize() +
                            " color=" + config.myColor() +
                            " komi=" + config.komiPoint() +
                            " handicap=" + config.handicapPoint());
            runGoGame(container_val);
        });
    }

    function runGoGame (container_val) {
        container_val.startGoGame();
        container_val.rootObject().htmlObject().createPlayHolders();
        container_val.uiObject().initElements();
        container_val.uiObject().drawBoard(container_val.engineObject());

        $("canvas").on("click", function(event) {
            container_val.uiObject().uiClickApi(event.clientX, event.clientY);
        });

        $("canvas").on("mousemove", function(event) {
            container_val.uiObject().uiMouseMove(event.clientX, event.clientY);
        });

        var addCommentFromInputBox = function () {
            var $new_comment = $("<p>");
            if ($(".comment-input input").val() !== "") {
                $new_comment.text($(".comment-input input").val());
                $new_comment.hide();
                $(".comments").append($new_comment);
                $new_comment.fadeIn();
                $(".comment-input input").val("");
            }
        };

        $(".comment-input button").on("click", function(event) {
            addCommentFromInputBox();
        });

        $(".comment-input input").on("keypress", function(event) {
            if (event.keyCode == 13) {
                addCommentFromInputBox();
            }
        });
    }
};

$(document).ready(main);

<commit_msg>timer<commit_after>var main = function () {
    "use strict";

    document.cookie="paul's cookie is here";
    runPrelude();

    function runPrelude () {
        var root = new RootObject();
        root.htmlObject().createPreludeHolder();
        $(".prelude_holder button").on("click", function() {
            root.setMyName($(".prelude_holder input").val());
            root.setLanguageUsed($(".prelude_holder select").val());
            console.log("runPrelude() ", "name=" + root.myName() + " language=" + root.languageUsed());
            if (root.myName()) {
                root.ajaxObject().setupLink(setupLinkCallback, root);
            }
        });
    }

    function updateTimer () {
        console.log("updataTimer");
    }

    function setupLinkCallback (root_val) {
        window.setInterval(updateTimer, 1000);
        var session = new SessionObject(root_val);
        root_val.ajaxObject().getNameList(getNameListCallback, session);
    }

    function getNameListCallback (session_val) {
        runCreateSession(session_val);
    }

    function runCreateSession (session_val) {
        session_val.rootObject().htmlObject().createSessionHolders(session_val.rootObject());
        $(".peer_paragraph button").on("click", function() {
            session_val.setHisName($(".peer_section select").val());
            console.log("runCreateSession() ", "peer_name=" + session_val.hisName());
            session_val.ajaxObject().getNameList(getNameListCallback, session_val);
        });
        $(".peer_connect_section button").on("click", function() {
            session_val.setHisName($(".peer_section select").val());
            console.log("runCreateSession() ", "peer_name=" + session_val.hisName());
            session_val.ajaxObject().initiateSessionConnection(setupSessionCallback, session_val);
        });
    }

    function setupSessionCallback (session_val) {
        var container = new GoContainerObject(session_val);
        runGoConfig(container);
    }

    function runGoConfig (container_val) {
        var config = container_val.configObject();
        container_val.rootObject().htmlObject().createConfigHolders();
        $(".config_holder button").on("click", function() {
            config.setBoardSize($(".board_size_section select").val());
            config.setMyColor($(".play_color_section select").val());
            config.setKomiPoint($(".komi_section select").val());
            config.setHandicapPoint($(".handicap_section select").val());
            console.log("runConfig() ", " board_size=" + config.boardSize() +
                            " color=" + config.myColor() +
                            " komi=" + config.komiPoint() +
                            " handicap=" + config.handicapPoint());
            runGoGame(container_val);
        });
    }

    function runGoGame (container_val) {
        container_val.startGoGame();
        container_val.rootObject().htmlObject().createPlayHolders();
        container_val.uiObject().initElements();
        container_val.uiObject().drawBoard(container_val.engineObject());

        $("canvas").on("click", function(event) {
            container_val.uiObject().uiClickApi(event.clientX, event.clientY);
        });

        $("canvas").on("mousemove", function(event) {
            container_val.uiObject().uiMouseMove(event.clientX, event.clientY);
        });

        var addCommentFromInputBox = function () {
            var $new_comment = $("<p>");
            if ($(".comment-input input").val() !== "") {
                $new_comment.text($(".comment-input input").val());
                $new_comment.hide();
                $(".comments").append($new_comment);
                $new_comment.fadeIn();
                $(".comment-input input").val("");
            }
        };

        $(".comment-input button").on("click", function(event) {
            addCommentFromInputBox();
        });

        $(".comment-input input").on("keypress", function(event) {
            if (event.keyCode == 13) {
                addCommentFromInputBox();
            }
        });
    }
};

$(document).ready(main);

<|endoftext|>


<commit_before>import Video from 'twilio-video';

Template.videoChat.onDestroyed(function (event, template) {
  event.preventDefault();
  if (template.room) {
    template.room.disconnect();
  }
});

Template.videoChat.onCreated(function (){
   this.mutedVariable = new ReactiveVar(null);
   this.cameraDisabledVariable = new ReactiveVar(null);
   this.previewVariable = new ReactiveVar(null);
   this.callStartedVariable = new ReactiveVar(null);
   this.mediaAttachedVarirable =  new ReactiveVar(null);
});

Template.videoChat.onRendered(function (){
   this.mutedVariable.set(false);
   this.cameraDisabledVariable.set(false);
   this.previewVariable.set(false);
   this.callStartedVariable.set(false);
   this.mediaAttachedVarirable.set(false);
});

Template.videoChat.helpers({
  twilioVideoNotSupportedByBrowser: function(){
    return (!navigator.webkitGetUserMedia && !navigator.mozGetUserMedia)
  },
  theClientIsMuted: function(){
    return (Template.instance().mutedVariable.get())
  },
  theCameraIsDisabled: function(){
    return (Template.instance().cameraDisabledVariable.get())
  },
  inPreviewMode: function () {
    return (Template.instance().previewVariable.get())
  },
  theCallStarted: function(){
    return (Template.instance().callStartedVariable.get())
  },
  theMediaIsAttached: function(){
    return (Template.instance().mediaAttachedVarirable.get())
  }
});

Template.videoChat.events({
  'submit #js-request-video-chat': function (event, template) {
    event.preventDefault();
    const target = event.target;
    const roomName = target.text.value;
    let initAccessToken;
    let accessToken;

    initAccessToken = Meteor.call(
      "requestVideoChatAccess", roomName,
      function requestVideoChatAccessCallback(error, result) {
        let localMediaPreview = null;
        if (error) {
          console.log(error, error.reson);
        }
        if (result) {
          accessToken = result;
          template.client = new Video.Client(accessToken.token);
          if (template.localMedia) {
            localMediaPreview = template.localMedia;
          }else {
            template.localMedia = new Video.LocalMedia();
            Video.getUserMedia().then(
              function (mediaStream) {
                template.localMedia.addStream(mediaStream);
                template.mediaAttachedVarirable.set(true);
              },
            function (error){
              console.log('LocalMedia error', error);
            })
          }
          room = template.client.connect({
            to: roomName,
            localMedia: localMediaPreview,
            audio: ( ! template.mutedVariable.get()),
            video: ( ! template.cameraDisabledVariable.get())
          })
          .then(
            room => {
              template.localMedia.attach('#local-media');

              room.participants.forEach(function(participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantConnected', function (participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantDisconnected', function(participant) {
                participant.media.detach();
              });

              room.on('disconnected', function () {
                room.localParticipant.media.detach();
                room.participants.forEach(function(participant) {
                  participant.media.detach();
                });
              });
              template.room = room;
              template.callStartedVariable.set(true);
            }
          )
        }
    })
  },
  "click #js-end-video-chat" : function (event, template){
    event.preventDefault();
    if (template.room) {
      template.room.disconnect();
      template.callStartedVariable.set(false);
    }
  },
  "click #js-mute-video-chat" : function (event, template) {
    event.preventDefault();
    template.localMedia.mute();
    if (template.localMedia) {
      template.localMedia.mute();
      if (template.localMedia.isMuted) {
      template.mutedVariable.set(true);
      }
    }
  },
  "click #js-unmute-video-chat" : function (event, template){
    event.preventDefault();
    template.localMedia.unmute();
    if (template.localMedia) {
      template.localMedia.unmute();
      if ( ! template.localMedia.isMuted) {
      template.mutedVariable.set(false);
      }
    }
  },
  "click #js-disable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      const localVideoTrack = template.localMedia.removeCamera();
      template.cameraDisabledVariable.set(true);
    }
  },
  "click #js-enable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      template.localMedia.addCamera().then(
        function(localVideoTrack){
          if (localVideoTrack.mediaStream.active) {
            template.cameraDisabledVariable.set(false);
          }
        },
        function (error){
          console.log('LocalMedia error', error);
        }
      )
    }
  },
  "click #js-preview-camera": function (event, template) {
    event.preventDefault();
    if( (! template.client) && ( ! template.localMedia)){
      template.localMedia = new Video.LocalMedia();
      Video.getUserMedia().then(
        function (mediaStream) {
          template.localMedia.addStream(mediaStream);
          template.localMedia.attach('#local-media');
          template.previewVariable.set(true);
          template.mediaAttachedVarirable.set(true);
        },
      function (error){
        console.log('LocalMedia error', error);
      })
    }
  }
});
<commit_msg>code style<commit_after>import Video from 'twilio-video';

Template.videoChat.onDestroyed(function (event, template) {
  event.preventDefault();
  if (template.room) {
    template.room.disconnect();
  }
});

Template.videoChat.onCreated(function (){
   this.mutedVariable = new ReactiveVar(null);
   this.cameraDisabledVariable = new ReactiveVar(null);
   this.previewVariable = new ReactiveVar(null);
   this.callStartedVariable = new ReactiveVar(null);
   this.mediaAttachedVarirable =  new ReactiveVar(null);
});

Template.videoChat.onRendered(function (){
   this.mutedVariable.set(false);
   this.cameraDisabledVariable.set(false);
   this.previewVariable.set(false);
   this.callStartedVariable.set(false);
   this.mediaAttachedVarirable.set(false);
});

Template.videoChat.helpers({
  twilioVideoNotSupportedByBrowser: function(){
    return (!navigator.webkitGetUserMedia && !navigator.mozGetUserMedia)
  },
  theClientIsMuted: function(){
    return (Template.instance().mutedVariable.get())
  },
  theCameraIsDisabled: function(){
    return (Template.instance().cameraDisabledVariable.get())
  },
  inPreviewMode: function () {
    return (Template.instance().previewVariable.get())
  },
  theCallStarted: function(){
    return (Template.instance().callStartedVariable.get())
  },
  theMediaIsAttached: function(){
    return (Template.instance().mediaAttachedVarirable.get())
  }
});

Template.videoChat.events({
  'submit #js-request-video-chat': function (event, template) {
    event.preventDefault();
    const target = event.target;
    const roomName = target.text.value;
    let initAccessToken;
    let accessToken;

    initAccessToken = Meteor.call(
      "requestVideoChatAccess", roomName,
      function requestVideoChatAccessCallback(error, result) {
        let localMediaPreview = null;
        if (error) {
          console.log(error, error.reson);
        }
        if (result) {
          accessToken = result;
          template.client = new Video.Client(accessToken.token);
          if (template.localMedia) {
            localMediaPreview = template.localMedia;
          }else {
            template.localMedia = new Video.LocalMedia();
            Video.getUserMedia().then(
              function (mediaStream) {
                template.localMedia.addStream(mediaStream);
                template.mediaAttachedVarirable.set(true);
              },
            function (error){
              console.log('LocalMedia error', error);
            })
          }
          room = template.client.connect({
            to: roomName,
            localMedia: localMediaPreview,
            audio: ( ! template.mutedVariable.get()),
            video: ( ! template.cameraDisabledVariable.get())
          })
          .then(
            room => {
              template.localMedia.attach('#local-media');

              room.participants.forEach(function(participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantConnected', function (participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantDisconnected', function(participant) {
                participant.media.detach();
              });

              room.on('disconnected', function () {
                room.localParticipant.media.detach();
                room.participants.forEach(function(participant) {
                  participant.media.detach();
                });
              });
              template.room = room;
              template.callStartedVariable.set(true);
            }
          )
        }
    })
  },
  "click #js-end-video-chat" : function (event, template){
    event.preventDefault();
    if (template.room) {
      template.room.disconnect();
      template.callStartedVariable.set(false);
    }
  },
  "click #js-mute-video-chat" : function (event, template) {
    event.preventDefault();
    template.localMedia.mute();
    if (template.localMedia) {
      template.localMedia.removeMicrophone()
      console.log(template.localMedia);
      // template.localMedia.mute();
      // if (template.localMedia.isMuted) {
      template.mutedVariable.set(true);
      // }
    }
  },
  "click #js-unmute-video-chat" : function (event, template){
    event.preventDefault();
    template.localMedia.unmute();
    if (template.localMedia) {
      template.localMedia.addMicrophone()
      console.log(template.localMedia);
      // template.localMedia.unmute();
      // if ( ! template.localMedia.isMuted) {
      template.mutedVariable.set(false);
      // }
    }
  },
  "click #js-disable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      const localVideoTrack = template.localMedia.removeCamera();
      template.cameraDisabledVariable.set(true);
    }
  },
  "click #js-enable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      template.localMedia.addCamera().then(
        function(localVideoTrack){
          if (localVideoTrack.mediaStream.active) {
            template.cameraDisabledVariable.set(false);
          }
        },
        function (error){
          console.log('LocalMedia error', error);
        }
      )
    }
  },
  "click #js-preview-camera": function (event, template) {
    event.preventDefault();
    if( (! template.client) && ( ! template.localMedia)){
      template.localMedia = new Video.LocalMedia();
      Video.getUserMedia().then(
        function (mediaStream) {
          template.localMedia.addStream(mediaStream);
          template.localMedia.attach('#local-media');
          template.previewVariable.set(true);
          template.mediaAttachedVarirable.set(true);
        },
      function (error){
        console.log('LocalMedia error', error);
      })
    }
  }
});
<|endoftext|>


<commit_before>
// Construct map, center if no location provided
var map = L.map('map', { maxZoom: 13 } );
var hash = new L.Hash(map);
if (!window.location.hash) {
    map.setView([37.958, -120.976], 8);
}

// Make the base map; a raster tile relief map from ESRI
var esriRelief = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';

var basemap = L.tileLayer(esriRelief, {
  attribution: 'ESRI shaded relief, NHDPlus v2',
  maxZoom: 13
});
//basemap.addTo(map);

// Add a single GeoJSON vector file for state boundaries
// This was loaded statically as a script; could also be AJAX
var stateLayer = new L.geoJson(usStates);
stateLayer.setStyle({ "color": "#444",
                      "weight": 1,
                      "fill": false,
                      "opacity": 1.0 });
stateLayer.addTo(map);

var nlcdlayer = L.tileLayer('/nlcd/{z}/{x}/{y}.png',{tms:true}).addTo(map);

var requestsPool = {
  requests: {}, //list of urls
  timeouts: {},
  timeout:  1000*60*10, //In milliseconds
  fetch: function(url) {
    if(requestsPool.exists(url))
      return requestsPool.requests[url];

    requestsPool.timeouts[url] = setTimeout(function(u) {
        requestsPool.remove(u);
    }.bind(this, url), requestsPool.timeout); //Defining the timeout

    requestsPool.requests[url] = $.getJSON(url);
    return requestsPool.requests[url];
  },
  exists: function(url) {
    return requestsPool.requests.hasOwnProperty(url); //Return the Timeout ID if present or undefined
  },
  remove: function(url) {
    requestsPool.cancel(url);
    delete requestsPool.requests[url];
  },
  cancel: function(url) {
    clearTimeout(requestsPool.timeouts[url]); //cancel the timeout
    delete requestsPool.timeouts[url];
  }
}

var riverinfo = {};

function StyleTheRivers(feature){
  requestsPool.fetch('/gauges/reachflow/'+feature.properties.huc8)
  .done(function(val){
    riverinfo[feature.properties.huc8]=val;
    $('.h'+feature.properties.huc8).css('stroke', (val.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*val.drank)]:'#FF00DE' );
    $('.h'+feature.properties.huc8).css('stroke-width', ((val.drank!==null)?(6*val.drank+2).toString():'2')+'px' );
  });
}
//$.getJSON('/gauges/reachflow/'+feature.properties.huc8, function(data){

// Style the river lines; width depends on its Strahler number
function riverStyle(feature) {
  return "stroke-width: " + feature.properties.strahler * map.getZoom()/13 + "px;stroke:#FF00DE;";
}

function riverClass(feature){
  StyleTheRivers(feature);
  return "river h" + feature.properties.huc8;
}

// Make the river overlay layer, vector tiles from our TileStache/Gunicorn server
var geojsonURL = "/rivers/{z}/{x}/{y}.json";
var riverLayer = new L.TileLayer.d3_geoJSON(geojsonURL, {
  class: riverClass,
  style: riverStyle
});
map.addLayer(riverLayer);

var counties = new L.geoJson();
counties.addTo(map);
$.getJSON("/counties.json",
  function(data) {
    counties = new L.geoJson(data,{style:{
      "stroke":  "black",
      "fill":    "gray",
      "weight":  3,
      "opacity": 0.65
    }});
    counties.addTo(map);
});

map.on('dragend', function(e) {
  //$('#spinnerBox').fadeIn();
  getStations();
});

map.on('zoomend', function() {
  getStations();
});

var markers = new L.FeatureGroup();
map.addLayer(markers);

var grad_colours = ['#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac']

var baseLayers = {
  "Terrain": basemap,
  "NLCD":    nlcdlayer,
};

var overlays = {
  "Rivers":         riverLayer,
  "Gauge Stations": markers
};

L.control.layers(baseLayers, overlays).addTo(map);

function getStations() {
  // Clear markers before getting new ones
  markers.clearLayers();

  // Get map bounds from Leaflet.  getBounds() returns an object
  var bbox = map.getBounds();

  var addy = "/gauges/list/xmin/ymin/xmax/ymax";
  addy     = addy.replace("xmin",bbox._southWest.lng);
  addy     = addy.replace("ymin",bbox._southWest.lat);
  addy     = addy.replace("xmax",bbox._northEast.lng);
  addy     = addy.replace("ymax",bbox._northEast.lat);

  //use jQuery's getJSON() to call the SODA API for NYC 311
  $.getJSON(addy, function(data) {
    //iterate over each 311 complaint, add a marker to the map
    _.each(data, function(marker){
      var markerItem = L.circleMarker(
        [marker.lat,marker.lng],
        {
          radius:      5,
          color:       'black',
          fillColor:   (marker.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*marker.drank)]:'#FF00DE',
          fillOpacity: 1
        }
      );
      markerItem.on('mouseover', function(){
        $('#headerbar').html(marker.name);
        $('#bottomright').html(
          'Stage: ' + marker.svalue + ' ft
' +
          ''+marker.sdt+'
' +
          'Discharge: ' + marker.dvalue + ' cfs
' +
          ''+marker.ddt+'
' +
          'Rank: ' + marker.drank.toFixed(2) + '
' +
          'More info here'
          );
      });

      // markerItem.bindPopup(
      //   '
' + marker.complaint_type + '
'
      //   + (new Date(marker.created_date)).toDateString()
      //   + ((marker.incident_address != null) ? '
' + marker.incident_address : '')
      // );

      markers.addLayer(markerItem);
    });
    map.addLayer(markers);
  });
}

$('.nlcdgrad').hover(function(e){
  var classname = $(e.target).data('classname');
  $('#nlcdexplanation').html(classname);
}, function(){
  $('#nlcdexplanation').html('NLCD Legend (hover over colours for details)');
})

$(document).ready(function(){
  getStations();
});<commit_msg>Styling<commit_after>
// Construct map, center if no location provided
var map = L.map('map', { maxZoom: 13 } );
var hash = new L.Hash(map);
if (!window.location.hash) {
    map.setView([37.958, -120.976], 8);
}

// Make the base map; a raster tile relief map from ESRI
var esriRelief = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';

var basemap = L.tileLayer(esriRelief, {
  attribution: 'ESRI shaded relief, NHDPlus v2',
  maxZoom: 13
});
//basemap.addTo(map);

// Add a single GeoJSON vector file for state boundaries
// This was loaded statically as a script; could also be AJAX
var stateLayer = new L.geoJson(usStates);
stateLayer.setStyle({ "color": "#444",
                      "weight": 1,
                      "fill": false,
                      "opacity": 1.0 });
stateLayer.addTo(map);

var nlcdlayer = L.tileLayer('/nlcd/{z}/{x}/{y}.png',{tms:true}).addTo(map);

var requestsPool = {
  requests: {}, //list of urls
  timeouts: {},
  timeout:  1000*60*10, //In milliseconds
  fetch: function(url) {
    if(requestsPool.exists(url))
      return requestsPool.requests[url];

    requestsPool.timeouts[url] = setTimeout(function(u) {
        requestsPool.remove(u);
    }.bind(this, url), requestsPool.timeout); //Defining the timeout

    requestsPool.requests[url] = $.getJSON(url);
    return requestsPool.requests[url];
  },
  exists: function(url) {
    return requestsPool.requests.hasOwnProperty(url); //Return the Timeout ID if present or undefined
  },
  remove: function(url) {
    requestsPool.cancel(url);
    delete requestsPool.requests[url];
  },
  cancel: function(url) {
    clearTimeout(requestsPool.timeouts[url]); //cancel the timeout
    delete requestsPool.timeouts[url];
  }
}

var riverinfo = {};

function StyleTheRivers(feature){
  requestsPool.fetch('/gauges/reachflow/'+feature.properties.huc8)
  .done(function(val){
    riverinfo[feature.properties.huc8]=val;
    $('.h'+feature.properties.huc8).css('stroke', (val.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*val.drank)]:'#FF00DE' );
    $('.h'+feature.properties.huc8).css('stroke-width', ((val.drank!==null)?(6*val.drank+2).toString():'2')+'px' );
  });
}
//$.getJSON('/gauges/reachflow/'+feature.properties.huc8, function(data){

// Style the river lines; width depends on its Strahler number
function riverStyle(feature) {
  return "stroke-width: " + feature.properties.strahler * map.getZoom()/13 + "px;stroke:#FF00DE;";
}

function riverClass(feature){
  StyleTheRivers(feature);
  return "river h" + feature.properties.huc8;
}

// Make the river overlay layer, vector tiles from our TileStache/Gunicorn server
var geojsonURL = "/rivers/{z}/{x}/{y}.json";
var riverLayer = new L.TileLayer.d3_geoJSON(geojsonURL, {
  class: riverClass,
  style: riverStyle
});
map.addLayer(riverLayer);

var countystyle={
  "stroke":  "black",
  "fill":    "gray",
  "weight":  3,
  "opacity": 0.65
};

var counties = new L.geoJson();
counties.addTo(map);
$.getJSON("/counties.json",
  function(data) {
    counties = new L.geoJson(data,{style:countystyle}).addTo(map);
  }
);

map.on('dragend', function(e) {
  //$('#spinnerBox').fadeIn();
  getStations();
});

map.on('zoomend', function() {
  getStations();
});

var markers = new L.FeatureGroup();
map.addLayer(markers);

var grad_colours = ['#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac']

var baseLayers = {
  "Terrain": basemap,
  "NLCD":    nlcdlayer,
};

var overlays = {
  "Rivers":         riverLayer,
  "Gauge Stations": markers
};

L.control.layers(baseLayers, overlays).addTo(map);

function getStations() {
  // Clear markers before getting new ones
  markers.clearLayers();

  // Get map bounds from Leaflet.  getBounds() returns an object
  var bbox = map.getBounds();

  var addy = "/gauges/list/xmin/ymin/xmax/ymax";
  addy     = addy.replace("xmin",bbox._southWest.lng);
  addy     = addy.replace("ymin",bbox._southWest.lat);
  addy     = addy.replace("xmax",bbox._northEast.lng);
  addy     = addy.replace("ymax",bbox._northEast.lat);

  //use jQuery's getJSON() to call the SODA API for NYC 311
  $.getJSON(addy, function(data) {
    //iterate over each 311 complaint, add a marker to the map
    _.each(data, function(marker){
      var markerItem = L.circleMarker(
        [marker.lat,marker.lng],
        {
          radius:      5,
          color:       'black',
          fillColor:   (marker.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*marker.drank)]:'#FF00DE',
          fillOpacity: 1
        }
      );
      markerItem.on('mouseover', function(){
        $('#headerbar').html(marker.name);
        $('#bottomright').html(
          'Stage: ' + marker.svalue + ' ft
' +
          ''+marker.sdt+'
' +
          'Discharge: ' + marker.dvalue + ' cfs
' +
          ''+marker.ddt+'
' +
          'Rank: ' + marker.drank.toFixed(2) + '
' +
          'More info here'
          );
      });

      // markerItem.bindPopup(
      //   '
' + marker.complaint_type + '
'
      //   + (new Date(marker.created_date)).toDateString()
      //   + ((marker.incident_address != null) ? '
' + marker.incident_address : '')
      // );

      markers.addLayer(markerItem);
    });
    map.addLayer(markers);
  });
}

$('.nlcdgrad').hover(function(e){
  var classname = $(e.target).data('classname');
  $('#nlcdexplanation').html(classname);
}, function(){
  $('#nlcdexplanation').html('NLCD Legend (hover over colours for details)');
})

$(document).ready(function(){
  getStations();
});<|endoftext|>


<commit_before>import Video from 'twilio-video';

Template.videoChat.onDestroyed(function (event, template) {
  event.preventDefault();
  if (template.room) {
    template.room.disconnect();
  }
});

Template.videoChat.onCreated(function (){
   this.mutedVariable = new ReactiveVar(null);
   this.cameraDisabledVariable = new ReactiveVar(null);
   this.previewVariable = new ReactiveVar(null);
   this.callStartedVariable = new ReactiveVar(null);
   this.mediaAttachedVarirable =  new ReactiveVar(null);
});

Template.videoChat.onRendered(function (){
   this.mutedVariable.set(false);
   this.cameraDisabledVariable.set(false);
   this.previewVariable.set(false);
   this.callStartedVariable.set(false);
   this.mediaAttachedVarirable.set(false);
});

Template.videoChat.helpers({
  twilioVideoNotSupportedByBrowser: function(){
    return (!navigator.webkitGetUserMedia && !navigator.mozGetUserMedia)
  },
  theClientIsMuted: function(){
    return (Template.instance().mutedVariable.get())
  },
  theCameraIsDisabled: function(){
    return (Template.instance().cameraDisabledVariable.get())
  },
  inPreviewMode: function () {
    return (Template.instance().previewVariable.get())
  },
  theCallStarted: function(){
    return (Template.instance().callStartedVariable.get())
  },
  theMediaIsAttached: function(){
    return (Template.instance().mediaAttachedVarirable.get())
  }
});

Template.videoChat.events({
  'submit #js-request-video-chat': function (event, template) {
    event.preventDefault();
    const target = event.target;
    const roomName = target.text.value;
    let initAccessToken;
    let accessToken;

    initAccessToken = Meteor.call(
      "requestVideoChatAccess", roomName,
      function requestVideoChatAccessCallback(error, result) {
        let localMediaPreview = null;
        if (error) {
          console.log(error, error.reson);
        }
        if (result) {
          accessToken = result;
          template.client = new Video.Client(accessToken.token);
          if (template.localMedia) {
            localMediaPreview = template.localMedia;
          }else {
            template.localMedia = new Video.LocalMedia();
            Video.getUserMedia().then(
              function (mediaStream) {
                template.localMedia.addStream(mediaStream);
                template.mediaAttachedVarirable.set(true);
              },
            function (error){
              console.log('LocalMedia error', error);
            })
          }
          room = template.client.connect({
            to: roomName,
            localMedia: localMediaPreview,
            audio: ( ! template.mutedVariable.get()),
            video: ( ! template.cameraDisabledVariable.get())
          })
          .then(
            room => {
              template.localMedia.attach('#local-media');

              room.participants.forEach(function(participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantConnected', function (participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantDisconnected', function(participant) {
                participant.media.detach();
              });

              room.on('disconnected', function () {
                room.localParticipant.media.detach();
                room.participants.forEach(function(participant) {
                  participant.media.detach();
                });
              });
              template.room = room;
              template.callStartedVariable.set(true);
            }
          )
        }
    })
  },
  "click #js-end-video-chat" : function (event, template){
    event.preventDefault();
    if (template.room) {
      template.room.disconnect();
      template.callStartedVariable.set(false);
    }
  },
  "click #js-mute-video-chat" : function (event, template) {
    event.preventDefault();
    template.localMedia.mute();
    if (template.localMedia) {
      template.localMedia.mute();
      if (template.localMedia.isMuted) {
      template.mutedVariable.set(true);
      }
    }
  },
  "click #js-unmute-video-chat" : function (event, template){
    event.preventDefault();
    template.localMedia.unmute();
    if (template.localMedia) {
      template.localMedia.unmute();
      if ( ! template.localMedia.isMuted) {
      template.mutedVariable.set(false);
      }
    }
  },
  "click #js-disable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      const localVideoTrack = template.localMedia.removeCamera();
      console.log(localVideoTrack);
      template.cameraDisabledVariable.set(true);
    }
  },
  "click #js-enable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      const localVideoTrack = template.localMedia.addCamera();
      console.log(localVideoTrack);
      template.cameraDisabledVariable.set(false);
    }
  },
  "click #js-preview-camera": function (event, template) {
    event.preventDefault();
    if( (! template.client) && ( ! template.localMedia)){
      template.localMedia = new Video.LocalMedia();
      Video.getUserMedia().then(
        function (mediaStream) {
          template.localMedia.addStream(mediaStream);
          template.localMedia.attach('#local-media');
          template.previewVariable.set(true);
          template.mediaAttachedVarirable.set(true);
        },
      function (error){
        console.log('LocalMedia error', error);
      })
    }
  }
});
<commit_msg>enable cameria style<commit_after>import Video from 'twilio-video';

Template.videoChat.onDestroyed(function (event, template) {
  event.preventDefault();
  if (template.room) {
    template.room.disconnect();
  }
});

Template.videoChat.onCreated(function (){
   this.mutedVariable = new ReactiveVar(null);
   this.cameraDisabledVariable = new ReactiveVar(null);
   this.previewVariable = new ReactiveVar(null);
   this.callStartedVariable = new ReactiveVar(null);
   this.mediaAttachedVarirable =  new ReactiveVar(null);
});

Template.videoChat.onRendered(function (){
   this.mutedVariable.set(false);
   this.cameraDisabledVariable.set(false);
   this.previewVariable.set(false);
   this.callStartedVariable.set(false);
   this.mediaAttachedVarirable.set(false);
});

Template.videoChat.helpers({
  twilioVideoNotSupportedByBrowser: function(){
    return (!navigator.webkitGetUserMedia && !navigator.mozGetUserMedia)
  },
  theClientIsMuted: function(){
    return (Template.instance().mutedVariable.get())
  },
  theCameraIsDisabled: function(){
    return (Template.instance().cameraDisabledVariable.get())
  },
  inPreviewMode: function () {
    return (Template.instance().previewVariable.get())
  },
  theCallStarted: function(){
    return (Template.instance().callStartedVariable.get())
  },
  theMediaIsAttached: function(){
    return (Template.instance().mediaAttachedVarirable.get())
  }
});

Template.videoChat.events({
  'submit #js-request-video-chat': function (event, template) {
    event.preventDefault();
    const target = event.target;
    const roomName = target.text.value;
    let initAccessToken;
    let accessToken;

    initAccessToken = Meteor.call(
      "requestVideoChatAccess", roomName,
      function requestVideoChatAccessCallback(error, result) {
        let localMediaPreview = null;
        if (error) {
          console.log(error, error.reson);
        }
        if (result) {
          accessToken = result;
          template.client = new Video.Client(accessToken.token);
          if (template.localMedia) {
            localMediaPreview = template.localMedia;
          }else {
            template.localMedia = new Video.LocalMedia();
            Video.getUserMedia().then(
              function (mediaStream) {
                template.localMedia.addStream(mediaStream);
                template.mediaAttachedVarirable.set(true);
              },
            function (error){
              console.log('LocalMedia error', error);
            })
          }
          room = template.client.connect({
            to: roomName,
            localMedia: localMediaPreview,
            audio: ( ! template.mutedVariable.get()),
            video: ( ! template.cameraDisabledVariable.get())
          })
          .then(
            room => {
              template.localMedia.attach('#local-media');

              room.participants.forEach(function(participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantConnected', function (participant) {
                participant.media.attach('#remote-media');
              });

              room.on('participantDisconnected', function(participant) {
                participant.media.detach();
              });

              room.on('disconnected', function () {
                room.localParticipant.media.detach();
                room.participants.forEach(function(participant) {
                  participant.media.detach();
                });
              });
              template.room = room;
              template.callStartedVariable.set(true);
            }
          )
        }
    })
  },
  "click #js-end-video-chat" : function (event, template){
    event.preventDefault();
    if (template.room) {
      template.room.disconnect();
      template.callStartedVariable.set(false);
    }
  },
  "click #js-mute-video-chat" : function (event, template) {
    event.preventDefault();
    template.localMedia.mute();
    if (template.localMedia) {
      template.localMedia.mute();
      if (template.localMedia.isMuted) {
      template.mutedVariable.set(true);
      }
    }
  },
  "click #js-unmute-video-chat" : function (event, template){
    event.preventDefault();
    template.localMedia.unmute();
    if (template.localMedia) {
      template.localMedia.unmute();
      if ( ! template.localMedia.isMuted) {
      template.mutedVariable.set(false);
      }
    }
  },
  "click #js-disable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      const localVideoTrack = template.localMedia.removeCamera();
      template.cameraDisabledVariable.set(true);
    }
  },
  "click #js-enable-camera-video-chat": function (event, template) {
    event.preventDefault();
    if (template.localMedia) {
      template.localMedia.addCamera().then(
        function(localVideoTrack){
          if (localVideoTrack.mediaStream.active) {
            template.cameraDisabledVariable.set(false);
          }
        },
        function (error){
          console.log('LocalMedia error', error);
        }
      )
    }
  },
  "click #js-preview-camera": function (event, template) {
    event.preventDefault();
    if( (! template.client) && ( ! template.localMedia)){
      template.localMedia = new Video.LocalMedia();
      Video.getUserMedia().then(
        function (mediaStream) {
          template.localMedia.addStream(mediaStream);
          template.localMedia.attach('#local-media');
          template.previewVariable.set(true);
          template.mediaAttachedVarirable.set(true);
        },
      function (error){
        console.log('LocalMedia error', error);
      })
    }
  }
});
<|endoftext|>


<commit_before>
// Construct map, center if no location provided
var map = L.map('map', {
  maxZoom:   13
  //minZoom:   1,
  /*maxBounds: [
    [20, -125], //Southwest
    [50,  -66]  //Northeast
  ]*/
});
var hash = new L.Hash(map);
if (!window.location.hash) {
    map.setView([37.958, -120.976], 8);
}

// Make the base map; a raster tile relief map from ESRI
var esriRelief = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';

var basemap = L.tileLayer(esriRelief, {
  attribution: 'ESRI shaded relief, NHDPlus v2',
  maxZoom: 13
});
//basemap.addTo(map);

// Add a single GeoJSON vector file for state boundaries
// This was loaded statically as a script; could also be AJAX
var stateLayer = new L.geoJson(usStates);
stateLayer.setStyle({ "color": "#444",
                      "weight": 1,
                      "fill": false,
                      "opacity": 1.0 });
stateLayer.addTo(map);

var nlcdlayer = L.tileLayer('/nlcd/{z}/{x}/{y}.png',{tms:true}).addTo(map);

var requestsPool = {
  requests: {}, //list of urls
  timeouts: {},
  timeout:  1000*60*10, //In milliseconds
  fetch: function(url, data, sendtype) {
    if(requestsPool.exists(url))
      return requestsPool.requests[url];

    requestsPool.timeouts[url] = setTimeout(function(u) {
        requestsPool.remove(u);
    }.bind(this, url), requestsPool.timeout); //Defining the timeout

    if(data){
      if(sendtype=='post')
        requestsPool.requests[url] = $.post(url,data,null,'json');
      else
        requestsPool.requests[url] = $.getJSON(url,data);
    } else
      requestsPool.requests[url] = $.getJSON(url);
    return requestsPool.requests[url];
  },
  exists: function(url) {
    return requestsPool.requests.hasOwnProperty(url); //Return the Timeout ID if present or undefined
  },
  remove: function(url) {
    requestsPool.cancel(url);
    delete requestsPool.requests[url];
  },
  cancel: function(url) {
    clearTimeout(requestsPool.timeouts[url]); //cancel the timeout
    delete requestsPool.timeouts[url];
  }
}

function UpdateRivers(newtime){
  requestsPool.fetch('/gauges/reachflow/'+newtime)
  .done(function(val){
    _.each(val['reachflows'],function(o){
      $('.h'+o.huc8).css('stroke',       (o.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*o.drank/100.0)]:'#FF00DE' );
      $('.h'+o.huc8).css('stroke-width', ((o.drank!==null)?(6*o.drank/100.0+2).toString():'2')+'px' );
    });
  });
}

/*function UpdateGauges(newtime){
  requestsPool.fetch('/gauges/getvals/'+newtime,{gauges:JSON.stringify(_.keys(gauges))},'post')
  .done(function(val){
    _.each(val,function(o){
      gauges[val.site_code.trim()].setStyle('')

    });
  });
}
UpdateGauges('2010-08-08');*/

// Style the river lines; width depends on its Strahler number
function riverStyle(feature) {
  var fp   = feature.properties;
  var temp = "stroke:" + ((fp.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*fp.drank/100.0)]:'#FF00DE') + ';' + "stroke-width:" + ((fp.drank!==null)?(6*fp.drank/100.0+2).toString():fp.strahler * map.getZoom()/13)+'px' + ';';
  return temp;
}

function riverClass(feature){
  return "river h" + feature.properties.huc8;
}

// Make the river overlay layer, vector tiles from our TileStache/Gunicorn server
var geojsonURL = "/rivers/{z}/{x}/{y}.json";
var riverLayer = new L.TileLayer.d3_geoJSON(geojsonURL, {
  class:         riverClass,
  style:         riverStyle,
});
map.addLayer(riverLayer);

var countystyle = {
  "color":       "black",
  "stroke":      "black",
  "weight":      3,
};

function highlightCounty(e) {
  var layer = e.target;

  layer.setStyle({
    weight:      5,
    color:       '#666',
  });

  if (!L.Browser.ie && !L.Browser.opera) {
      layer.bringToFront();
  }
}

function resetCounty(e) {
  var layer = e.target;

  layer.setStyle({
    weight: 3,
    color:  "black"
  });
}

function zoomToFeature(e) {
    map.fitBounds(e.target.getBounds());
}

function onEachCounty(feature, layer) {
  layer.on({
      mouseover: highlightCounty,
      mouseout:  resetCounty,
      click:     zoomToFeature
  });
}

var counties = new L.geoJson(null,{style:countystyle,onEachFeature:onEachCounty});
$.getJSON("/counties.json",
  function(data) {
    $(data.features).each(function(key, data) {
      counties.addData(data);
    });
  }
);

setTimeout(function(){colourCounties('allwater',95);},1000*5);

map.on('dragend', function(e) {
  //$('#spinnerBox').fadeIn();
  getStations();
});

map.on('zoomend', function() {
  getStations();
});

var markers = new L.FeatureGroup();
map.addLayer(markers);

var grad_colours = ['#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac']

var hurricane_tracks = L.featureGroup();
map.addLayer(hurricane_tracks);
var hurricane_points = L.featureGroup();
map.addLayer(hurricane_points);

var baseLayers = {
  "Terrain": basemap,
  "NLCD":    nlcdlayer,
};

var overlays = {
  "Rivers":           riverLayer,
  "Gauge Stations":   markers,
  "Counties":         counties,
  "Hurricane Tracks": hurricane_tracks,
  "Hurricane Points": hurricane_points
};

L.control.layers(baseLayers, overlays).addTo(map);

var gauges = {};
function getStations() {
  // Clear markers before getting new ones
  markers.clearLayers();

  var date = $('#datepicker').val();

  // Get map bounds from Leaflet.  getBounds() returns an object
  var bbox = map.getBounds();

  var addy = "/gauges/list/date/xmin/ymin/xmax/ymax";
  addy     = addy.replace("date",date);
  addy     = addy.replace("xmin",bbox._southWest.lng);
  addy     = addy.replace("ymin",bbox._southWest.lat);
  addy     = addy.replace("xmax",bbox._northEast.lng);
  addy     = addy.replace("ymax",bbox._northEast.lat);

  $.getJSON(addy, function(data) {
    gauges = {};
    _.each(data, function(marker){
      gauges[marker.site_code] = L.circleMarker(
        [marker.lat,marker.lng],
        {
          radius:      5,
          color:       'black',
          fillColor:   (marker.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*marker.drank/100.0)]:'#FF00DE',
          fillOpacity: 1
        }
      );
      gauges[marker.site_code].on('mouseover', function(){
        $('#headerbar').html(marker.name);
        $('#bottomright').html(
          'Stage: ' + marker.svalue + ' ft
' +
          'Discharge: ' + marker.dvalue + ' cfs
' +
          'Rank: ' + marker.drank.toFixed(2) + '
' +
          'More info here'
          );
      });

      // markerItem.bindPopup(
      //   '
' + marker.complaint_type + '
'
      //   + (new Date(marker.created_date)).toDateString()
      //   + ((marker.incident_address != null) ? '
' + marker.incident_address : '')
      // );

      markers.addLayer(gauges[marker.site_code]);
    });
  });
}

function colourCounties(style,percentile_max){
  $.getJSON('/county/style/'+style+'?percentile_max='+percentile_max,function(data){
    counties.setStyle(function(feature){
      var myid = feature.properties.STATE+feature.properties.COUNTY;
      return data[myid];
    });
  });
}
colourCounties('allwater',95);

$('.nlcdgrad').hover(function(e){
  var classname = $(e.target).data('classname');
  $('#nlcdexplanation').html(classname);
}, function(){
  $('#nlcdexplanation').html('NLCD Legend (hover over colours for details)');
});

function UpdateHurricanes(newtime){
  var newtimeunix = moment(newtime,'YYYY-MM-DD').unix();
  requestsPool.fetch('/hurricanes/'+newtime) //Prevent multiple calls to server in same session
  .done(function(data){
    var load_time = moment().unix();
    _.each(data['hurricanes'],function(o){
      if(!_.has(hurricanes,o.stormid)){
        hurricanes[o.stormid] = {
          mintime:   moment('2100-01-01','YYYY-MM-DD').unix(),
          maxtime:   moment('1800-01-01','YYYY-MM-DD').unix(),
          points:    [],
          load_time: load_time
        };
      } else if(hurricanes[o.stormid].load_time!=load_time)
        return;
      var ptgeojson = {type:"Feature",properties:o,geometry:{type:"Point",coordinates:[o.lon,o.lat]}};
      o.marker      = L.geoJson(ptgeojson,{pointToLayer: function (feature, latlng) {
        return new L.CircleMarker(latlng, {radius: o.wind/5, fillOpacity: 0.55, fillColor:'red', color:'red'});
      }});
      o.marker.stormid = o.stormid;
      o.marker.dt      = moment(o.dt,'YYYY-MM-DD').unix();
      o.marker.on('mouseover',function(e){
        e.layer.setStyle({color:'black'});
        $('#headerbar').html("Hurricane " + o.name);
        $('#bottomright').html("Wind: "+(o.wind*1.15077945).toFixed(0)+" MPH
" + o.dt);
      });
      o.marker.on('mouseout',function(e){
        e.layer.setStyle({color:'red'});
      });
      hurricane_points_raw.push(o.marker);
      hurricane_points.addLayer(o.marker);
      hurricanes[o.stormid].points.push(o);
      hurricanes[o.stormid].name    = o.name;
      hurricanes[o.stormid].mintime = Math.min(hurricanes[o.stormid].mintime, moment(o.dt,'YYYY-MM-DD').unix());
      hurricanes[o.stormid].maxtime = Math.max(hurricanes[o.stormid].maxtime, moment(o.dt,'YYYY-MM-DD').unix());
    });
    _.each(hurricanes,function(o){
      if(_.has(o,'line'))
        return;
      var polyline      = {type:"Feature",geometry:{type:"LineString", coordinates:_.map(o.points,function(x){return [x.lon,x.lat];})}};
      polyline          = turf.bezier(polyline);
      o.line            = L.geoJson(polyline, {color:'green',weight:5});
      o.name            = o.name.toLowerCase().replace( /\b\w/g, function (m) {return m.toUpperCase();}); //Capitalize first letter of each word
      o.line.properties = {mintime:o.mintime,maxtime:o.maxtime};
      o.line.on('mouseover',function(e){
        e.layer.setStyle({color:'#A6FF00'});
        $('#headerbar').html("Hurricane " + o.name)
      });
      o.line.on('mouseout',function(e){
        e.layer.setStyle({color:'green'});
      });
      hurricane_tracks_raw.push(o.line);
      hurricane_tracks.addLayer(o.line,true);
    });
    _.each(hurricane_tracks_raw, function(o){
      if(!(o.properties.mintime<=newtimeunix && newtimeunix<=o.properties.maxtime))
        hurricane_tracks.removeLayer(o);
      else
        hurricane_tracks.addLayer(o);
    });
    _.each(hurricane_points_raw, function(o){
      if(!(hurricanes[o.stormid].mintime<=newtimeunix && newtimeunix<=hurricanes[o.stormid].maxtime))
        hurricane_points.removeLayer(o);
      else {
        hurricane_points.addLayer(o);
        if(o.dt==newtimeunix)
          o.setStyle({fillColor:'green'});
        else
          o.setStyle({fillColor:'red'});
      }
    });
  });
}

var hurricanes           = {};
var hurricane_points_raw = [];
var hurricane_tracks_raw = [];
//TODO: Prevent multiple calls to hurricanes for the same date
function timeChanged(newtime){
  UpdateHurricanes(newtime);
  UpdateRivers(newtime);
}

$(document).ready(function(){
  $('#datepicker').datepick({
    minDate:    '1950-01-01',
    maxDate:    'now',
    dateFormat: 'yyyy-mm-dd',
    onSelect:   function(date) { timeChanged(moment(date[0]).format('YYYY-MM-DD')); }
  });

  $('#datepicker').val(moment().format('YYYY-MM-DD'));

  $('#dateminus').click(function(){
    var dedate = moment($('#datepicker').val(), "YYYY-MM-DD");
    dedate.add(-1, 'days');
    if(dedate.unix()>=moment('1950-01-01').unix())
      $('#datepicker').val( dedate.format('YYYY-MM-DD') );
    timeChanged(dedate.format('YYYY-MM-DD'));
  });

  $('#dateplus').click(function(){
    var dedate = moment($('#datepicker').val(), "YYYY-MM-DD");
    dedate.add(1, 'days');
    if(dedate.unix()<moment().unix())
      $('#datepicker').val( dedate.format('YYYY-MM-DD') );
    timeChanged(dedate.format('YYYY-MM-DD'));
  });

  getStations();

});<commit_msg>Change stations on time change<commit_after>
// Construct map, center if no location provided
var map = L.map('map', {
  maxZoom:   13
  //minZoom:   1,
  /*maxBounds: [
    [20, -125], //Southwest
    [50,  -66]  //Northeast
  ]*/
});
var hash = new L.Hash(map);
if (!window.location.hash) {
    map.setView([37.958, -120.976], 8);
}

// Make the base map; a raster tile relief map from ESRI
var esriRelief = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';

var basemap = L.tileLayer(esriRelief, {
  attribution: 'ESRI shaded relief, NHDPlus v2',
  maxZoom: 13
});
//basemap.addTo(map);

// Add a single GeoJSON vector file for state boundaries
// This was loaded statically as a script; could also be AJAX
var stateLayer = new L.geoJson(usStates);
stateLayer.setStyle({ "color": "#444",
                      "weight": 1,
                      "fill": false,
                      "opacity": 1.0 });
stateLayer.addTo(map);

var nlcdlayer = L.tileLayer('/nlcd/{z}/{x}/{y}.png',{tms:true}).addTo(map);

var requestsPool = {
  requests: {}, //list of urls
  timeouts: {},
  timeout:  1000*60*10, //In milliseconds
  fetch: function(url, data, sendtype) {
    if(requestsPool.exists(url))
      return requestsPool.requests[url];

    requestsPool.timeouts[url] = setTimeout(function(u) {
        requestsPool.remove(u);
    }.bind(this, url), requestsPool.timeout); //Defining the timeout

    if(data){
      if(sendtype=='post')
        requestsPool.requests[url] = $.post(url,data,null,'json');
      else
        requestsPool.requests[url] = $.getJSON(url,data);
    } else
      requestsPool.requests[url] = $.getJSON(url);
    return requestsPool.requests[url];
  },
  exists: function(url) {
    return requestsPool.requests.hasOwnProperty(url); //Return the Timeout ID if present or undefined
  },
  remove: function(url) {
    requestsPool.cancel(url);
    delete requestsPool.requests[url];
  },
  cancel: function(url) {
    clearTimeout(requestsPool.timeouts[url]); //cancel the timeout
    delete requestsPool.timeouts[url];
  }
}

function UpdateRivers(newtime){
  requestsPool.fetch('/gauges/reachflow/'+newtime)
  .done(function(val){
    _.each(val['reachflows'],function(o){
      $('.h'+o.huc8).css('stroke',       (o.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*o.drank/100.0)]:'#FF00DE' );
      $('.h'+o.huc8).css('stroke-width', ((o.drank!==null)?(6*o.drank/100.0+2).toString():'2')+'px' );
    });
  });
}

/*function UpdateGauges(newtime){
  requestsPool.fetch('/gauges/getvals/'+newtime,{gauges:JSON.stringify(_.keys(gauges))},'post')
  .done(function(val){
    _.each(val,function(o){
      gauges[val.site_code.trim()].setStyle('')

    });
  });
}
UpdateGauges('2010-08-08');*/

// Style the river lines; width depends on its Strahler number
function riverStyle(feature) {
  var fp   = feature.properties;
  var temp = "stroke:" + ((fp.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*fp.drank/100.0)]:'#FF00DE') + ';' + "stroke-width:" + ((fp.drank!==null)?(6*fp.drank/100.0+2).toString():fp.strahler * map.getZoom()/13)+'px' + ';';
  return temp;
}

function riverClass(feature){
  return "river h" + feature.properties.huc8;
}

// Make the river overlay layer, vector tiles from our TileStache/Gunicorn server
var geojsonURL = "/rivers/{z}/{x}/{y}.json";
var riverLayer = new L.TileLayer.d3_geoJSON(geojsonURL, {
  class:         riverClass,
  style:         riverStyle,
});
map.addLayer(riverLayer);

var countystyle = {
  "color":       "black",
  "stroke":      "black",
  "weight":      3,
};

function highlightCounty(e) {
  var layer = e.target;

  layer.setStyle({
    weight:      5,
    color:       '#666',
  });

  if (!L.Browser.ie && !L.Browser.opera) {
      layer.bringToFront();
  }
}

function resetCounty(e) {
  var layer = e.target;

  layer.setStyle({
    weight: 3,
    color:  "black"
  });
}

function zoomToFeature(e) {
    map.fitBounds(e.target.getBounds());
}

function onEachCounty(feature, layer) {
  layer.on({
      mouseover: highlightCounty,
      mouseout:  resetCounty,
      click:     zoomToFeature
  });
}

var counties = new L.geoJson(null,{style:countystyle,onEachFeature:onEachCounty});
$.getJSON("/counties.json",
  function(data) {
    $(data.features).each(function(key, data) {
      counties.addData(data);
    });
  }
);

setTimeout(function(){colourCounties('allwater',95);},1000*5);

map.on('dragend', function(e) {
  //$('#spinnerBox').fadeIn();
  getStations();
});

map.on('zoomend', function() {
  getStations();
});

var markers = new L.FeatureGroup();
map.addLayer(markers);

var grad_colours = ['#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac']

var hurricane_tracks = L.featureGroup();
map.addLayer(hurricane_tracks);
var hurricane_points = L.featureGroup();
map.addLayer(hurricane_points);

var baseLayers = {
  "Terrain": basemap,
  "NLCD":    nlcdlayer,
};

var overlays = {
  "Rivers":           riverLayer,
  "Gauge Stations":   markers,
  "Counties":         counties,
  "Hurricane Tracks": hurricane_tracks,
  "Hurricane Points": hurricane_points
};

L.control.layers(baseLayers, overlays).addTo(map);

var gauges = {};
function getStations() {
  // Clear markers before getting new ones
  markers.clearLayers();

  var date = $('#datepicker').val();

  // Get map bounds from Leaflet.  getBounds() returns an object
  var bbox = map.getBounds();

  var addy = "/gauges/list/date/xmin/ymin/xmax/ymax";
  addy     = addy.replace("date",date);
  addy     = addy.replace("xmin",bbox._southWest.lng);
  addy     = addy.replace("ymin",bbox._southWest.lat);
  addy     = addy.replace("xmax",bbox._northEast.lng);
  addy     = addy.replace("ymax",bbox._northEast.lat);

  $.getJSON(addy, function(data) {
    gauges = {};
    _.each(data, function(marker){
      gauges[marker.site_code] = L.circleMarker(
        [marker.lat,marker.lng],
        {
          radius:      5,
          color:       'black',
          fillColor:   (marker.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*marker.drank/100.0)]:'#FF00DE',
          fillOpacity: 1
        }
      );
      gauges[marker.site_code].on('mouseover', function(){
        $('#headerbar').html(marker.name);
        $('#bottomright').html(
          'Stage: ' + marker.svalue + ' ft
' +
          'Discharge: ' + marker.dvalue + ' cfs
' +
          'Rank: ' + marker.drank.toFixed(2) + '
' +
          'More info here'
          );
      });

      // markerItem.bindPopup(
      //   '
' + marker.complaint_type + '
'
      //   + (new Date(marker.created_date)).toDateString()
      //   + ((marker.incident_address != null) ? '
' + marker.incident_address : '')
      // );

      markers.addLayer(gauges[marker.site_code]);
    });
  });
}

function colourCounties(style,percentile_max){
  $.getJSON('/county/style/'+style+'?percentile_max='+percentile_max,function(data){
    counties.setStyle(function(feature){
      var myid = feature.properties.STATE+feature.properties.COUNTY;
      return data[myid];
    });
  });
}
colourCounties('allwater',95);

$('.nlcdgrad').hover(function(e){
  var classname = $(e.target).data('classname');
  $('#nlcdexplanation').html(classname);
}, function(){
  $('#nlcdexplanation').html('NLCD Legend (hover over colours for details)');
});

function UpdateHurricanes(newtime){
  var newtimeunix = moment(newtime,'YYYY-MM-DD').unix();
  requestsPool.fetch('/hurricanes/'+newtime) //Prevent multiple calls to server in same session
  .done(function(data){
    var load_time = moment().unix();
    _.each(data['hurricanes'],function(o){
      if(!_.has(hurricanes,o.stormid)){
        hurricanes[o.stormid] = {
          mintime:   moment('2100-01-01','YYYY-MM-DD').unix(),
          maxtime:   moment('1800-01-01','YYYY-MM-DD').unix(),
          points:    [],
          load_time: load_time
        };
      } else if(hurricanes[o.stormid].load_time!=load_time)
        return;
      var ptgeojson = {type:"Feature",properties:o,geometry:{type:"Point",coordinates:[o.lon,o.lat]}};
      o.marker      = L.geoJson(ptgeojson,{pointToLayer: function (feature, latlng) {
        return new L.CircleMarker(latlng, {radius: o.wind/5, fillOpacity: 0.55, fillColor:'red', color:'red'});
      }});
      o.marker.stormid = o.stormid;
      o.marker.dt      = moment(o.dt,'YYYY-MM-DD').unix();
      o.marker.on('mouseover',function(e){
        e.layer.setStyle({color:'black'});
        $('#headerbar').html("Hurricane " + o.name);
        $('#bottomright').html("Wind: "+(o.wind*1.15077945).toFixed(0)+" MPH
" + o.dt);
      });
      o.marker.on('mouseout',function(e){
        e.layer.setStyle({color:'red'});
      });
      hurricane_points_raw.push(o.marker);
      hurricane_points.addLayer(o.marker);
      hurricanes[o.stormid].points.push(o);
      hurricanes[o.stormid].name    = o.name;
      hurricanes[o.stormid].mintime = Math.min(hurricanes[o.stormid].mintime, moment(o.dt,'YYYY-MM-DD').unix());
      hurricanes[o.stormid].maxtime = Math.max(hurricanes[o.stormid].maxtime, moment(o.dt,'YYYY-MM-DD').unix());
    });
    _.each(hurricanes,function(o){
      if(_.has(o,'line'))
        return;
      var polyline      = {type:"Feature",geometry:{type:"LineString", coordinates:_.map(o.points,function(x){return [x.lon,x.lat];})}};
      polyline          = turf.bezier(polyline);
      o.line            = L.geoJson(polyline, {color:'green',weight:5});
      o.name            = o.name.toLowerCase().replace( /\b\w/g, function (m) {return m.toUpperCase();}); //Capitalize first letter of each word
      o.line.properties = {mintime:o.mintime,maxtime:o.maxtime};
      o.line.on('mouseover',function(e){
        e.layer.setStyle({color:'#A6FF00'});
        $('#headerbar').html("Hurricane " + o.name)
      });
      o.line.on('mouseout',function(e){
        e.layer.setStyle({color:'green'});
      });
      hurricane_tracks_raw.push(o.line);
      hurricane_tracks.addLayer(o.line,true);
    });
    _.each(hurricane_tracks_raw, function(o){
      if(!(o.properties.mintime<=newtimeunix && newtimeunix<=o.properties.maxtime))
        hurricane_tracks.removeLayer(o);
      else
        hurricane_tracks.addLayer(o);
    });
    _.each(hurricane_points_raw, function(o){
      if(!(hurricanes[o.stormid].mintime<=newtimeunix && newtimeunix<=hurricanes[o.stormid].maxtime))
        hurricane_points.removeLayer(o);
      else {
        hurricane_points.addLayer(o);
        if(o.dt==newtimeunix)
          o.setStyle({fillColor:'green'});
        else
          o.setStyle({fillColor:'red'});
      }
    });
  });
}

var hurricanes           = {};
var hurricane_points_raw = [];
var hurricane_tracks_raw = [];
//TODO: Prevent multiple calls to hurricanes for the same date
function timeChanged(newtime){
  UpdateHurricanes(newtime);
  UpdateRivers(newtime);
  getStations();
}

$(document).ready(function(){
  $('#datepicker').datepick({
    minDate:    '1950-01-01',
    maxDate:    'now',
    dateFormat: 'yyyy-mm-dd',
    onSelect:   function(date) { timeChanged(moment(date[0]).format('YYYY-MM-DD')); }
  });

  $('#datepicker').val(moment().format('YYYY-MM-DD'));

  $('#dateminus').click(function(){
    var dedate = moment($('#datepicker').val(), "YYYY-MM-DD");
    dedate.add(-1, 'days');
    if(dedate.unix()>=moment('1950-01-01').unix())
      $('#datepicker').val( dedate.format('YYYY-MM-DD') );
    timeChanged(dedate.format('YYYY-MM-DD'));
  });

  $('#dateplus').click(function(){
    var dedate = moment($('#datepicker').val(), "YYYY-MM-DD");
    dedate.add(1, 'days');
    if(dedate.unix()<moment().unix())
      $('#datepicker').val( dedate.format('YYYY-MM-DD') );
    timeChanged(dedate.format('YYYY-MM-DD'));
  });

  getStations();

});<|endoftext|>


<commit_before>// Vue.use(VueRouter);
Vue.use(VueResource);

Vue.http.options.root = '/api';

new Vue({
  el: '#app',
  data: {
    key: '',
    provider: '',
    region: '',
    vpns: [],
    providers: [],
    regions: [],
    checked: false,
    loader: {
      refresh: false,
      create: false,
    }
  },
  ready: function () {
    this.$set('key', localStorage._key);
    this.$set('provider', localStorage.provider);
    this.$set('region', localStorage.region);

    if (this.key || this.provider || this.region) {
      this.$set('checked', true);
    }

    this.$http.get('providers')
      .then(function (resp) {
        this.$set('providers', resp.data);
      }, function (resp) {
        console.log(resp);
      }
    );
  },
  methods: {

    getList: function () {
      this.loader.refresh = true;
      this.$http.get('', { region: this.region, key: this.key, provider: this.provider })
        .then(function (resp) {
          this.$set('vpns', resp.data);
          this.loader.refresh = false;
        }, function (resp) {
          console.log(resp);
          this.loader.refresh = false;
        }
      );
    },

    create: function () {
      this.loader.create = true;
      this.$http.post('', { region: this.region, key: this.key, provider: this.provider })
        .then(function (resp) {
          this.loader.create = false;
          if (this.vpns === undefined) {
            this.$set('vpns', []);
          }
          this.vpns.push(resp.data);
        }, function (resp) {
          this.loader.create = false;
          console.log(resp);
        }
      );
    },

    remove: function (vpn) {
      this.$http.delete('', { vpn_id: vpn.id, key: this.key, provider: this.provider })
        .then(function (resp) {
          this.vpns.splice(this.vpns.indexOf(vpn), 1);
        }, function (resp) {
          console.log(resp);
        }
      );
    }
  },
  watch: {
    'provider': function (val, oldVal) {
        if (!this.key || !val) {
          return ;
        }
        this.$http.get('regions', { provider: this.provider, key: this.key })
        .then(function (resp) {
          this.$set('regions', resp.data);
          if (this.checked) {
              localStorage.provider = this.provider;
          }
        }, function (resp) {
          console.log(resp)
        }
      );
    },
    'key': function (val, oldVal) {
        if (!this.provider || !val) {
          return ;
        }
        this.$http.get('regions', { provider: this.provider, key: this.key })
        .then(function (resp) {
          this.$set('regions', resp.data);
          if (this.checked) {
              localStorage._key = this.key;
          }
        }, function (resp) {
          console.log(resp)
        }
      );
    },
    'region': function (val, oldVal) {
        if (this.checked) {
            localStorage.region = this.region;
        }
    },
    'checked': function (val, oldVal) {
        if (val) {
          localStorage.provider = this.provider;
          localStorage.region = this.region;
          localStorage._key = this.key;
        } else {
          localStorage.removeItem('provider');
          localStorage.removeItem('region');
          localStorage.removeItem('_key');
        }
    }
  }
})
<commit_msg>Update the server list on key update<commit_after>// Vue.use(VueRouter);
Vue.use(VueResource);

Vue.http.options.root = '/api';

new Vue({
  el: '#app',
  data: {
    key: '',
    provider: '',
    region: '',
    vpns: [],
    providers: [],
    regions: [],
    checked: false,
    loader: {
      refresh: false,
      create: false,
    }
  },
  ready: function () {
    this.$set('key', localStorage._key);
    this.$set('provider', localStorage.provider);
    this.$set('region', localStorage.region);

    if (this.key || this.provider || this.region) {
      this.$set('checked', true);
    }

    this.$http.get('providers')
      .then(function (resp) {
        this.$set('providers', resp.data);
      }, function (resp) {
        console.log(resp);
      }
    );
  },
  methods: {

    getList: function () {
      this.loader.refresh = true;
      this.$http.get('', { region: this.region, key: this.key, provider: this.provider })
        .then(function (resp) {
          this.$set('vpns', resp.data);
          this.loader.refresh = false;
        }, function (resp) {
          console.log(resp);
          this.loader.refresh = false;
        }
      );
    },

    create: function () {
      this.loader.create = true;
      this.$http.post('', { region: this.region, key: this.key, provider: this.provider })
        .then(function (resp) {
          this.loader.create = false;
          if (this.vpns === undefined) {
            this.$set('vpns', []);
          }
          this.vpns.push(resp.data);
        }, function (resp) {
          this.loader.create = false;
          console.log(resp);
        }
      );
    },

    remove: function (vpn) {
      this.$http.delete('', { vpn_id: vpn.id, key: this.key, provider: this.provider })
        .then(function (resp) {
          this.vpns.splice(this.vpns.indexOf(vpn), 1);
        }, function (resp) {
          console.log(resp);
        }
      );
    }
  },
  watch: {
    'provider': function (val, oldVal) {
        if (!this.key || !val) {
          return ;
        }
        this.$http.get('regions', { provider: this.provider, key: this.key })
        .then(function (resp) {
          this.$set('regions', resp.data);
          if (this.checked) {
              localStorage.provider = this.provider;
          }
        }, function (resp) {
          console.log(resp)
        }
      );
    },
    'key': function (val, oldVal) {
        if (!this.provider || !val) {
          return ;
        }
        this.$http.get('regions', { provider: this.provider, key: this.key })
        .then(function (resp) {
          this.$set('regions', resp.data);
          this.getList();
          if (this.checked) {
              localStorage._key = this.key;
          }
        }, function (resp) {
          console.log(resp)
        }
      );
    },
    'region': function (val, oldVal) {
        if (this.checked) {
            localStorage.region = this.region;
        }
    },
    'checked': function (val, oldVal) {
        if (val) {
          localStorage.provider = this.provider;
          localStorage.region = this.region;
          localStorage._key = this.key;
        } else {
          localStorage.removeItem('provider');
          localStorage.removeItem('region');
          localStorage.removeItem('_key');
        }
    }
  }
})
<|endoftext|>


<commit_before>// Copyright (c) Martin Costello, 2017. All rights reserved.
// Licensed under the MIT. See the LICENSE file in the project root for full license information.

"use strict";

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;
    const headers = response.headers;

    const values = [
        { key: "Content-Security-Policy", value: "default-src 'self'; child-src 'self' platform.twitter.com syndication.twitter.com; connect-src 'self' syndication.twitter.com; frame-src platform.twitter.com syndication.twitter.com twitter.com; font-src 'self' fonts.gstatic.com stackpath.bootstrapcdn.com use.fontawesome.com; img-src 'self' abs.twimg.com cdn.martincostello.com csi.gstatic.com o.twimg.com pbs.twimg.com platform.twitter.com ssl.google-analytics.com www.google-analytics.com stats.g.doubleclick.net syndication.twitter.com ton.twimg.com data:; script-src 'self' ajax.googleapis.com apis.google.com cdn.syndication.twimg.com cdnjs.cloudflare.com connect.facebook.net stackpath.bootstrapcdn.com platform.twitter.com ssl.google-analytics.com www.google-analytics.com; style-src 'self' fonts.googleapis.com stackpath.bootstrapcdn.com platform.twitter.com ton.twimg.com use.fontawesome.com 'unsafe-inline'; report-uri https://martincostello.report-uri.io/r/default/csp/reportOnly;" },
        { key: "Expect-CT", value: "max-age=1800; report-uri https://martincostello.report-uri.io/r/default/ct/reportOnly" },
        { key: "Feature-Policy", value: "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'" },
        { key: "Referrer-Policy", value: "no-referrer-when-downgrade" },
        { key: "Strict-Transport-Security", value: "max-age=31536000" },
        { key: "X-Content-Type-Options", value: "nosniff" },
        { key: "X-Download-Options", value: "noopen" },
        { key: "X-Frame-Options", value: "DENY" },
        { key: "X-XSS-Protection", value: "1; mode=block" }
    ];

    values.forEach((header) => {
        headers[header.key] = [header];
    });

    callback(null, response);
};
<commit_msg>Fix CSP<commit_after>// Copyright (c) Martin Costello, 2017. All rights reserved.
// Licensed under the MIT. See the LICENSE file in the project root for full license information.

"use strict";

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;
    const headers = response.headers;

    const values = [
        { key: "Content-Security-Policy", value: "default-src 'self'; child-src 'self' platform.twitter.com syndication.twitter.com; connect-src 'self' syndication.twitter.com www.google-analytics.com; frame-src platform.twitter.com syndication.twitter.com twitter.com; font-src 'self' fonts.gstatic.com stackpath.bootstrapcdn.com use.fontawesome.com; img-src 'self' abs.twimg.com cdn.martincostello.com csi.gstatic.com o.twimg.com pbs.twimg.com platform.twitter.com ssl.google-analytics.com www.google-analytics.com stats.g.doubleclick.net syndication.twitter.com ton.twimg.com data:; script-src 'self' ajax.googleapis.com apis.google.com cdn.syndication.twimg.com cdnjs.cloudflare.com connect.facebook.net stackpath.bootstrapcdn.com platform.twitter.com ssl.google-analytics.com www.google-analytics.com; style-src 'self' fonts.googleapis.com stackpath.bootstrapcdn.com platform.twitter.com ton.twimg.com use.fontawesome.com 'unsafe-inline'; report-uri https://martincostello.report-uri.io/r/default/csp/reportOnly;" },
        { key: "Expect-CT", value: "max-age=1800; report-uri https://martincostello.report-uri.io/r/default/ct/reportOnly" },
        { key: "Feature-Policy", value: "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'" },
        { key: "Referrer-Policy", value: "no-referrer-when-downgrade" },
        { key: "Strict-Transport-Security", value: "max-age=31536000" },
        { key: "X-Content-Type-Options", value: "nosniff" },
        { key: "X-Download-Options", value: "noopen" },
        { key: "X-Frame-Options", value: "DENY" },
        { key: "X-XSS-Protection", value: "1; mode=block" }
    ];

    values.forEach((header) => {
        headers[header.key] = [header];
    });

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