<commit_before>angular
  .module('mage')
  .directive('leaflet', leaflet);

function leaflet() {
  var directive = {
    restrict: "A",
    replace: true,
    template: '

',
    controller: LeafletController,
    bindToController: true
  };

  return directive;
}

LeafletController.$inject = ['$rootScope', '$scope', '$interval', 'MapService', 'LocalStorageService'];

function LeafletController($rootScope, $scope, $interval, MapService, LocalStorageService) {
  var layers = {};
  var temporalLayers = [];
  var spiderfyState = null;
  var currentLocation = null;
  var locationLayer = L.locationMarker([0,0], {color: '#136AEC'});
  var map = L.map("map", {
    center: [0,0],
    zoom: 3,
    minZoom: 0,
    maxZoom: 18
  });

  // toolbar  and controls config
  var sidebar = L.control.sidebar('side-bar', {closeButton: false});
  map.addControl(new L.Control.MageFeature({
    onClick: function(latlng) {
      $scope.$emit('observation:create', latlng);
    }
  }));
  map.addControl(new L.Control.MageUserLocation({
    onLocation: onLocation,
    stopLocation: stopLocation
  }));
  map.addControl(new L.Control.MageListTools({
    onClick: function() {
      sidebar.toggle();
    }
  }));
  map.addControl(sidebar);
  sidebar.show();

  var layerControl = L.control.groupedLayers();
  layerControl.addTo(map);
  map.on('baselayerchange', function(baseLayer) {
    var layer = layers[baseLayer.name];
    MapService.selectBaseLayer(layer);
  });

  map.on('overlayadd', function(overlay, name) {
    var layer = layers[overlay.name];
    MapService.overlayAdded(layer);
  });

  function onLocation(location, broadcast) {
    // no need to do anything if the location has not changed
    if (currentLocation &&
        (currentLocation.lat === location.latlng.lat &&
         currentLocation.lng === location.latlng.lng &&
         currentLocation.accuracy === location.accuracy)) {
      return;
    }
    currentLocation = location;

    map.fitBounds(location.bounds);
    locationLayer.setLatLng(location.latlng).setAccuracy(location.accuracy);

    if (!map.hasLayer(locationLayer)) {
      map.addLayer(locationLayer);
    }

    if (broadcast) MapService.onLocation(location);
  }

  function stopLocation() {
    if (map.hasLayer(locationLayer)) {
      map.removeLayer(locationLayer);
    }

    currentLocation = null;
  }

  // setup my listeners
  var listener = {
    onLayerRemoved: onLayerRemoved,
    onLayersChanged: onLayersChanged,
    onFeaturesChanged: onFeaturesChanged,
    onFeatureZoom: onFeatureZoom,
    onPoll: onPoll
  };
  MapService.addListener(listener);

  $scope.$on('$destroy', function() {
    MapService.removeListener(listener);
  });

  function createMarker(marker) {
    // cannot create another marker with the same id
    if (layers[marker.layerId]) return;

    var options = marker.options || {};

    if (marker.geometry && marker.geometry.type === 'Point') {
      var latlng = [0, 0];
      if (marker.geometry.coordinates) {
        latlng = [marker.geometry.coordinates[1], marker.geometry.coordinates[0]];
      } else {
        latlng = map.getCenter();
      }

      var layer = L.marker(latlng, {
        draggable: options.draggable,
        icon: L.AwesomeMarkers.newDivIcon({
          icon: 'plus',
          color: 'cadetblue'
        })
      });

      if (_.isFunction(options.onDragEnd)) {
        layer.on('dragend', function() {
          options.onDragEnd(layer.getLatLng());
        });
      }

      if (options.selected) layer.addTo(map);
      layers[marker.layerId] = {layer: layer};
    }
  }

  function updateMarker(marker) {
    var layer = layers[marker.id];
    if (marker.geometry && marker.geometry.type === 'Point') {
      layer.setLatLng([marker.geometry.coordinates[1], marker.geometry.coordinates[0]]);
    }
  }

  // TODO move into leaflet ***REMOVED***, this and map clip both use it
  function createRasterLayer(layerInfo) {
    var baseLayer = null;
    var options = {};
    if (layerInfo.format == 'XYZ' || layerInfo.format == 'TMS') {
      options = { tms: layerInfo.format == 'TMS', maxZoom: 18}
      layerInfo.layer = new L.TileLayer(layerInfo.url, options);
    } else if (layerInfo.format == 'WMS') {
      options = {
        layers: layerInfo.wms.layers,
        version: layerInfo.wms.version,
        format: layerInfo.wms.format,
        transparent: layerInfo.wms.transparent
      };

      if (layerInfo.wms.styles) options.styles = layerInfo.wms.styles;
      layerInfo.layer = new L.TileLayer.WMS(layerInfo.url, options);
    }

    layers[layerInfo.name] = layerInfo;

    if (layerInfo.base) {
      layerControl.addBaseLayer(layerInfo.layer, layerInfo.name);
    } else {
      layerControl.addOverlay(layerInfo.layer, layerInfo.name, 'Static Layers');
    }

    if (layerInfo.options && layerInfo.options.selected) layerInfo.layer.addTo(map);
  }

  function colorForFeature(feature, options) {
    var age = Date.now() - moment(feature.properties[options.property]).valueOf();
    var bucket = _.find(options.colorBuckets, function(bucket) { return age > bucket.min && age <= bucket.max; });
    return bucket ? bucket.color : null;
  }

  function createGeoJsonForLayer(json, layerInfo) {
    var popup = layerInfo.options.popup;

    var geojson = L.geoJson(json, {
      onEachFeature: function (feature, layer) {
        if (popup) {
          if (_.isFunction(popup.html)) {
            var options = {};
            if (popup.closeButton != null) options.closeButton = popup.closeButton;
            layer.bindPopup(popup.html(feature), options);
          }

          if (_.isFunction(popup.onOpen)) {
            layer.on('popupopen', function() {
              popup.onOpen(feature);
            });
          }

          if (_.isFunction(popup.onClose)) {
            layer.on('popupclose', function() {
              popup.onClose(feature);
            });
          }
        }

        if (layerInfo.options.showAccuracy) {
          layer.on('popupopen', function() {
            layer.setAccuracy(layer.feature.properties.accuracy);
          });

          layer.on('popupclose', function() {
            layer.setAccuracy(null);
          });
        }

        layerInfo.featureIdToLayer[feature.id] = layer;
      },
      pointToLayer: function (feature, latlng) {
        if (layerInfo.options.temporal) {
          // TODO temporal layers should be fixed width as well, ie use fixedWidthMarker cl***REMOVED***
          var options = {
            color: colorForFeature(feature, layerInfo.options.temporal)
          };
          if (feature.style && feature.style.iconUrl) options.iconUrl = feature.style.iconUrl + '?access_token=' + LocalStorageService.getToken();

          return L.locationMarker(latlng, options);
        } else {
          var options = {};
          if (feature.style && feature.style.iconUrl) options.iconUrl = feature.style.iconUrl + '?access_token=' + LocalStorageService.getToken()
          return L.fixedWidthMarker(latlng, options);
        }
      },
      style: function(feature) {
        return feature.style;
      }
    });

    return geojson;
  }

  function createGeoJsonLayer(data) {
    var layerInfo = {
      type: 'geojson',
      featureIdToLayer: {},
      options: data.options
    };

    var geojson = createGeoJsonForLayer(data.geojson, layerInfo);
    if (data.options.cluster) {
      layerInfo.layer = L.markerClusterGroup().addLayer(geojson);
      layerInfo.layer.on('spiderfied', function(e) {
        if (spiderfyState) {
          spiderfyState.layer.openPopup();
        }
      });
    } else {
      layerInfo.layer = geojson;
    }

    layers[data.name] = layerInfo;
    if (data.options.temporal) temporalLayers.push(layerInfo);

    layerControl.addOverlay(layerInfo.layer, data.name, data.group);
    if (data.options.selected) layerInfo.layer.addTo(map);
  }

  function onLayersChanged(changed) {
    _.each(changed.added, function(added) {
      switch(added.type) {
        case 'Feature':
          createMarker(added);
          break;
        case 'Imagery':
          createRasterLayer(added);
          break;
        case 'geojson':
          createGeoJsonLayer(added);
          break;
      }
    });

    _.each(changed.updated, function(updated) {
      switch(updated.type) {
        case 'Feature':
          updateMarker(updated);
          break;
      }
    });

    _.each(changed.removed, function(removed) {
      var layer = layers[removed.layerId];
      if (layer) {
        map.removeLayer(layer.layer);
        delete layer.layer;
        delete layer;
        delete layers[removed.layerId];
      }
    });
  }

  function onFeaturesChanged(changed) {
    var featureLayer = layers[changed.name];

    _.each(changed.added, function(feature) {
      if (featureLayer.options.cluster) {
        featureLayer.layer.addLayer(createGeoJsonForLayer(feature, featureLayer));
      } else {
        featureLayer.layer.addData(feature);
      }

    });

    _.each(changed.updated, function(feature) {
      var layer = featureLayer.featureIdToLayer[feature.id];

      // Copy over the updated feature data
      if (layer.feature) {
        layer.feature = feature;
      }

      // Set the icon
      if (layer.feature && layer.feature.iconUrl !== feature.iconUrl) {
        layer.setIcon(L.urlDivIcon({
            feature: feature,
            token: LocalStorageService.getToken()
          })
        );
      }

      if (featureLayer.options.temporal) {
        var color = colorForFeature(feature, featureLayer.options.temporal);
        layer.setColor(color);
      }

      // Set the lat/lng
      if (feature.geometry.coordinates) {
        layer.setLatLng(L.GeoJSON.coordsToLatLng(feature.geometry.coordinates));
        if (featureLayer.options.showAccuracy && layer.getAccuracy()) {
          layer.setAccuracy(layer.feature.properties.accuracy);
        }
      }
    });

    _.each(changed.removed, function(feature) {
      var layer = featureLayer.featureIdToLayer[feature.id];
      featureLayer.layer.removeLayer(layer);
    });
  }

  function openPopup(layer, options) {
    options = options || {};
    var zoom = options.zoomToLocation ? 17: map.getZoom();
    var bounds = map.getBounds();
    if (options.zoomToLocation && (!bounds.contains(layer.getLatLng()) || zoom != map.getZoom())) {
      map.once('moveend', function() {
        layer.openPopup();
      });

      map.setView(layer.getLatLng(), zoom);
    } else {
      layer.openPopup();
    }
  }

  function onFeatureZoom(zoom) {
    var featureLayer = layers[zoom.name];
    var layer = featureLayer.featureIdToLayer[zoom.feature.id];
    if (!map.hasLayer(featureLayer.layer)) return;

    if (featureLayer.options.cluster) {
      if (map.getZoom() < 17) {
        map.once('zoomend', function() {
          featureLayer.layer.zoomToShowLayer(layer, function() {
            openPopup(layer);
          });
        });
        map.setZoom(17);
      } else {
        featureLayer.layer.zoomToShowLayer(layer, function() {
          openPopup(layer);
        });
      }
    } else {
      openPopup(layer, {zoomToLocation: true});
    }
  }

  function onPoll() {
    adjustTemporalLayers();
  }

  function adjustTemporalLayers() {
    _.each(temporalLayers, function(temporalLayer) {
      _.each(temporalLayer.featureIdToLayer, function(layer) {
        var color = colorForFeature(layer.feature, temporalLayer.options.temporal);
        layer.setColor(color);
      });
    });
  }

  function onLayerRemoved(layer) {
    var layerInfo = layers[layer.name];
    if (layerInfo) {
      map.removeLayer(layerInfo.layer);
      layerControl.removeLayer(layerInfo.layer);
      delete layers[layer.name];
    }
  }
}
<commit_msg>Set popup auto follow to false<commit_after>angular
  .module('mage')
  .directive('leaflet', leaflet);

function leaflet() {
  var directive = {
    restrict: "A",
    replace: true,
    template: '

',
    controller: LeafletController,
    bindToController: true
  };

  return directive;
}

LeafletController.$inject = ['$rootScope', '$scope', '$interval', 'MapService', 'LocalStorageService'];

function LeafletController($rootScope, $scope, $interval, MapService, LocalStorageService) {
  var layers = {};
  var temporalLayers = [];
  var spiderfyState = null;
  var currentLocation = null;
  var locationLayer = L.locationMarker([0,0], {color: '#136AEC'});
  var map = L.map("map", {
    center: [0,0],
    zoom: 3,
    minZoom: 0,
    maxZoom: 18
  });

  // toolbar  and controls config
  var sidebar = L.control.sidebar('side-bar', {closeButton: false});
  map.addControl(new L.Control.MageFeature({
    onClick: function(latlng) {
      $scope.$emit('observation:create', latlng);
    }
  }));
  map.addControl(new L.Control.MageUserLocation({
    onLocation: onLocation,
    stopLocation: stopLocation
  }));
  map.addControl(new L.Control.MageListTools({
    onClick: function() {
      sidebar.toggle();
    }
  }));
  map.addControl(sidebar);
  sidebar.show();

  var layerControl = L.control.groupedLayers();
  layerControl.addTo(map);
  map.on('baselayerchange', function(baseLayer) {
    var layer = layers[baseLayer.name];
    MapService.selectBaseLayer(layer);
  });

  map.on('overlayadd', function(overlay, name) {
    var layer = layers[overlay.name];
    MapService.overlayAdded(layer);
  });

  function onLocation(location, broadcast) {
    // no need to do anything if the location has not changed
    if (currentLocation &&
        (currentLocation.lat === location.latlng.lat &&
         currentLocation.lng === location.latlng.lng &&
         currentLocation.accuracy === location.accuracy)) {
      return;
    }
    currentLocation = location;

    map.fitBounds(location.bounds);
    locationLayer.setLatLng(location.latlng).setAccuracy(location.accuracy);

    if (!map.hasLayer(locationLayer)) {
      map.addLayer(locationLayer);
    }

    if (broadcast) MapService.onLocation(location);
  }

  function stopLocation() {
    if (map.hasLayer(locationLayer)) {
      map.removeLayer(locationLayer);
    }

    currentLocation = null;
  }

  // setup my listeners
  var listener = {
    onLayerRemoved: onLayerRemoved,
    onLayersChanged: onLayersChanged,
    onFeaturesChanged: onFeaturesChanged,
    onFeatureZoom: onFeatureZoom,
    onPoll: onPoll
  };
  MapService.addListener(listener);

  $scope.$on('$destroy', function() {
    MapService.removeListener(listener);
  });

  function createMarker(marker) {
    // cannot create another marker with the same id
    if (layers[marker.layerId]) return;

    var options = marker.options || {};

    if (marker.geometry && marker.geometry.type === 'Point') {
      var latlng = [0, 0];
      if (marker.geometry.coordinates) {
        latlng = [marker.geometry.coordinates[1], marker.geometry.coordinates[0]];
      } else {
        latlng = map.getCenter();
      }

      var layer = L.marker(latlng, {
        draggable: options.draggable,
        icon: L.AwesomeMarkers.newDivIcon({
          icon: 'plus',
          color: 'cadetblue'
        })
      });

      if (_.isFunction(options.onDragEnd)) {
        layer.on('dragend', function() {
          options.onDragEnd(layer.getLatLng());
        });
      }

      if (options.selected) layer.addTo(map);
      layers[marker.layerId] = {layer: layer};
    }
  }

  function updateMarker(marker) {
    var layer = layers[marker.id];
    if (marker.geometry && marker.geometry.type === 'Point') {
      layer.setLatLng([marker.geometry.coordinates[1], marker.geometry.coordinates[0]]);
    }
  }

  // TODO move into leaflet ***REMOVED***, this and map clip both use it
  function createRasterLayer(layerInfo) {
    var baseLayer = null;
    var options = {};
    if (layerInfo.format == 'XYZ' || layerInfo.format == 'TMS') {
      options = { tms: layerInfo.format == 'TMS', maxZoom: 18}
      layerInfo.layer = new L.TileLayer(layerInfo.url, options);
    } else if (layerInfo.format == 'WMS') {
      options = {
        layers: layerInfo.wms.layers,
        version: layerInfo.wms.version,
        format: layerInfo.wms.format,
        transparent: layerInfo.wms.transparent
      };

      if (layerInfo.wms.styles) options.styles = layerInfo.wms.styles;
      layerInfo.layer = new L.TileLayer.WMS(layerInfo.url, options);
    }

    layers[layerInfo.name] = layerInfo;

    if (layerInfo.base) {
      layerControl.addBaseLayer(layerInfo.layer, layerInfo.name);
    } else {
      layerControl.addOverlay(layerInfo.layer, layerInfo.name, 'Static Layers');
    }

    if (layerInfo.options && layerInfo.options.selected) layerInfo.layer.addTo(map);
  }

  function colorForFeature(feature, options) {
    var age = Date.now() - moment(feature.properties[options.property]).valueOf();
    var bucket = _.find(options.colorBuckets, function(bucket) { return age > bucket.min && age <= bucket.max; });
    return bucket ? bucket.color : null;
  }

  function createGeoJsonForLayer(json, layerInfo) {
    var popup = layerInfo.options.popup;

    var geojson = L.geoJson(json, {
      onEachFeature: function (feature, layer) {
        if (popup) {
          if (_.isFunction(popup.html)) {
            var options = {autoPan: false};
            if (popup.closeButton != null) options.closeButton = popup.closeButton;
            layer.bindPopup(popup.html(feature), options);
          }

          if (_.isFunction(popup.onOpen)) {
            layer.on('popupopen', function() {
              popup.onOpen(feature);
            });
          }

          if (_.isFunction(popup.onClose)) {
            layer.on('popupclose', function() {
              popup.onClose(feature);
            });
          }
        }

        if (layerInfo.options.showAccuracy) {
          layer.on('popupopen', function() {
            layer.setAccuracy(layer.feature.properties.accuracy);
          });

          layer.on('popupclose', function() {
            layer.setAccuracy(null);
          });
        }

        layerInfo.featureIdToLayer[feature.id] = layer;
      },
      pointToLayer: function (feature, latlng) {
        if (layerInfo.options.temporal) {
          // TODO temporal layers should be fixed width as well, ie use fixedWidthMarker cl***REMOVED***
          var options = {
            color: colorForFeature(feature, layerInfo.options.temporal)
          };
          if (feature.style && feature.style.iconUrl) options.iconUrl = feature.style.iconUrl + '?access_token=' + LocalStorageService.getToken();

          return L.locationMarker(latlng, options);
        } else {
          var options = {};
          if (feature.style && feature.style.iconUrl) options.iconUrl = feature.style.iconUrl + '?access_token=' + LocalStorageService.getToken()
          return L.fixedWidthMarker(latlng, options);
        }
      },
      style: function(feature) {
        return feature.style;
      }
    });

    return geojson;
  }

  function createGeoJsonLayer(data) {
    var layerInfo = {
      type: 'geojson',
      featureIdToLayer: {},
      options: data.options
    };

    var geojson = createGeoJsonForLayer(data.geojson, layerInfo);
    if (data.options.cluster) {
      layerInfo.layer = L.markerClusterGroup().addLayer(geojson);
      layerInfo.layer.on('spiderfied', function(e) {
        if (spiderfyState) {
          spiderfyState.layer.openPopup();
        }
      });
    } else {
      layerInfo.layer = geojson;
    }

    layers[data.name] = layerInfo;
    if (data.options.temporal) temporalLayers.push(layerInfo);

    layerControl.addOverlay(layerInfo.layer, data.name, data.group);
    if (data.options.selected) layerInfo.layer.addTo(map);
  }

  function onLayersChanged(changed) {
    _.each(changed.added, function(added) {
      switch(added.type) {
        case 'Feature':
          createMarker(added);
          break;
        case 'Imagery':
          createRasterLayer(added);
          break;
        case 'geojson':
          createGeoJsonLayer(added);
          break;
      }
    });

    _.each(changed.updated, function(updated) {
      switch(updated.type) {
        case 'Feature':
          updateMarker(updated);
          break;
      }
    });

    _.each(changed.removed, function(removed) {
      var layer = layers[removed.layerId];
      if (layer) {
        map.removeLayer(layer.layer);
        delete layer.layer;
        delete layer;
        delete layers[removed.layerId];
      }
    });
  }

  function onFeaturesChanged(changed) {
    var featureLayer = layers[changed.name];

    _.each(changed.added, function(feature) {
      if (featureLayer.options.cluster) {
        featureLayer.layer.addLayer(createGeoJsonForLayer(feature, featureLayer));
      } else {
        featureLayer.layer.addData(feature);
      }

    });

    _.each(changed.updated, function(feature) {
      var layer = featureLayer.featureIdToLayer[feature.id];

      // Copy over the updated feature data
      if (layer.feature) {
        layer.feature = feature;
      }

      // Set the icon
      if (layer.feature && layer.feature.iconUrl !== feature.iconUrl) {
        layer.setIcon(L.urlDivIcon({
            feature: feature,
            token: LocalStorageService.getToken()
          })
        );
      }

      if (featureLayer.options.temporal) {
        var color = colorForFeature(feature, featureLayer.options.temporal);
        layer.setColor(color);
      }

      // Set the lat/lng
      if (feature.geometry.coordinates) {
        layer.setLatLng(L.GeoJSON.coordsToLatLng(feature.geometry.coordinates));
        if (featureLayer.options.showAccuracy && layer.getAccuracy()) {
          layer.setAccuracy(layer.feature.properties.accuracy);
        }
      }
    });

    _.each(changed.removed, function(feature) {
      var layer = featureLayer.featureIdToLayer[feature.id];
      featureLayer.layer.removeLayer(layer);
    });
  }

  function openPopup(layer, options) {
    options = options || {};
    var zoom = options.zoomToLocation ? 17: map.getZoom();
    var bounds = map.getBounds();
    if (options.zoomToLocation && (!bounds.contains(layer.getLatLng()) || zoom != map.getZoom())) {
      map.once('moveend', function() {
        layer.openPopup();
      });

      map.setView(layer.getLatLng(), zoom);
    } else {
      layer.openPopup();
    }
  }

  function onFeatureZoom(zoom) {
    var featureLayer = layers[zoom.name];
    var layer = featureLayer.featureIdToLayer[zoom.feature.id];
    if (!map.hasLayer(featureLayer.layer)) return;

    if (featureLayer.options.cluster) {
      if (map.getZoom() < 17) {
        map.once('zoomend', function() {
          featureLayer.layer.zoomToShowLayer(layer, function() {
            openPopup(layer);
          });
        });
        map.setZoom(17);
      } else {
        featureLayer.layer.zoomToShowLayer(layer, function() {
          openPopup(layer);
        });
      }
    } else {
      openPopup(layer, {zoomToLocation: true});
    }
  }

  function onPoll() {
    adjustTemporalLayers();
  }

  function adjustTemporalLayers() {
    _.each(temporalLayers, function(temporalLayer) {
      _.each(temporalLayer.featureIdToLayer, function(layer) {
        var color = colorForFeature(layer.feature, temporalLayer.options.temporal);
        layer.setColor(color);
      });
    });
  }

  function onLayerRemoved(layer) {
    var layerInfo = layers[layer.name];
    if (layerInfo) {
      map.removeLayer(layerInfo.layer);
      layerControl.removeLayer(layerInfo.layer);
      delete layers[layer.name];
    }
  }
}
<|endoftext|>


<commit_before>
// acorn.shells.YouTubeShell -- links to youtube video and embeds it.
// ------------------------------------------------------------------

var YouTubeShell = acorn.shells.YouTubeShell = VideoLinkShell.extend({

  shellid: 'acorn.YouTubeShell',

  // The cannonical type of this media. One of `acorn.types`.
  type: 'video',

  // **youtubeId** returns the youtube video id of this link.
  youtubeId: function() {
    var link = this.link();

    var re = this.urlMatches(link);
    assert(re, 'Incorrect youtube link, no video id found.');

    var videoid = re.exec(link)[3];
    return videoid;
  },

  embedLink: function() {
    // see https://developers.google.com/youtube/player_parameters for options
    return 'http://www.youtube.com/embed/' + this.youtubeId() + '?'
         + '&fs=1'
         // + '&modestbranding=1'
         + '&iv_load_policy=3'
         + '&rel=0'
         + '&showsearch=0'
         + '&showinfo=0'
         + '&hd=1'
         + '&wmode=transparent'
         + '&enablejsapi=1'
         + '&controls=1'
         ;
  },

  // **thumbnailLink** returns the link to the thumbnail image
  thumbnailLink: function() {
    return "https://img.youtube.com/vi/" + this.youtubeId() + "/0.jpg";
  },

  extraInfoLink: function() {
    return 'http://gdata.youtube.com/feeds/api/videos/' + this.youtubeId()
         + '?v=2'
         + '&alt=jsonc';
  },

  // **title** returns a simple title of the shell
  title: function() {
    return this.extraInfo ? this.extraInfo.data.title : this.link();
  },

  // **description** returns a simple description of the shell
  description: function() {
    return 'Seconds ' + (this.data.time_start || 0)
         + ' to ' + (this.data.time_end || this.duration())
         + ' of YouTube video '
         + this.link();
  },

  duration: function() {
    return this.extraInfo ? this.extraInfo.data.duration : this.data.time_end;
  },

  // **validRegexes** list of valid LinkRegexes
  validRegexes: [
    UrlRegExp('(www\.)?youtube\.com\/v\/([A-Za-z0-9\-_]+).*'),
    UrlRegExp('(www\.)?youtube\.com\/embed\/([A-Za-z0-9\-_]+).*'),
    UrlRegExp('(www\.)?youtube\.com\/watch\?.*v=([A-Za-z0-9\-_]+).*'),
    UrlRegExp('(www\.)?y2u.be\/([A-Za-z0-9\-_]+)'),
  ],

});

// ContentView -- displays the embedded player, and interacts through js api.
// --------------------------------------------------------------------------

YouTubeShell.ContentView = VideoLinkShell.ContentView.extend({

  render: function() {
    VideoLinkShell.ContentView.prototype.render.call(this);

    // initialize YouTube setup.
    this.onYTInitialize();

    // add the YouTube player iframe
    var link = this.shell.embedLink();
    this.$el.append(iframe(link, 'ytplayer'));
  },

  // YouTube API - communication between the YouTube js API and the shell.
  // ---------------------------------------------------------------------
  // see https://developers.google.com/youtube/js_api_reference

  // the javascript file with the youtube player api.
  youtubePlayerApiSrc: 'http://www.youtube.com/iframe_api',

  // initialize youtube API
  onYTInitialize: function() {
    // initialization should only happen once per page load.

    // if YT hasn't been initialized, initialize it.
    if (!window.onYouTubeIframeAPIReady) {

      // setup YT ready callback
      window.onYouTubeIframeAPIReady = this.onYTReady;

      // include the YouTubePlayerAPI code
      var script = $('<script>').attr('src', this.youtubePlayerApiSrc);
      $('body').append(script);

      return; // onYTReady will be called when YT finishes initializing
    }

    // must call onYTReady once the current render call stack finishes
    // because the frame is not yet on the page. YT API expects the id
    // of a player currently on the page. Backbone has yet to add the
    // current DOM subtree to the page DOM. setTimeout will schedule
    // the callback after the current stack finishes.
    setTimeout(this.onYTReady, 0);
  },

  // The YT API is ready for use
  onYTReady: function() {

    // initialize the `ytplayer` object
    this.ytplayer = new YT.Player('ytplayer', {
      events: {
        'onReady': this.onYTPlayerReady,
        'onStateChange': this.onYTPlayerStateChange,
      }
    });

    // clear the callback function, but set empty function:
    // * in case the callback gets called again
    // * to signal YT has already been initialized
    window.onYouTubeIframeAPIReady = function() {};
  },

  onYTPlayerReady: function() {

    // tell `ytplayer` to load the video, with given start time.
    // this *should* initialize the playback at the correct point,
    // but in practice it doesn't. Need a robust solution (tick).
    var start = parseInt(this.shell.data.time_start || 0);

    if (this.options.autoplay) {
      this.ytplayer.loadVideoById(this.shell.youtubeId(), start);
    } else {
      this.ytplayer.cueVideoById(this.shell.youtubeId(), start);
      this.play();
    }
  },

  onYTPlayerStateChange: function(event) {
    var state = event.data;
    // ``event.data`` ought to equal ``this.ytplayer.getPlayerState()``.
    // I'm using ``event.data`` here in case events get fired from other
    // YouTube Players?? Seems safer to trust the function paramters.

    if (state == YT.PlayerState.PLAYING)
      this.timer.startTick();
    else
      this.timer.stopTick();
  },

  // VideoLinkShell.ContentView interface -- overriding with native impl
  // -------------------------------------------------------------------

  // -- Information:

  // the total duration in seconds
  totalTime: function() {
    return this.ytplayer.getDuration() || Infinity;
  },

  // the current playback position in seconds
  currentTime: function() {
    return this.ytplayer.getCurrentTime();
  },

  // whether the video is currently playing
  isPlaying: function() {
    if (!this.ytplayer)
      return false;

    var state = this.ytplayer.getPlayerState();
    return (state == YT.PlayerState.PLAYING);
  },

  // -- Actions:

  // begins playing the video (idempotent)
  play: function() {
    this.ytplayer.playVideo();
  },

  // stops playing the video (idempotent)
  stop: function() {
    this.ytplayer.pauseVideo();
  },

  // seeks to the specific offset in seconds
  seek: function(seconds) {
    this.ytplayer.seekTo(seconds, true);
  },

});

// EditView -- video link, time clipping, and other options.
// ---------------------------------------------------------

YouTubeShell.EditView = VideoLinkShell.EditView.extend({
  // Overrides LinkShell.generateThumbnailLink()
  generateThumbnailLink: function(callback) {
    callback = callback || function() {};
    callback(this.shell.thumbnailLink());
  },
});

// Register the shell with the acorn object.
acorn.registerShell(YouTubeShell);
<commit_msg>Added TODO.<commit_after>
// acorn.shells.YouTubeShell -- links to youtube video and embeds it.
// ------------------------------------------------------------------

var YouTubeShell = acorn.shells.YouTubeShell = VideoLinkShell.extend({

  shellid: 'acorn.YouTubeShell',

  // The cannonical type of this media. One of `acorn.types`.
  type: 'video',

  // **youtubeId** returns the youtube video id of this link.
  youtubeId: function() {
    var link = this.link();

    var re = this.urlMatches(link);
    assert(re, 'Incorrect youtube link, no video id found.');

    var videoid = re.exec(link)[3];
    return videoid;
  },

  embedLink: function() {
    // see https://developers.google.com/youtube/player_parameters for options
    return 'http://www.youtube.com/embed/' + this.youtubeId() + '?'
         + '&fs=1'
         // + '&modestbranding=1'
         + '&iv_load_policy=3'
         + '&rel=0'
         + '&showsearch=0'
         + '&showinfo=0'
         + '&hd=1'
         + '&wmode=transparent'
         + '&enablejsapi=1'
         + '&controls=1'
         ;
  },

  // **thumbnailLink** returns the link to the thumbnail image
  thumbnailLink: function() {
    return "https://img.youtube.com/vi/" + this.youtubeId() + "/0.jpg";
  },

  extraInfoLink: function() {
    return 'http://gdata.youtube.com/feeds/api/videos/' + this.youtubeId()
         + '?v=2'
         + '&alt=jsonc';
  },

  // **title** returns a simple title of the shell
  title: function() {
    return this.extraInfo ? this.extraInfo.data.title : this.link();
  },

  // **description** returns a simple description of the shell
  description: function() {
    return 'Seconds ' + (this.data.time_start || 0)
         + ' to ' + (this.data.time_end || this.duration())
         + ' of YouTube video '
         + this.link();
  },

  duration: function() {
    return this.extraInfo ? this.extraInfo.data.duration : this.data.time_end;
  },

  // **validRegexes** list of valid LinkRegexes
  validRegexes: [
    UrlRegExp('(www\.)?youtube\.com\/v\/([A-Za-z0-9\-_]+).*'),
    UrlRegExp('(www\.)?youtube\.com\/embed\/([A-Za-z0-9\-_]+).*'),
    UrlRegExp('(www\.)?youtube\.com\/watch\?.*v=([A-Za-z0-9\-_]+).*'),
    UrlRegExp('(www\.)?y2u.be\/([A-Za-z0-9\-_]+)'),
  ],

});

// ContentView -- displays the embedded player, and interacts through js api.
// --------------------------------------------------------------------------

YouTubeShell.ContentView = VideoLinkShell.ContentView.extend({

  render: function() {
    VideoLinkShell.ContentView.prototype.render.call(this);

    // initialize YouTube setup.
    this.onYTInitialize();

    // add the YouTube player iframe
    var link = this.shell.embedLink();
    this.$el.append(iframe(link, 'ytplayer'));
  },

  // YouTube API - communication between the YouTube js API and the shell.
  // ---------------------------------------------------------------------
  // see https://developers.google.com/youtube/js_api_reference

  // the javascript file with the youtube player api.
  youtubePlayerApiSrc: 'http://www.youtube.com/iframe_api',

  // initialize youtube API
  onYTInitialize: function() {
    // initialization should only happen once per page load.

    // if YT hasn't been initialized, initialize it.
    if (!window.onYouTubeIframeAPIReady) {

      // setup YT ready callback
      window.onYouTubeIframeAPIReady = this.onYTReady;

      // include the YouTubePlayerAPI code
      var script = $('<script>').attr('src', this.youtubePlayerApiSrc);
      $('body').append(script);

      return; // onYTReady will be called when YT finishes initializing
    }

    // must call onYTReady once the current render call stack finishes
    // because the frame is not yet on the page. YT API expects the id
    // of a player currently on the page. Backbone has yet to add the
    // current DOM subtree to the page DOM. setTimeout will schedule
    // the callback after the current stack finishes.
    setTimeout(this.onYTReady, 0);
  },

  // The YT API is ready for use
  onYTReady: function() {

    // initialize the `ytplayer` object
    this.ytplayer = new YT.Player('ytplayer', {
      events: {
        'onReady': this.onYTPlayerReady,
        'onStateChange': this.onYTPlayerStateChange,
      }
    });

    // clear the callback function, but set empty function:
    // * in case the callback gets called again
    // * to signal YT has already been initialized
    window.onYouTubeIframeAPIReady = function() {};
  },

  onYTPlayerReady: function() {

    // tell `ytplayer` to load the video, with given start time.
    // this *should* initialize the playback at the correct point,
    // but in practice it doesn't. Need a robust solution (tick).
    var start = parseInt(this.shell.data.time_start || 0);

    if (this.options.autoplay) {
      this.ytplayer.loadVideoById(this.shell.youtubeId(), start);
    } else {
      this.ytplayer.cueVideoById(this.shell.youtubeId(), start);
      // TODO: what is this doing here? this seems to contrdict the if.
      this.play();
    }
  },

  onYTPlayerStateChange: function(event) {
    var state = event.data;
    // ``event.data`` ought to equal ``this.ytplayer.getPlayerState()``.
    // I'm using ``event.data`` here in case events get fired from other
    // YouTube Players?? Seems safer to trust the function paramters.

    if (state == YT.PlayerState.PLAYING)
      this.timer.startTick();
    else
      this.timer.stopTick();
  },

  // VideoLinkShell.ContentView interface -- overriding with native impl
  // -------------------------------------------------------------------

  // -- Information:

  // the total duration in seconds
  totalTime: function() {
    return this.ytplayer.getDuration() || Infinity;
  },

  // the current playback position in seconds
  currentTime: function() {
    return this.ytplayer.getCurrentTime();
  },

  // whether the video is currently playing
  isPlaying: function() {
    if (!this.ytplayer)
      return false;

    var state = this.ytplayer.getPlayerState();
    return (state == YT.PlayerState.PLAYING);
  },

  // -- Actions:

  // begins playing the video (idempotent)
  play: function() {
    this.ytplayer.playVideo();
  },

  // stops playing the video (idempotent)
  stop: function() {
    this.ytplayer.pauseVideo();
  },

  // seeks to the specific offset in seconds
  seek: function(seconds) {
    this.ytplayer.seekTo(seconds, true);
  },

});

// EditView -- video link, time clipping, and other options.
// ---------------------------------------------------------

YouTubeShell.EditView = VideoLinkShell.EditView.extend({
  // Overrides LinkShell.generateThumbnailLink()
  generateThumbnailLink: function(callback) {
    callback = callback || function() {};
    callback(this.shell.thumbnailLink());
  },
});

// Register the shell with the acorn object.
acorn.registerShell(YouTubeShell);
<|endoftext|>


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

/*
 * This is a common JavaScript file containing the code to support internationalization
 */
/**
 * List of all supported language keyed by 2 or 3 character ISO language.  The value is the display for the language
 */
var LANGUAGES = {"en":"English",
                 "ru":"Russian"};
//TODO: See if we can use I18N to populate this variable - i18next.languages should contain the language

/**************** For initializing the i18next framework ***********************/
		 i18next.use(i18nextXHRBackend);
			jqueryI18next.init(i18next, $);
			i18next.init({
		   fallbackLng: getCurrentLanguage(),
			 backend: {
		      loadPath: 'resources/locales/{{lng}}/translation.json'
		  		},

			}, function(err, t) {
				i18next.changeLanguage(getCurrentLanguage());

			});

/****************Get the current language from the URL***********/
			function getCurrentLanguage() {
				//TODO: See if we can get this from i18next - i18next should be the language, but it is not being set
				return (url('?locale') || 'en');
			}

/****************Error handling functions ***********************/

			function displayError( error ) {

				event.preventDefault();
			   	$.widget("ui.dialog", $.extend({}, $.ui.dialog.prototype, {
				    _title: function(title) {
				        if (!this.options.title ) {
				            title.html(" ");
				        } else {
				            title.html(this.options.title);
				        }
				    }
				}));

				$( "#errors" ).dialog({
					title:'Error',
					resizable: false,
				    height: 250,
				    width: 300,
				    dialogClass: 'success-dialog translate',
				    modal: true,
				    buttons: [{
				    	text: "Ok",
			    		"data-i18n": "Ok",
			    		 click: function () {
				            $( this ).dialog( "close" );
				        }
				    }]
				}).html ( error ).parent().addClass( "ui-state-error" );
				$('.translate').localize();
			}

			function handleError(xhr, status, errorThrown, msg) {
				if ( msg === undefined ) {
					var responseType = xhr.getResponseHeader("content-type") || "";
					if ( responseType.indexOf('text') >= 0 && xhr.responseText != null && xhr.responseText!= "" ) {
						msg = 'Sorry - there was a problem loading data:   ' + xhr.responseText;
					} else if ( responseType.indexOf('json') > 1 && xhr.responseText != null && xhr.responseText!= "" ) {
						response = JSON.parse(xhr.responseText);
						msg = response.error;
					} else {
						msg ='Sorry - there was a problem loading data:  ' + errorThrown;

					}
				}
				if ( xhr.status == 401 ) {
					// Redirect to login page
					window.location="login.html"+'?locale='+(url('?locale') || 'en');
				} else {
					displayError( msg );
			        console.log( "Error: " + xhr.responseText );
			        console.log( "Status: " + status );
			        console.dir( xhr );
				}
			}

/****************When Language is changed ***********************/

		function changeLng(lng)
		{
			if (!lng || !LANGUAGES[lng]) {
				displayError( "Language not supported" );
				return;
			}
			// update the back-end
			$.ajax({
				url: "CertificationServlet",
				data: JSON.stringify({
			        request:  "setlanguage",
			        language: lng,
			        locale: lng
			    }),
			    type: "POST",
			    dataType : "json",
			    contentType: "json",
			    async: false,
			    success: function( json ) {
			    	if ( json.status == "OK" ) {
			    		updateLanguageUI(lng);
			    	} else {
			    		displayError( json.error );
			    	}
			    },
			    error: function( xhr, status, errorThrown ) {
			    	handleError( xhr, status, errorThrown );
			    }
			});
		}

/**********Update the language user interface and I18N framework*********************/
		function updateLanguageUI(language) {
			if (language == getCurrentLanguage()) {
				return;	// already set.  This is an important check otherwise we will keep refreshing and calling the method
			}
			var u = new URL(window.location.href);
    		if(u.searchParams.has("locale"))
    		{
    			u.searchParams.set("locale",language ? language : (url('?locale') || 'en'));
    		}
    		else
    		{
    			u.searchParams.append("locale",language ? language : (url('?locale') || 'en'));
    		}
    		window.location.href=u;
    		i18next.changeLanguage(language ? language : (url('?locale') || 'en'));
		}

/****************Creates HTML choices for user dropdown list of language selections*********/
		function getLanguageSelectionHtml() {  // Used in the profile update and user signup pages
			var html = '';
			for (var lang in LANGUAGES) {
				html += '<option class="translate" data-i18n="';
				html += LANGUAGES[lang];
				html += '" value="';
				html += lang;
				html += '">';
				html += LANGUAGES[lang];
				html += ' (';
				html += lang;
				html += ')</option>\n';
			}
			return html;
		}
/****************Creates the HTML for the dropdown list items from the list of languages****/
		function getLanguageHtml() {	// Used for the main navigation language chooser dropdown
			var html = '';
			for (var lang in LANGUAGES) {
				html += '
';
				html += LANGUAGES[lang];
				html += ' (';
				html += lang;
				html += ')
\n';
			}
			return html;
		}

/*******************TO get the language of a previous page ***********************/

		$(document).delegate('.append','click', function($this){
			 event.preventDefault();
			 window.location.href = $(this).attr('href')+'?locale='+(url('?locale') || 'en');
		 });

/*****************Function to translate the HTML content***************************/

		i18next.on('languageChanged', () => {
			$('.translate').localize();
		});

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

/*
 * This is a common JavaScript file containing the code to support internationalization
 */
/**
 * List of all supported language keyed by 2 or 3 character ISO language.  The value is the display for the language
 */
var LANGUAGES = {"en":"English"};
//TODO: See if we can use I18N to populate this variable - i18next.languages should contain the language

/**************** For initializing the i18next framework ***********************/
		 i18next.use(i18nextXHRBackend);
			jqueryI18next.init(i18next, $);
			i18next.init({
		   fallbackLng: getCurrentLanguage(),
			 backend: {
		      loadPath: 'resources/locales/{{lng}}/translation.json'
		  		},

			}, function(err, t) {
				i18next.changeLanguage(getCurrentLanguage());

			});

/****************Get the current language from the URL***********/
			function getCurrentLanguage() {
				//TODO: See if we can get this from i18next - i18next should be the language, but it is not being set
				return (url('?locale') || 'en');
			}

/****************Error handling functions ***********************/

			function displayError( error ) {

				event.preventDefault();
			   	$.widget("ui.dialog", $.extend({}, $.ui.dialog.prototype, {
				    _title: function(title) {
				        if (!this.options.title ) {
				            title.html(" ");
				        } else {
				            title.html(this.options.title);
				        }
				    }
				}));

				$( "#errors" ).dialog({
					title:'Error',
					resizable: false,
				    height: 250,
				    width: 300,
				    dialogClass: 'success-dialog translate',
				    modal: true,
				    buttons: [{
				    	text: "Ok",
			    		"data-i18n": "Ok",
			    		 click: function () {
				            $( this ).dialog( "close" );
				        }
				    }]
				}).html ( error ).parent().addClass( "ui-state-error" );
				$('.translate').localize();
			}

			function handleError(xhr, status, errorThrown, msg) {
				if ( msg === undefined ) {
					var responseType = xhr.getResponseHeader("content-type") || "";
					if ( responseType.indexOf('text') >= 0 && xhr.responseText != null && xhr.responseText!= "" ) {
						msg = 'Sorry - there was a problem loading data:   ' + xhr.responseText;
					} else if ( responseType.indexOf('json') > 1 && xhr.responseText != null && xhr.responseText!= "" ) {
						response = JSON.parse(xhr.responseText);
						msg = response.error;
					} else {
						msg ='Sorry - there was a problem loading data:  ' + errorThrown;

					}
				}
				if ( xhr.status == 401 ) {
					// Redirect to login page
					window.location="login.html"+'?locale='+(url('?locale') || 'en');
				} else {
					displayError( msg );
			        console.log( "Error: " + xhr.responseText );
			        console.log( "Status: " + status );
			        console.dir( xhr );
				}
			}

/****************When Language is changed ***********************/

		function changeLng(lng)
		{
			if (!lng || !LANGUAGES[lng]) {
				displayError( "Language not supported" );
				return;
			}
			// update the back-end
			$.ajax({
				url: "CertificationServlet",
				data: JSON.stringify({
			        request:  "setlanguage",
			        language: lng,
			        locale: lng
			    }),
			    type: "POST",
			    dataType : "json",
			    contentType: "json",
			    async: false,
			    success: function( json ) {
			    	if ( json.status == "OK" ) {
			    		updateLanguageUI(lng);
			    	} else {
			    		displayError( json.error );
			    	}
			    },
			    error: function( xhr, status, errorThrown ) {
			    	handleError( xhr, status, errorThrown );
			    }
			});
		}

/**********Update the language user interface and I18N framework*********************/
		function updateLanguageUI(language) {
			if (language == getCurrentLanguage()) {
				return;	// already set.  This is an important check otherwise we will keep refreshing and calling the method
			}
			var u = new URL(window.location.href);
    		if(u.searchParams.has("locale"))
    		{
    			u.searchParams.set("locale",language ? language : (url('?locale') || 'en'));
    		}
    		else
    		{
    			u.searchParams.append("locale",language ? language : (url('?locale') || 'en'));
    		}
    		window.location.href=u;
    		i18next.changeLanguage(language ? language : (url('?locale') || 'en'));
		}

/****************Creates HTML choices for user dropdown list of language selections*********/
		function getLanguageSelectionHtml() {  // Used in the profile update and user signup pages
			var html = '';
			for (var lang in LANGUAGES) {
				html += '<option class="translate" data-i18n="';
				html += LANGUAGES[lang];
				html += '" value="';
				html += lang;
				html += '">';
				html += LANGUAGES[lang];
				html += ' (';
				html += lang;
				html += ')</option>\n';
			}
			return html;
		}
/****************Creates the HTML for the dropdown list items from the list of languages****/
		function getLanguageHtml() {	// Used for the main navigation language chooser dropdown
			var html = '';
			for (var lang in LANGUAGES) {
				html += '
';
				html += LANGUAGES[lang];
				html += ' (';
				html += lang;
				html += ')
\n';
			}
			return html;
		}

/*******************TO get the language of a previous page ***********************/

		$(document).delegate('.append','click', function($this){
			 event.preventDefault();
			 window.location.href = $(this).attr('href')+'?locale='+(url('?locale') || 'en');
		 });

/*****************Function to translate the HTML content***************************/

		i18next.on('languageChanged', () => {
			$('.translate').localize();
		});

/*************************************************************************************/
	<|endoftext|>


<commit_before>var fs = require('fs')
var util = require('util')
var dvbtee = require('../build/Release/dvbtee.node')

var filename

if (process.argv.length <= 2) {
  filename = 'sample.ts'
} else {
  filename = process.argv[2]
}

var parser = new dvbtee.Parser

parser.listenTables(function(a,b,data) {
  console.log('\ntable data:\n', util.inspect(data, false, null))
})

fs.readFile(filename, function(err, buf) {

    console.log('pushing ' + buf.length + ' bytes')

    parser.feed(buf, buf.length, function(err, status) {

      if (err)
          console.log(err)
      else
          console.log('complete: status = ' + status)
    })
})
<commit_msg>rm examples/pushfile.js<commit_after><|endoftext|>


<commit_before>$(function() {

  window.slap = {
    user: {
      email: 'andre@ventajou.com'
    }
  };

  function commentClick(e) {
    var el = $(e.target);
    if (el.hasClass('slp_commented')) {
      el = el.children('slp_token');
    }

    if (el.hasClass('slp_token')) {
      var popup = el.children('.slp_popup').get(0);

      $('.slp_popup').each(function() {
        if ($(this).get(0) == popup) {
          $(popup).toggleClass('slp_popup_visible');
        }
        else {
          $(this).removeClass('slp_popup_visible');
        }
      });
    }

    e.stopPropagation();
  }

  function keydownHandler(e) {
    if (e.which == 13) {
      if (e.ctrlKey) {
        e.target.value += '\n';
      }
      else {
        var selector = $(e.target).closest('.slp_comment').data('slp-id');

        var comment = {
          email: window.slap.user.email,
          date: new Date(),
          text: e.target.value
        };

        if (!window.slapComments[selector]) {
          window.slapComments[selector] = []
        }
        window.slapComments[selector].push(comment);
        addComment(selector, comment);
        e.target.value = '';
        e.target.blur();
      }
      e.preventDefault();
    }
  }

  function addComment(selector, comment) {
    var html = '

';
    if (comment.email) {
      var hash = MD5(comment.email);
      html += '';
    }
    html += '' + (comment.email || 'Anonymous') + '' +
            '' + comment.date.toLocaleDateString() + ' ' + comment.date.toLocaleTimeString() + '' +
            '

' + comment.text.replace('\n', '
') + '

';

    $(selector + ' ul').append(html);
  }

  function addThread(selector, comments, show) {
    var html = '
' +
      '
' + (comments.length || '?') + '

<textarea required placeholder="comment here"></textarea>' +
            '

';

    var el = $(selector);

    el.addClass('slp_commented');
    el.prepend(html);
    el.click(commentClick);
    $(selector + ' > .slp_comment textarea').on('keydown', keydownHandler);

    _.forEach(comments, function(c) { addComment(selector, c); });

    if (show) {
      el.find('.slp_comment textarea').focus();
    }
  };

  _.forEach(window.slapComments, function(value,key) { addThread(key, value, false); });

  function getPath(node) {
    // phase 1: generation
    var path = [];
    while (node) {
      name = node.localName;
      if (!name) break;
      name = name.toLowerCase();

      if (node.id && node.id !== '') {
        path.unshift('#' + node.id);
        break;
      }

      var parent = node.parentElement;
      if (!parent) break;
      if (node.classList.length > 0) {
        for (var i = 0; i < node.classList.length; i++) {
          var className = node.classList[i];
          var sameClassSiblings = [].filter.call(parent.children, function(e) {
            return [].indexOf.call(e.classList, className) > 0;
          });
          if (sameClassSiblings.length == 1) {
            name = '.' + className;
            break;
          }
        }
      } else {
        var sameTagSiblings = [].filter.call(parent.children, function(e) { return e.localName.toLowerCase() == name});
        if (sameTagSiblings.length > 1) {
          allSiblings = parent.children;
          var index = [].indexOf.call(allSiblings, node) + 1;
          if (index > 1) {
              name += ':nth-child(' + index + ')';
          }
        }
      }

      path.unshift(name);
      node = parent;
    }

    // phase 2: simplification
    var results = 0, tempPath, origPath = path.slice(0);;
    for (var i = path.length - 1; i >= 0; i--) {
      // tempPath = path[i] + (tempPath ? '>' + tempPath : '');
      tempPath = path.slice(i).join(' ');
      var newResults = document.querySelectorAll(tempPath).length;
      if (newResults == results) {
        path.splice(i, 1);
      } else {
        results = newResults;
      }
    }
    // simplification failed
    if (results != 1) {
      path = origPath;
    }

    return path.join(' > ');
  }

  $(document).click(function(e) {
    $('.slp_popup').removeClass('slp_popup_visible');

    addThread(getPath(e.target), [], true);
  });
})
<commit_msg>updating count in token when adding a comment<commit_after>$(function() {

  window.slap = {
    user: {
      email: 'andre@ventajou.com'
    }
  };

  function commentClick(e) {
    var el = $(e.target);
    if (el.hasClass('slp_commented')) {
      el = el.children('slp_token');
    }

    if (el.hasClass('slp_token')) {
      var popup = el.children('.slp_popup').get(0);

      $('.slp_popup').each(function() {
        if ($(this).get(0) == popup) {
          $(popup).toggleClass('slp_popup_visible');
        }
        else {
          $(this).removeClass('slp_popup_visible');
        }
      });
    }

    e.stopPropagation();
  }

  function keydownHandler(e) {
    if (e.which == 13) {
      if (e.ctrlKey) {
        e.target.value += '\n';
      }
      else {
        var selector = $(e.target).closest('.slp_comment').data('slp-id');

        var comment = {
          email: window.slap.user.email,
          date: new Date(),
          text: e.target.value
        };

        if (!window.slapComments[selector]) {
          window.slapComments[selector] = []
        }
        window.slapComments[selector].push(comment);
        addComment(selector, comment);
        $(selector + ' > .slp_comment .slp_count').text(window.slapComments[selector].length);
        e.target.value = '';
        e.target.blur();
      }
      e.preventDefault();
    }
  }

  function addComment(selector, comment) {
    var html = '

';
    if (comment.email) {
      var hash = MD5(comment.email);
      html += '';
    }
    html += '' + (comment.email || 'Anonymous') + '' +
            '' + comment.date.toLocaleDateString() + ' ' + comment.date.toLocaleTimeString() + '' +
            '

' + comment.text.replace('\n', '
') + '

';

    $(selector + ' > .slp_comment ul').append(html);
  }

  function addThread(selector, comments, show) {
    var html = '
' +
      '
' + (comments.length || '?') + '

<textarea required placeholder="comment here"></textarea>' +
            '

';

    var el = $(selector);

    el.addClass('slp_commented');
    el.prepend(html);
    el.click(commentClick);
    $(selector + ' > .slp_comment textarea').on('keydown', keydownHandler);

    _.forEach(comments, function(c) { addComment(selector, c); });

    if (show) {
      el.find('.slp_comment textarea').focus();
    }
  };

  _.forEach(window.slapComments, function(value,key) { addThread(key, value, false); });

  function getPath(node) {
    // phase 1: generation
    var path = [];
    while (node) {
      name = node.localName;
      if (!name) break;
      name = name.toLowerCase();

      if (node.id && node.id !== '') {
        path.unshift('#' + node.id);
        break;
      }

      var parent = node.parentElement;
      if (!parent) break;
      if (node.classList.length > 0) {
        for (var i = 0; i < node.classList.length; i++) {
          var className = node.classList[i];
          var sameClassSiblings = [].filter.call(parent.children, function(e) {
            return [].indexOf.call(e.classList, className) > 0;
          });
          if (sameClassSiblings.length == 1) {
            name = '.' + className;
            break;
          }
        }
      } else {
        var sameTagSiblings = [].filter.call(parent.children, function(e) { return e.localName.toLowerCase() == name});
        if (sameTagSiblings.length > 1) {
          allSiblings = parent.children;
          var index = [].indexOf.call(allSiblings, node) + 1;
          if (index > 1) {
              name += ':nth-child(' + index + ')';
          }
        }
      }

      path.unshift(name);
      node = parent;
    }

    // phase 2: simplification
    var results = 0, tempPath, origPath = path.slice(0);;
    for (var i = path.length - 1; i >= 0; i--) {
      // tempPath = path[i] + (tempPath ? '>' + tempPath : '');
      tempPath = path.slice(i).join(' ');
      var newResults = document.querySelectorAll(tempPath).length;
      if (newResults == results) {
        path.splice(i, 1);
      } else {
        results = newResults;
      }
    }
    // simplification failed
    if (results != 1) {
      path = origPath;
    }

    return path.join(' > ');
  }

  $(document).click(function(e) {
    $('.slp_popup').removeClass('slp_popup_visible');

    addThread(getPath(e.target), [], true);
  });
})
<|endoftext|>


<commit_before>import urls from '../../../../../src/lib/urls'

const selectAdvisersTypeahead = (fieldName, input) =>
  cy.get(fieldName).within(() => {
    cy.server()
    cy.route('/api-proxy/adviser/?*').as('adviserResults')
    cy.get('div').eq(0).type(input)
    cy.wait('@adviserResults')
    cy.get('[class*="menu"] > div').click()
  })

const assertTypehead = (element, label, placeholder, input, selectedOption) => {
  cy.get(element)
    .find('label')
    .should('have.text', label)
    .next()
    .should('contain', placeholder)
    .find('div')
    .eq(0)
    .type(input)
  cy.get(element).find('[class*="menu"] > div').click()
  cy.get(element).click()
  cy.get(element).should('contain', selectedOption)
}

const assertFilterIndicator = (count, label) => {
  cy.get(`main article div + div button:nth-child(${count})`).should((el) => {
    expect(el.text()).to.contain(label)
  })
}

const assertRemovedFilterIndicator = (element, placeholder = null) => {
  cy.get('main article div + div button').click()
  cy.get('main article div + div').should('be.empty')
  placeholder && cy.get(element).should('contain', placeholder)
}

describe('Investments Collections Filter', () => {
  beforeEach(() => {
    cy.get('aside button')
      .next()
      .find('#field-advisers')
      .as('adviserTypeaheadFilter')
      .next()
      .as('sectorFilter')
      .next()
      .as('estimatedDateBefore')
      .next()
      .as('estimatedDateAfter')
  })
  context('when the url contains no state', () => {
    before(() => {
      cy.visit(urls.investments.projects.index())
    })

    it('should filter by advisers', () => {
      cy.get('@adviserTypeaheadFilter')
        .should('contain', 'Search advisers')
        .find('label')
        .should('have.text', 'Advisers')

      selectAdvisersTypeahead('@adviserTypeaheadFilter', 'puc')
      cy.get('@adviserTypeaheadFilter').should('contain', 'Puck Head')
      assertFilterIndicator(1, 'Puck Head')
    })

    it('should remove the advisers filter', () => {
      assertRemovedFilterIndicator('@adviserTypeaheadFilter', 'Search advisers')
    })

    it('should filter by sector', () => {
      assertTypehead(
        '@sectorFilter',
        'Sector',
        'Search sectors',
        'adv',
        'Advanced Engineering'
      )
    })
    it('should remove the sector filter', () => {
      assertRemovedFilterIndicator('@sectorFilter', 'Search sectors')
    })

    it('should filter the estimated land date before', () => {
      cy.get('@estimatedDateBefore')
        .find('label')
        .should('have.text', 'Estimated land date before')
        .next()
        .click()
        .type('2020-01-01')
      assertFilterIndicator(1, 'Estimated land date before : 1 January 2020')
    })

    it('should remove the estimated land date before filter', () => {
      assertRemovedFilterIndicator('@estimatedDateBefore')
    })

    it('should filter the estimated land date after', () => {
      cy.get('@estimatedDateAfter')
        .find('label')
        .should('have.text', 'Estimated land date after')
        .next()
        .click()
        .type('2020-01-01')
      assertFilterIndicator(1, 'Estimated land date after : 1 January 2020')
    })

    it('should remove the estimated land date before filter', () => {
      assertRemovedFilterIndicator('@estimatedDateBefore')
    })
  })

  context('when the url contains state', () => {
    before(() => {
      cy.visit(urls.investments.projects.index(), {
        qs: {
          adviser: 'e83a608e-84a4-11e6-ae22-56b6b6499611',
          sector_descends: 'af959812-6095-e211-a939-e4115bead28a',
          estimated_land_date_before: '2020-01-01',
          estimated_land_date_after: '2020-01-01',
        },
      })
    })
    it('should set the selected filter values and filter indicators', () => {
      assertFilterIndicator(1, 'Puck Head')
      cy.get('@adviserTypeaheadFilter').should('contain', 'Puck Head')
      assertFilterIndicator(2, 'Advanced Engineering')
      cy.get('@sectorFilter').should('contain', 'Advanced Engineering')
      assertFilterIndicator(3, 'Estimated land date before : 1 January 2020')
      cy.get('@estimatedDateBefore')
        .find('input')
        .should('have.attr', 'value', '2020-01-01')
      assertFilterIndicator(4, 'Estimated land date after : 1 January 2020')
      cy.get('@estimatedDateAfter')
        .find('input')
        .should('have.attr', 'value', '2020-01-01')
    })

    it('should clear all filters', () => {
      cy.get('main article div + div button').as('filterIndicators')
      cy.get('@filterIndicators').should('have.length', 4)
      cy.get('main article div:first-child > button').click()
      cy.get('@filterIndicators').should('have.length', 0)
    })
  })
})

//   it('should filter by country', () => {
//     const country = selectors.filter.investments.country
//     const { typeahead } = selectors.filter

//     cy.get(typeahead(country).selectedOption)
//       .click()
//       .get(typeahead(country).textInput)
//       .type('United Kingdom')
//       .get(typeahead(country).options)
//       .should('have.length', 1)
//       .get(typeahead(country).textInput)
//       .type('{enter}')
//       .type('{esc}')

//     cy.wait('@filterResults').then((xhr) => {
//       expect(xhr.url).to.contain('country=80756b9a-5d95-e211-a939-e4115bead28a')
//     })
//   })

//   it('should filter by uk region', () => {
//     const { typeahead } = selectors.filter
//     const { ukRegion } = selectors.filter.investments
//     cy.get(typeahead(ukRegion).selectedOption)
//       .click()
//       .get(typeahead(ukRegion).textInput)
//       .type('North East')
//       .get(typeahead(ukRegion).options)
//       .should('have.length', 1)
//       .get(typeahead(ukRegion).textInput)
//       .type('{enter}')
//       .type('{esc}')

//     cy.wait('@filterResults').then((xhr) => {
//       expect(xhr.url).to.contain(
//         'uk_region_location=814cd12a-6095-e211-a939-e4115bead28a'
//       )
//     })

//     cy.get(selectors.entityCollection.entities)
//       .children()
//       .should('have.length', 2)
//   })
// })
<commit_msg>Replace strings with constants<commit_after>import urls from '../../../../../src/lib/urls'

const ADVISER_ID = 'e83a608e-84a4-11e6-ae22-56b6b6499611'
const SECTOR_ID = 'af959812-6095-e211-a939-e4115bead28a'

const selectAdvisersTypeahead = (fieldName, input) =>
  cy.get(fieldName).within(() => {
    cy.server()
    cy.route('/api-proxy/adviser/?*').as('adviserResults')
    cy.get('div').eq(0).type(input)
    cy.wait('@adviserResults')
    cy.get('[class*="menu"] > div').click()
  })

const assertTypehead = (element, label, placeholder, input, selectedOption) => {
  cy.get(element)
    .find('label')
    .should('have.text', label)
    .next()
    .should('contain', placeholder)
    .find('div')
    .eq(0)
    .type(input)
  cy.get(element).find('[class*="menu"] > div').click()
  cy.get(element).click()
  cy.get(element).should('contain', selectedOption)
}

const assertFilterIndicator = (count, label) => {
  cy.get(`main article div + div button:nth-child(${count})`).should((el) => {
    expect(el.text()).to.contain(label)
  })
}

const assertRemovedFilterIndicator = (element, placeholder = null) => {
  cy.get('main article div + div button').click()
  cy.get('main article div + div').should('be.empty')
  placeholder && cy.get(element).should('contain', placeholder)
}

describe('Investments Collections Filter', () => {
  beforeEach(() => {
    cy.get('aside button')
      .next()
      .find('#field-advisers')
      .as('adviserTypeaheadFilter')
      .next()
      .as('sectorFilter')
      .next()
      .as('estimatedDateBefore')
      .next()
      .as('estimatedDateAfter')
  })
  context('when the url contains no state', () => {
    before(() => {
      cy.visit(urls.investments.projects.index())
    })

    it('should filter by advisers', () => {
      cy.get('@adviserTypeaheadFilter')
        .should('contain', 'Search advisers')
        .find('label')
        .should('have.text', 'Advisers')

      selectAdvisersTypeahead('@adviserTypeaheadFilter', 'puc')
      cy.get('@adviserTypeaheadFilter').should('contain', 'Puck Head')
      assertFilterIndicator(1, 'Puck Head')
    })

    it('should remove the advisers filter', () => {
      assertRemovedFilterIndicator('@adviserTypeaheadFilter', 'Search advisers')
    })

    it('should filter by sector', () => {
      assertTypehead(
        '@sectorFilter',
        'Sector',
        'Search sectors',
        'adv',
        'Advanced Engineering'
      )
    })
    it('should remove the sector filter', () => {
      assertRemovedFilterIndicator('@sectorFilter', 'Search sectors')
    })

    it('should filter the estimated land date before', () => {
      cy.get('@estimatedDateBefore')
        .find('label')
        .should('have.text', 'Estimated land date before')
        .next()
        .click()
        .type('2020-01-01')
      assertFilterIndicator(1, 'Estimated land date before : 1 January 2020')
    })

    it('should remove the estimated land date before filter', () => {
      assertRemovedFilterIndicator('@estimatedDateBefore')
    })

    it('should filter the estimated land date after', () => {
      cy.get('@estimatedDateAfter')
        .find('label')
        .should('have.text', 'Estimated land date after')
        .next()
        .click()
        .type('2020-01-01')
      assertFilterIndicator(1, 'Estimated land date after : 1 January 2020')
    })

    it('should remove the estimated land date before filter', () => {
      assertRemovedFilterIndicator('@estimatedDateBefore')
    })
  })

  context('when the url contains state', () => {
    before(() => {
      cy.visit(urls.investments.projects.index(), {
        qs: {
          adviser: ADVISER_ID,
          sector_descends: SECTOR_ID,
          estimated_land_date_before: '2020-01-01',
          estimated_land_date_after: '2020-01-01',
        },
      })
    })
    it('should set the selected filter values and filter indicators', () => {
      assertFilterIndicator(1, 'Puck Head')
      cy.get('@adviserTypeaheadFilter').should('contain', 'Puck Head')
      assertFilterIndicator(2, 'Advanced Engineering')
      cy.get('@sectorFilter').should('contain', 'Advanced Engineering')
      assertFilterIndicator(3, 'Estimated land date before : 1 January 2020')
      cy.get('@estimatedDateBefore')
        .find('input')
        .should('have.attr', 'value', '2020-01-01')
      assertFilterIndicator(4, 'Estimated land date after : 1 January 2020')
      cy.get('@estimatedDateAfter')
        .find('input')
        .should('have.attr', 'value', '2020-01-01')
    })

    it('should clear all filters', () => {
      cy.get('main article div + div button').as('filterIndicators')
      cy.get('@filterIndicators').should('have.length', 4)
      cy.get('main article div:first-child > button').click()
      cy.get('@filterIndicators').should('have.length', 0)
    })
  })
})

//   it('should filter by country', () => {
//     const country = selectors.filter.investments.country
//     const { typeahead } = selectors.filter

//     cy.get(typeahead(country).selectedOption)
//       .click()
//       .get(typeahead(country).textInput)
//       .type('United Kingdom')
//       .get(typeahead(country).options)
//       .should('have.length', 1)
//       .get(typeahead(country).textInput)
//       .type('{enter}')
//       .type('{esc}')

//     cy.wait('@filterResults').then((xhr) => {
//       expect(xhr.url).to.contain('country=80756b9a-5d95-e211-a939-e4115bead28a')
//     })
//   })

//   it('should filter by uk region', () => {
//     const { typeahead } = selectors.filter
//     const { ukRegion } = selectors.filter.investments
//     cy.get(typeahead(ukRegion).selectedOption)
//       .click()
//       .get(typeahead(ukRegion).textInput)
//       .type('North East')
//       .get(typeahead(ukRegion).options)
//       .should('have.length', 1)
//       .get(typeahead(ukRegion).textInput)
//       .type('{enter}')
//       .type('{esc}')

//     cy.wait('@filterResults').then((xhr) => {
//       expect(xhr.url).to.contain(
//         'uk_region_location=814cd12a-6095-e211-a939-e4115bead28a'
//       )
//     })

//     cy.get(selectors.entityCollection.entities)
//       .children()
//       .should('have.length', 2)
//   })
// })
<|endoftext|>


<commit_before>(function () {
    'use strict';
    angular
        .module(HygieiaConfig.module)
        .controller('subnetController', SubnetController);

    SubnetController.$inject = ['$scope', 'cloudData', '$http', '$modal'];

    function SubnetController($scope, cloudData, $http, $modal) {

        var ctrl = this;
        $scope.vpcs = [];

        ctrl.accountNumber = $scope.widgetConfig.options.accountNumber || "";

        $scope.ipUtilizations;

       $scope.ipUtilizationsOptions = {
            horizontalBars: true,
            stackBars: true,

            axisY: {
    offset: 100
  },
  axisX: {
    offset:20,
     labelInterpolationFnc: function(value, index) {
      return index % 2 === 0 ? value : null;
    }
  }

        };

        $scope.ipUtilizationsEvents = {

  draw: function (data) {

if (data.type === 'bar') {
  var strokeColor = '##05ac45';

  if (data.meta == 'high') {
        strokeColor = '#d8514d'
  } else if (data.meta == 'med') {
      strokeColor = '#ffbd35'
  }
    data.element.attr({
      style: 'stroke-width: 20px; stroke: ' + strokeColor + ';'
    });
  }

  if (data.type === 'label') {
    data.valueOf;
    data.element.attr({
     // onclick: "angular.element(document.getElementById('iptutildiv')).scope().viewSubnetUtilization2(this.innerHTML)",
      class: 'clickable'
    });  }

  }

      }

        ctrl.calculatePercentage = function(count, total) {
          var percentage = count / total * 100;
          return Math.round(percentage);
        }

        $scope.totalAvailable = 0;
        $scope.totalUsed = 0;

        $scope.getIpUtilizations = function() {
            $scope.getSubnets
            var vpcData = {labels:[], series:[[], [], []]};
            angular.forEach($scope.vpcs, function(vpc) {

              var angularModalPopUpCall = "angular.element(document.getElementById('iptutildiv')).scope().viewSubnetUtilization('" + vpc.id + "')";

              var clickableLabel = '
' + vpc.id + '
';

              vpcData.labels.push(clickableLabel);
              var countOfSubnetsByUtilization = vpc.countOfSubnetsByUtilization;
              var totalSubnets = countOfSubnetsByUtilization.high + countOfSubnetsByUtilization.med + countOfSubnetsByUtilization.low;

              vpcData.series[0].push({ meta: 'low', value:ctrl.calculatePercentage(countOfSubnetsByUtilization.low, totalSubnets)});
              vpcData.series[1].push({ meta: 'med', value:ctrl.calculatePercentage(countOfSubnetsByUtilization.med, totalSubnets)});
              vpcData.series[2].push({ meta: 'high', value:ctrl.calculatePercentage(countOfSubnetsByUtilization.high, totalSubnets)});

              $scope.totalAvailable += vpc.ips.totalAvailable;
              $scope.totalUsed += vpc.ips.totalUsed ;

            });

            $scope.ipUtilizations = vpcData;
            $scope.totalIPs = $scope.totalAvailable + $scope.totalUsed;
            $scope.avgUtilization = ctrl.calculatePercentage($scope.totalUsed, $scope.totalIPs);

        }

        $scope.getSubnets = function() {

            cloudData.getAWSSubnetsByAccount(ctrl.accountNumber)
                .then(function(subnets){
                    $scope.vpcs = ctrl.groupByVpc(subnets);
                    $scope.getIpUtilizations();
                    console.log($scope.vpcs)
            });
        };

$scope.getHeight = function() {

    return $scope.vpcs.length * 30;
}
        $scope.viewSubnetUtilization = function(vpcId) {

            var vpc = {};

            angular.forEach($scope.vpcs, function(item) {
              if (item.id.toUpperCase() == vpcId.toUpperCase()) {
                  vpc = item;
              }
            });

            $modal.open({
                controller: 'SubnetUtilizationController',
                controllerAs: 'subnetUtilization',
                templateUrl: 'components/widgets/cloud/subnetUtilization.html',
                size: 'lg',
                resolve: {
                  vpc: function() {
                    return vpc;
                  }
                },
                windowTopClass: 'windowTopClass'

            });
        };

        ctrl.calculateUtilization = function(subnet) {
            return subnet.usedIPCount/(subnet.usedIPCount + subnet.availableIPCount) * 100;
        }

        ctrl.groupByVpc = function(subnets) {
          var vpcMap = {};
          var vpcs = []
          angular.forEach(subnets, function(subnet) {
            if (!vpcMap[subnet.virtualNetworkId]) {
              var vpc = {};
              vpc.id = subnet.virtualNetworkId;
              vpc.subnets = [];
              vpc.ips = {totalAvailable:0, totalUsed: 0};
              vpc.countOfSubnetsByUtilization = {};
              vpc.countOfSubnetsByUtilization.high = 0;
              vpc.countOfSubnetsByUtilization.med = 0;
              vpc.countOfSubnetsByUtilization.low = 0;
              vpcs.push(vpc);
              vpcMap[subnet.virtualNetworkId] = vpc;
            };

            vpcMap[subnet.virtualNetworkId].subnets.push(subnet);
            var utilization = ctrl.calculateUtilization(subnet);
            if (utilization > 70) {
              vpcMap[subnet.virtualNetworkId].countOfSubnetsByUtilization.high+=1;
            } else if (utilization <= 70 && utilization > 50) {
                vpcMap[subnet.virtualNetworkId].countOfSubnetsByUtilization.med+=1;
            } else {
                vpcMap[subnet.virtualNetworkId].countOfSubnetsByUtilization.low+=1;
            }

            vpcMap[subnet.virtualNetworkId].ips.totalAvailable += subnet.availableIPCount;
            vpcMap[subnet.virtualNetworkId].ips.totalUsed += subnet.usedIPCount;

          });
          return vpcs;
        };

    }

})();
<commit_msg>remove unused line<commit_after>(function () {
    'use strict';
    angular
        .module(HygieiaConfig.module)
        .controller('subnetController', SubnetController);

    SubnetController.$inject = ['$scope', 'cloudData', '$http', '$modal', '$compile'];

    function SubnetController($scope, cloudData, $http, $modal, $compile) {

        var ctrl = this;
        $scope.vpcs = [];

        ctrl.accountNumber = $scope.widgetConfig.options.accountNumber || "";

        $scope.ipUtilizations;

       $scope.ipUtilizationsOptions = {
            horizontalBars: true,
            stackBars: true,

            axisY: {
    offset: 100
  },
  axisX: {
    offset:20,
     labelInterpolationFnc: function(value, index) {
      return index % 2 === 0 ? value : null;
    }
  }

        };

        $scope.ipUtilizationsEvents = {

  draw: function (data) {

if (data.type === 'bar') {
  var strokeColor = '##05ac45';

  if (data.meta == 'high') {
        strokeColor = '#d8514d'
  } else if (data.meta == 'med') {
      strokeColor = '#ffbd35'
  }
    data.element.attr({
      style: 'stroke-width: 20px; stroke: ' + strokeColor + ';'
    });
  }

  if (data.type === 'label') {
    //var compiledHtml = $compile(strElm);
    //element.append(compiledHtml);
    data.valueOf;
    data.element.attr({
     // onclick: "angular.element(document.getElementById('iptutildiv')).scope().viewSubnetUtilization2(this.innerHTML)",
      class: 'clickable'
    });  }

  }

      }

        ctrl.calculatePercentage = function(count, total) {
          var percentage = count / total * 100;
          return Math.round(percentage);
        }

        $scope.totalAvailable = 0;
        $scope.totalUsed = 0;

        $scope.getIpUtilizations = function() {
            $scope.getSubnets
            var vpcData = {labels:[], series:[[], [], []]};
            angular.forEach($scope.vpcs, function(vpc) {

              var angularModalPopUpCall = "angular.element(document.getElementById('iptutildiv')).scope().viewSubnetUtilization('" + vpc.id + "')";

              var clickableLabel = '
' + vpc.id + '
';

              vpcData.labels.push(clickableLabel);
              var countOfSubnetsByUtilization = vpc.countOfSubnetsByUtilization;
              var totalSubnets = countOfSubnetsByUtilization.high + countOfSubnetsByUtilization.med + countOfSubnetsByUtilization.low;

              vpcData.series[0].push({ meta: 'low', value:ctrl.calculatePercentage(countOfSubnetsByUtilization.low, totalSubnets)});
              vpcData.series[1].push({ meta: 'med', value:ctrl.calculatePercentage(countOfSubnetsByUtilization.med, totalSubnets)});
              vpcData.series[2].push({ meta: 'high', value:ctrl.calculatePercentage(countOfSubnetsByUtilization.high, totalSubnets)});

              $scope.totalAvailable += vpc.ips.totalAvailable;
              $scope.totalUsed += vpc.ips.totalUsed ;

            });

            $scope.ipUtilizations = vpcData;
            $scope.totalIPs = $scope.totalAvailable + $scope.totalUsed;
            $scope.avgUtilization = ctrl.calculatePercentage($scope.totalUsed, $scope.totalIPs);

        }

        $scope.getSubnets = function() {

            cloudData.getAWSSubnetsByAccount(ctrl.accountNumber)
                .then(function(subnets){
                    $scope.vpcs = ctrl.groupByVpc(subnets);
                    $scope.getIpUtilizations();
                    console.log($scope.vpcs)
            });
        };

$scope.getHeight = function() {

    return $scope.vpcs.length * 30;
}
        $scope.viewSubnetUtilization = function(vpcId) {

            var vpc = {};

            angular.forEach($scope.vpcs, function(item) {
              if (item.id.toUpperCase() == vpcId.toUpperCase()) {
                  vpc = item;
              }
            });

            $modal.open({
                controller: 'SubnetUtilizationController',
                controllerAs: 'subnetUtilization',
                templateUrl: 'components/widgets/cloud/subnetUtilization.html',
                size: 'lg',
                resolve: {
                  vpc: function() {
                    return vpc;
                  }
                },

            });
        };

        ctrl.calculateUtilization = function(subnet) {
            return subnet.usedIPCount/(subnet.usedIPCount + subnet.availableIPCount) * 100;
        }

        ctrl.groupByVpc = function(subnets) {
          var vpcMap = {};
          var vpcs = []
          angular.forEach(subnets, function(subnet) {
            if (!vpcMap[subnet.virtualNetworkId]) {
              var vpc = {};
              vpc.id = subnet.virtualNetworkId;
              vpc.subnets = [];
              vpc.ips = {totalAvailable:0, totalUsed: 0};
              vpc.countOfSubnetsByUtilization = {};
              vpc.countOfSubnetsByUtilization.high = 0;
              vpc.countOfSubnetsByUtilization.med = 0;
              vpc.countOfSubnetsByUtilization.low = 0;
              vpcs.push(vpc);
              vpcMap[subnet.virtualNetworkId] = vpc;
            };

            vpcMap[subnet.virtualNetworkId].subnets.push(subnet);
            var utilization = ctrl.calculateUtilization(subnet);
            if (utilization > 70) {
              vpcMap[subnet.virtualNetworkId].countOfSubnetsByUtilization.high+=1;
            } else if (utilization <= 70 && utilization > 50) {
                vpcMap[subnet.virtualNetworkId].countOfSubnetsByUtilization.med+=1;
            } else {
                vpcMap[subnet.virtualNetworkId].countOfSubnetsByUtilization.low+=1;
            }

            vpcMap[subnet.virtualNetworkId].ips.totalAvailable += subnet.availableIPCount;
            vpcMap[subnet.virtualNetworkId].ips.totalUsed += subnet.usedIPCount;

          });
          return vpcs;
        };

    }

})();<|endoftext|>


<commit_before>$(document).ready(function() {
    var socket = io();

    function getMessageValue(){
        return $('.messageTextInput').val();
    }

    $('.sendButton').click(function() {
        socket.emit('sendMessage', getMessageValue());
    });

    $('.messageTextInput').keyup(function(event){
        if(event.keyCode == 13){
            $('.sendButton').click();
        }
    });
});
<commit_msg>added updateChat<commit_after>$(document).ready(function() {
    var socket = io();
    socket.on('updateChat', function(username, message) {
        $('.chatWindow').append("<p> username: " + username +
            "Message: " + message + "</p>" );
        console.log('I have recieved the update event');
    });

    function getMessageValue(){
        return $('.messageTextInput').val();
    }

    $('.sendButton').click(function() {
        socket.emit('sendMessage', getMessageValue());
    });

    $('.messageTextInput').keyup(function(event){
        if(event.keyCode == 13){
            $('.sendButton').click();
        }
    });
});
<|endoftext|>