<commit_before>    var customIcons = {
        building: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/building_icon.png'
        },
        student_centre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/student_centre_icon.png'
        },
        lecture_theatre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/lecture_theatre_icon.png'
        },
        computer_lab: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/computer_lab_icon.png'
        },
        library: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/library_icon.png'
        },
        cycle_hire: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_hire_icon.png'
        },
        cycle_parking: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_parking_icon.png'
        },
        atm: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/atm_icon.png'
        }
    };

    var markerGroups = {
        "building": [],
        "student_centre": [],
        "lecture_theatre": [],
        "computer_lab": [],
        "library": [],
        "cycle_hire": [],
        "cycle_parking": [],
        "atm": []
    };

    // Add a Home control that returns the user to London
    function showCurrentLocation(currentLocationDiv, map) {
        currentLocationDiv.style.padding = '5px';
        var currentLocationUI = document.createElement('div');
        currentLocationUI.style.backgroundColor = 'white';
        currentLocationUI.style.border = '1px solid gray';
        currentLocationUI.style.cursor = 'pointer';
        currentLocationUI.style.textAlign = 'center';
        currentLocationUI.title = 'Current location';
        currentLocationDiv.appendChild(controlUI);
        var currentLocationText = document.createElement('div');
        currentLocationText.style.fontFamily = 'Arial,sans-serif';
        currentLocationText.style.fontSize = '12px';
        currentLocationText.style.paddingLeft = '4px';
        currentLocationText.style.paddingRight = '4px';
        currentLocationText.innerHTML = 'Current location';
        currentLocationUI.appendChild(currentLocationText);

        google.maps.event.addDomListener(currentLocationUI, 'click', function () {

        });
    }

    function loadMap() {
    var map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(51.527287, -0.103842),
        zoom: 15,
        mapTypeId: 'roadmap'
    });

    var currentLocationDiv = document.createElement('div');
    var showCurrentLocation = new showCurrentLocation(currentLocationDiv, map);
    map.controls[google.maps.ControlPosition.TOP_RIGHT].push(currentLocationUI);

    downloadUrl("../../includes/university-map/source/overview_source.php", function(data) {
    var xml = data.responseXML;
    var markers = xml.documentElement.getElementsByTagName("marker");
    for (var i = 0; i < markers.length; i++) {
        var name = markers[i].getAttribute("name");
        var notes = markers[i].getAttribute("notes");
        var category = markers[i].getAttribute("category");
        var point = new google.maps.LatLng(
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, notes, category, map);
    }
    });
    }

    var infoWindow = new google.maps.InfoWindow({
        maxWidth: 400
    });

    function createMarker(point, name, notes, category, map) {
        var icon = customIcons[category] || {};
        var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon.icon,
            type: category
        });
        if (!markerGroups[category]) markerGroups[category] = [];
        markerGroups[category].push(marker);
        var html = "" + name + "
" + notes;
        bindInfoWindow(marker, map, infoWindow, html);
        return marker;
    }

    function toggleGroup(category) {
        for (var i = 0; i < markerGroups[category].length; i++) {
            var marker = markerGroups[category][i];
            if (!marker.getVisible()) {
                marker.setVisible(true);
            } else {
                marker.setVisible(false);
            }
        }
    }

    function bindInfoWindow(marker, map, infoWindow, html) {
        google.maps.event.addListener(marker, 'click', function() {
            infoWindow.setContent(html);
            infoWindow.open(map, marker);

        });
    }

    function downloadUrl(url, callback) {
        var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();

        request.onreadystatechange = function() {
            if (request.readyState == 4) {
                request.onreadystatechange = doNothing;
                callback(request, request.status);
            }
        };

        request.open('GET', url, true);
        request.send(null);
    }

    function doNothing() {}
<commit_msg>Changed structure<commit_after>    var customIcons = {
        building: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/building_icon.png'
        },
        student_centre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/student_centre_icon.png'
        },
        lecture_theatre: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/lecture_theatre_icon.png'
        },
        computer_lab: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/computer_lab_icon.png'
        },
        library: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/library_icon.png'
        },
        cycle_hire: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_hire_icon.png'
        },
        cycle_parking: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/cycle_parking_icon.png'
        },
        atm: {
            icon: 'https://student-portal.co.uk/assets/img/university-map/atm_icon.png'
        }
    };

    var markerGroups = {
        "building": [],
        "student_centre": [],
        "lecture_theatre": [],
        "computer_lab": [],
        "library": [],
        "cycle_hire": [],
        "cycle_parking": [],
        "atm": []
    };

    // Add a Home control that returns the user to London
    function showCurrentLocation(currentLocationDiv, map) {
        currentLocationDiv.style.padding = '5px';
        var currentLocationUI = document.createElement('div');
        currentLocationUI.style.backgroundColor = 'white';
        currentLocationUI.style.border = '1px solid gray';
        currentLocationUI.style.cursor = 'pointer';
        currentLocationUI.style.textAlign = 'center';
        currentLocationUI.title = 'Current location';
        currentLocationDiv.appendChild(controlUI);
        var currentLocationText = document.createElement('div');
        currentLocationText.style.fontFamily = 'Arial,sans-serif';
        currentLocationText.style.fontSize = '12px';
        currentLocationText.style.paddingLeft = '4px';
        currentLocationText.style.paddingRight = '4px';
        currentLocationText.innerHTML = 'Current location';
        currentLocationUI.appendChild(currentLocationText);

        google.maps.event.addDomListener(currentLocationUI, 'click', function () {

        });
    }

    function loadMap() {
    var map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(51.527287, -0.103842),
        zoom: 15,
        mapTypeId: 'roadmap'
    });

    var currentLocationDiv = document.createElement('div');
    var showCurrentLocation = new showCurrentLocation(currentLocationDiv, map);
    map.controls[google.maps.ControlPosition.TOP_RIGHT].push(currentLocationDiv);

    downloadUrl("../../includes/university-map/source/overview_source.php", function(data) {
    var xml = data.responseXML;
    var markers = xml.documentElement.getElementsByTagName("marker");
    for (var i = 0; i < markers.length; i++) {
        var name = markers[i].getAttribute("name");
        var notes = markers[i].getAttribute("notes");
        var category = markers[i].getAttribute("category");
        var point = new google.maps.LatLng(
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng")));
        var marker = createMarker(point, name, notes, category, map);
    }
    });
    }

    var infoWindow = new google.maps.InfoWindow({
        maxWidth: 400
    });

    function createMarker(point, name, notes, category, map) {
        var icon = customIcons[category] || {};
        var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon.icon,
            type: category
        });
        if (!markerGroups[category]) markerGroups[category] = [];
        markerGroups[category].push(marker);
        var html = "" + name + "
" + notes;
        bindInfoWindow(marker, map, infoWindow, html);
        return marker;
    }

    function toggleGroup(category) {
        for (var i = 0; i < markerGroups[category].length; i++) {
            var marker = markerGroups[category][i];
            if (!marker.getVisible()) {
                marker.setVisible(true);
            } else {
                marker.setVisible(false);
            }
        }
    }

    function bindInfoWindow(marker, map, infoWindow, html) {
        google.maps.event.addListener(marker, 'click', function() {
            infoWindow.setContent(html);
            infoWindow.open(map, marker);

        });
    }

    function downloadUrl(url, callback) {
        var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();

        request.onreadystatechange = function() {
            if (request.readyState == 4) {
                request.onreadystatechange = doNothing;
                callback(request, request.status);
            }
        };

        request.open('GET', url, true);
        request.send(null);
    }

    function doNothing() {}
<|endoftext|>


<commit_before>sharksDB.Views.CentralPanel = Backbone.View.extend({
		el : '#centralPanel',

		initialize: function (options) {
			this.options = options || {};
			this.listenTo(this.model, 'change', this.render);
		},

		events : {
			"click td.doclink":"updateCurrentState"
		},

		countryTemplate : _.template($('#countrySelectedDocuments').html()),
		speciesTemplate : _.template($('#speciesSelectedDocuments').html()),
		rfmoTemplate : _.template($('#rfmoSelectedDocuments').html()),

		render : function () {
			this.$el.hide();
			$('#displayTitle').html(''); /* clear title */
			$('#map').hide();
			if (this.model.get('country')!='') {
				var country = this.model.get('country');
				var countriesModel = sharksDB.Collections.countriesCollection.get(country);
				var targetView = this;
				if (countriesModel.get('completed') == false) { /* we have to fetch the data*/
					countriesModel.url =  'http://figisapps.fao.org/figis/sharks/rest/countries'+'/'+country;
					countriesModel.fetch({
						success : function () {
							countriesModel.set('completed', true);
							$('#displayTitle').html(countriesModel.get('name'));
							targetView.$el.html(targetView.countryTemplate({poasArray: countriesModel.get('poas').sort(poayearSort), othersArray: countriesModel.get('others').sort(yearSort)}));
							sharksDB.Models.currentState.trigger("modelUpdated");
						}
					});
				} else {
					$('#displayTitle').html(countriesModel.get('name'));
					this.$el.html(this.countryTemplate({dataArray: countriesModel.get('poas').sort(poayearSort)}));
				}

				this.$el.show();
			}

			if (this.model.get('species')!='') {
				var species = this.model.get('species');
				if (!isNaN(+species)) { /* this is a species group, data has already been fetched at loading, just display the table */
					$('#displayTitle').html(sharksDB.Collections.speciesGroupsCollection.get(species).get('name'));
					this.$el.html(this.speciesTemplate({dataArray: sharksDB.Collections.speciesGroupsCollection.get(species).get('measures').sort(yearSort)}));
					this.$el.show();
				} else { /* this is not a species group : fetch the complete information about it if needed */
					var speciesModel = sharksDB.Collections.speciesCollection.get(species);
					$('#displayTitle').html(speciesModel.get('englishName'));
					if (speciesModel.get('completed') == false) { /* we have to fetch the data*/
						speciesModel.url =  'http://figisapps.fao.org/figis/sharks/rest/species'+'/'+species;
						speciesModel.fetch({
							success : function () {
								speciesModel.set('completed', true);
								$('#centralPanel').html(sharksDB.Views.CentralPanel.prototype.speciesTemplate({dataArray: speciesModel.get('measures').sort(yearSort)}));
								sharksDB.Models.currentState.trigger("modelUpdated");
							}
						});
					} else {
						this.$el.html(this.speciesTemplate({dataArray: speciesModel.get('measures').sort(yearSort)}));
					}

					$('#map').show();
					this.$el.show(); /* display the map div before loading the map to get correct dimension */

					/* load map from mapbox if needed */
					if (sharksDB.Map.map == undefined) {
						setBackgroundMap();
					} else { /* map was already loaded, we must clean zone layer before adding new one */
						sharksDB.Map.map.removeLayer(sharksDB.Map.maritimeZoneLayer); /* remove the wms tile of rfmo competence zone */
						d3.select("#layerCountries").selectAll("g").remove(); /* remove all highlighted countries if needed */
					}
					sharksDB.Map.map.setView([25,0], 2);

					/* get the distribution area from FAO server */
					sharksDB.Map.maritimeZoneLayer = L.tileLayer.wms('http://www.fao.org/figis/geoserver/wms', {
						dpiMode: 7,
						layers: 'fifao:SPECIES_DIST',
						cql_filter: "ALPHACODE='"+species+"'",
						featureCount: 10,
						format: 'image/png',
						transparent: true,
						zIndex: 1
					}).setOpacity(0.85)
					.addTo(sharksDB.Map.map);
				}

							}
			if (this.model.get('rfmo')!='') {
				var rfmo = this.model.get('rfmo');
				var entitiesModel = sharksDB.Collections.entitiesCollection.get(rfmo);
				var targetView = this;
				if (entitiesModel.get('completed') == false) { /* we have to fetch the data*/
					entitiesModel.url =  'http://figisapps.fao.org/figis/sharks/rest/managemententities'+'/'+rfmo;
					entitiesModel.fetch({
						success : function () {
							entitiesModel.set('completed', true);
							$('#displayTitle').html(""+entitiesModel.get('name')+"");
							targetView.$el.html(targetView.rfmoTemplate({dataArray: entitiesModel.get('measures').sort(yearSort)}));
							sharksDB.Models.currentState.trigger("modelUpdated");
							renderCountriesOnRFMOMap(entitiesModel.get('members'));
						}
					});
				} else {
					$('#displayTitle').html(""+entitiesModel.get('name')+"");
					this.$el.html(this.rfmoTemplate({dataArray: entitiesModel.get('measures').sort(yearSort)}));
					renderCountriesOnRFMOMap(entitiesModel.get('members'));
				}

				/* render rfmo map */
				$('#map').show();
				this.$el.show(); /* display the map div before loading the map to get correct dimension */

				/* load map from mapbox if needed */
				if (sharksDB.Map.map == undefined) {
					setBackgroundMap();
				} else { /* map was already loaded, we must clean zone layers before adding new one */
					sharksDB.Map.map.removeLayer(sharksDB.Map.maritimeZoneLayer); /* remove the wms tile of rfmo competence zone */
				}

				//sharksDB.Map.map.setView(sharksDB.Collections.RFMOInfoList[rfmo].map, 2); TODO: get the zoom from a geaFeature call
				sharksDB.Map.map.setView([0, 25], 2);

				/* add the competence area from FAO server */
				sharksDB.Map.maritimeZoneLayer = L.tileLayer.wms('http://www.fao.org/figis/geoserver/wms', {
							dpiMode: 7,
							layers: 'rfb:RFB_'+rfmo,
							featureCount: 10,
							format: 'image/png',
							transparent: true,
							zIndex: 1
						})
						.setOpacity(0.15)
						.addTo(sharksDB.Map.map);
			}
			return this;
		},

		updateCurrentState : function (e) {
			this.model.set({country: ('country' in e.target.dataset)?e.target.dataset.country:'',
					rfmo: ('rfmo' in e.target.dataset)?e.target.dataset.rfmo:'',
					species: ('species' in e.target.dataset)?e.target.dataset.species:''});
		}
});

/* sort by most recent to less recent and alphabetical order of title for same year docs */
function yearSort(a,b) {
	 if (+a.year>+b.year) return -1;
	 if (+a.year<+b.year) return 1;
	 if (a.title>b.title) return 1;
	 return -1;
}
function poayearSort(a,b) {
	 if (+a.poAYear>+b.poAYear) return -1;
	 if (+a.poAYear<+b.poAYear) return 1;
	 if (a.title>b.title) return 1;
	 return -1;
}

/* Load background map and 200nm limit WMS layer from FAO server */
function setBackgroundMap() {
	sharksDB.Map.map = L.mapbox.map('map', 'jeannotlapin.lcld15nl', {worldCopyJump: false}).setView([0,0], 2);

	/* initialise svg layer */
	sharksDB.Map.map._initPathRoot();
	var svg = d3.select("#map").select("svg"),
	    g = svg.append("g").attr("id", "layerCountries");
	g.classed('countryHigh', true); /* set class to layerCountries g element */

	/* add the 200nm limit from FAO server */
	var nm200Layer = L.tileLayer.wms('http://www.fao.org/figis/geoserver/wms', {
			dpiMode: 7,
			layers: 'fifao:limit_200nm',
			featureCount: 10,
			format: 'image/png',
			transparent: true,
			zIndex: 5
		})
		.setOpacity(0.20)
		.addTo(sharksDB.Map.map);
}

/* render countries on the RFMO maps, is out of the render function because must wait for the asynchronous fetch of entity data */
function renderCountriesOnRFMOMap(modelMembers) {
	/* add countries highlighting layer using d3 */
	var entityCountryList = []; /* get all member iso_a3 code in an array */
	modelMembers.forEach(function(d){
		entityCountryList.push(d.code);
	});

	d3.json("data/geodata/countries110.json", function(collection) {
		var transform = d3.geo.transform({point: projectPoint}),
		path = d3.geo.path().projection(transform);
		var transform2 = d3.geo.transform({point: projectPoint2}),
		path2 = d3.geo.path().projection(transform2);

		var selectedCountries = d3.select("#layerCountries").selectAll("g")
			.data(collection.features.filter(function (d){
				/* check country */
				if ($.inArray(d.properties.iso_a3, entityCountryList) != -1) {
					return true;
				}
				return false;
			}),
			function (d){return d.properties.iso_a3});

		selectedCountries.exit().remove(); /* on selection exit remove the g element */

		var countryGroups =selectedCountries.enter() /* append a g element on enter */
			.append("g");

		var countryPathsWorld1 = countryGroups.append("path"); /* on enter: append 2 path elements in each g one : duplicate the world at +360 */
		var countryPathsWorld2 = countryGroups.append("path");

		sharksDB.Map.map.on("viewreset", reset);

		/* Draw the SVG paths for countries. */
		function reset() {
			countryPathsWorld1.attr("d", path); /* on current world [-180,180]*/
			countryPathsWorld2.attr("d", path2); /* on another world [180, 540]*/
			sharksDB.Map.map._updateSvgViewport(); /* make sure we update correctly svg layer translate attribute */
		}

		/* Use Leaflet to implement a D3 geometric transformation */
		function projectPoint(x, y) {
			var point = sharksDB.Map.map.latLngToLayerPoint(new L.LatLng(y, x));
			this.stream.point(point.x, point.y);
		}
		function projectPoint2(x, y) {
			var point2 = sharksDB.Map.map.latLngToLayerPoint(new L.LatLng(y, x+360)); /* project on a world translated by 360° */
			this.stream.point(point2.x, point2.y);
		}

		reset();
	});
}
<commit_msg>Use the hasDistributionMap field to display or not the map<commit_after>sharksDB.Views.CentralPanel = Backbone.View.extend({
		el : '#centralPanel',

		initialize: function (options) {
			this.options = options || {};
			this.listenTo(this.model, 'change', this.render);
		},

		events : {
			"click td.doclink":"updateCurrentState"
		},

		countryTemplate : _.template($('#countrySelectedDocuments').html()),
		speciesTemplate : _.template($('#speciesSelectedDocuments').html()),
		rfmoTemplate : _.template($('#rfmoSelectedDocuments').html()),

		render : function () {
			this.$el.hide();
			$('#displayTitle').html(''); /* clear title */
			$('#map').hide();
			if (this.model.get('country')!='') {
				var country = this.model.get('country');
				var countriesModel = sharksDB.Collections.countriesCollection.get(country);
				var targetView = this;
				if (countriesModel.get('completed') == false) { /* we have to fetch the data*/
					countriesModel.url =  'http://figisapps.fao.org/figis/sharks/rest/countries'+'/'+country;
					countriesModel.fetch({
						success : function () {
							countriesModel.set('completed', true);
							$('#displayTitle').html(countriesModel.get('name'));
							targetView.$el.html(targetView.countryTemplate({poasArray: countriesModel.get('poas').sort(poayearSort), othersArray: countriesModel.get('others').sort(yearSort)}));
							sharksDB.Models.currentState.trigger("modelUpdated");
						}
					});
				} else {
					$('#displayTitle').html(countriesModel.get('name'));
					this.$el.html(this.countryTemplate({dataArray: countriesModel.get('poas').sort(poayearSort)}));
				}

				this.$el.show();
			}

			if (this.model.get('species')!='') {
				var species = this.model.get('species');
				if (!isNaN(+species)) { /* this is a species group, data has already been fetched at loading, just display the table */
					$('#displayTitle').html(sharksDB.Collections.speciesGroupsCollection.get(species).get('name'));
					this.$el.html(this.speciesTemplate({dataArray: sharksDB.Collections.speciesGroupsCollection.get(species).get('measures').sort(yearSort)}));
					this.$el.show();
				} else { /* this is not a species group : fetch the complete information about it if needed */
					var speciesModel = sharksDB.Collections.speciesCollection.get(species);
					var targetView = this;
					$('#displayTitle').html(speciesModel.get('englishName'));
					if (speciesModel.get('completed') == false) { /* we have to fetch the data*/
						speciesModel.url =  'http://figisapps.fao.org/figis/sharks/rest/species'+'/'+species;
						speciesModel.fetch({
							success : function () {
								speciesModel.set('completed', true);
								$('#centralPanel').html(targetView.speciesTemplate({dataArray: speciesModel.get('measures').sort(yearSort)}));
								sharksDB.Models.currentState.trigger("modelUpdated");
								targetView.$el.show(); /* display the map div before loading the map to get correct dimension */
								renderSpeciesDistributionMap(speciesModel, species);
							}
						});
					} else {
						this.$el.html(this.speciesTemplate({dataArray: speciesModel.get('measures').sort(yearSort)}));
						this.$el.show(); /* display the map div before loading the map to get correct dimension */
						renderSpeciesDistributionMap(speciesModel, species);
					}

				}
			}

			if (this.model.get('rfmo')!='') {
				var rfmo = this.model.get('rfmo');
				var entitiesModel = sharksDB.Collections.entitiesCollection.get(rfmo);
				var targetView = this;
				if (entitiesModel.get('completed') == false) { /* we have to fetch the data*/
					entitiesModel.url =  'http://figisapps.fao.org/figis/sharks/rest/managemententities'+'/'+rfmo;
					entitiesModel.fetch({
						success : function () {
							entitiesModel.set('completed', true);
							$('#displayTitle').html(""+entitiesModel.get('name')+"");
							targetView.$el.html(targetView.rfmoTemplate({dataArray: entitiesModel.get('measures').sort(yearSort)}));
							sharksDB.Models.currentState.trigger("modelUpdated");
							renderCountriesOnRFMOMap(entitiesModel.get('members'));
						}
					});
				} else {
					$('#displayTitle').html(""+entitiesModel.get('name')+"");
					this.$el.html(this.rfmoTemplate({dataArray: entitiesModel.get('measures').sort(yearSort)}));
					renderCountriesOnRFMOMap(entitiesModel.get('members'));
				}

				/* render rfmo map */
				$('#map').show();
				this.$el.show(); /* display the map div before loading the map to get correct dimension */

				/* load map from mapbox if needed */
				if (sharksDB.Map.map == undefined) {
					setBackgroundMap();
				} else { /* map was already loaded, we must clean zone layers before adding new one */
					sharksDB.Map.map.removeLayer(sharksDB.Map.maritimeZoneLayer); /* remove the wms tile of rfmo competence zone */
				}

				//sharksDB.Map.map.setView(sharksDB.Collections.RFMOInfoList[rfmo].map, 2); TODO: get the zoom from a geaFeature call
				sharksDB.Map.map.setView([0, 25], 2);

				/* add the competence area from FAO server */
				sharksDB.Map.maritimeZoneLayer = L.tileLayer.wms('http://www.fao.org/figis/geoserver/wms', {
							dpiMode: 7,
							layers: 'rfb:RFB_'+rfmo,
							featureCount: 10,
							format: 'image/png',
							transparent: true,
							zIndex: 1
						})
						.setOpacity(0.15)
						.addTo(sharksDB.Map.map);
			}
			return this;
		},

		updateCurrentState : function (e) {
			this.model.set({country: ('country' in e.target.dataset)?e.target.dataset.country:'',
					rfmo: ('rfmo' in e.target.dataset)?e.target.dataset.rfmo:'',
					species: ('species' in e.target.dataset)?e.target.dataset.species:''});
		}
});

/* sort by most recent to less recent and alphabetical order of title for same year docs */
function yearSort(a,b) {
	 if (+a.year>+b.year) return -1;
	 if (+a.year<+b.year) return 1;
	 if (a.title>b.title) return 1;
	 return -1;
}
function poayearSort(a,b) {
	 if (+a.poAYear>+b.poAYear) return -1;
	 if (+a.poAYear<+b.poAYear) return 1;
	 if (a.title>b.title) return 1;
	 return -1;
}

/* Load background map and 200nm limit WMS layer from FAO server */
function setBackgroundMap() {
	sharksDB.Map.map = L.mapbox.map('map', 'jeannotlapin.lcld15nl', {worldCopyJump: false}).setView([0,0], 2);

	/* initialise svg layer */
	sharksDB.Map.map._initPathRoot();
	var svg = d3.select("#map").select("svg"),
	    g = svg.append("g").attr("id", "layerCountries");
	g.classed('countryHigh', true); /* set class to layerCountries g element */

	/* add the 200nm limit from FAO server */
	var nm200Layer = L.tileLayer.wms('http://www.fao.org/figis/geoserver/wms', {
			dpiMode: 7,
			layers: 'fifao:limit_200nm',
			featureCount: 10,
			format: 'image/png',
			transparent: true,
			zIndex: 5
		})
		.setOpacity(0.20)
		.addTo(sharksDB.Map.map);
}

/* render countries on the RFMO maps, is out of the render function because must wait for the asynchronous fetch of entity data */
function renderCountriesOnRFMOMap(modelMembers) {
	/* add countries highlighting layer using d3 */
	var entityCountryList = []; /* get all member iso_a3 code in an array */
	modelMembers.forEach(function(d){
		entityCountryList.push(d.code);
	});

	d3.json("data/geodata/countries110.json", function(collection) {
		var transform = d3.geo.transform({point: projectPoint}),
		path = d3.geo.path().projection(transform);
		var transform2 = d3.geo.transform({point: projectPoint2}),
		path2 = d3.geo.path().projection(transform2);

		var selectedCountries = d3.select("#layerCountries").selectAll("g")
			.data(collection.features.filter(function (d){
				/* check country */
				if ($.inArray(d.properties.iso_a3, entityCountryList) != -1) {
					return true;
				}
				return false;
			}),
			function (d){return d.properties.iso_a3});

		selectedCountries.exit().remove(); /* on selection exit remove the g element */

		var countryGroups =selectedCountries.enter() /* append a g element on enter */
			.append("g");

		var countryPathsWorld1 = countryGroups.append("path"); /* on enter: append 2 path elements in each g one : duplicate the world at +360 */
		var countryPathsWorld2 = countryGroups.append("path");

		sharksDB.Map.map.on("viewreset", reset);

		/* Draw the SVG paths for countries. */
		function reset() {
			countryPathsWorld1.attr("d", path); /* on current world [-180,180]*/
			countryPathsWorld2.attr("d", path2); /* on another world [180, 540]*/
			sharksDB.Map.map._updateSvgViewport(); /* make sure we update correctly svg layer translate attribute */
		}

		/* Use Leaflet to implement a D3 geometric transformation */
		function projectPoint(x, y) {
			var point = sharksDB.Map.map.latLngToLayerPoint(new L.LatLng(y, x));
			this.stream.point(point.x, point.y);
		}
		function projectPoint2(x, y) {
			var point2 = sharksDB.Map.map.latLngToLayerPoint(new L.LatLng(y, x+360)); /* project on a world translated by 360° */
			this.stream.point(point2.x, point2.y);
		}

		reset();
	});
}

function renderSpeciesDistributionMap(modelSpecies, species) {
	if (modelSpecies.get('hasDistributionMap') == true) { /* render the distribution map if there is one */
		$('#map').show();

		/* load map from mapbox if needed */
		if (sharksDB.Map.map == undefined) {
			setBackgroundMap();
		} else { /* map was already loaded, we must clean zone layer before adding new one */
			sharksDB.Map.map.removeLayer(sharksDB.Map.maritimeZoneLayer); /* remove the wms tile of rfmo competence zone */
			d3.select("#layerCountries").selectAll("g").remove(); /* remove all highlighted countries if needed */
		}
		sharksDB.Map.map.setView([25,0], 2);

		/* get the distribution area from FAO server */
		sharksDB.Map.maritimeZoneLayer = L.tileLayer.wms('http://www.fao.org/figis/geoserver/wms', {
			dpiMode: 7,
			layers: 'fifao:SPECIES_DIST',
			cql_filter: "ALPHACODE='"+species+"'",
			featureCount: 10,
			format: 'image/png',
			transparent: true,
			zIndex: 1
		}).setOpacity(0.85)
		.addTo(sharksDB.Map.map);
	}
}
<|endoftext|>


<commit_before>var GUI = (function(){ //IIFE for all Views

//=============================================
//              TABLE OF CONTENTS
//  -----------------------------------------
//  1. AddTaskView
//  2. TaskView
//  3. UnassignedTasksView
//  4. UserTasksView
//  5. UserView
//  6. LoginView
//  7. GUI
//
//=============================================

//=============================================
// 1. AddTaskView :
//      Modal view for adding a task to the model
//    Called by :
//      UnassignedTaskView
//=============================================

  var AddTaskView = Backbone.View.extend({
    className: 'modal',

    render: function(){
      var $form = $('<form>');
      var $title = $('<input type="text" name="title" id="title" placholder="task title">');
      var $description = $('<input type="text" name="description" id="description" placholder="task title">');
      var $submit = $('<button id="submit">Submit</button>');
      $form.append([$title, $description, $submit] );
      this.$el.html($form);
    },

    initialize: function(){
      $('#app').addClass('faded');
      this.render();
      $('body').append(this.$el);
    },

    events: {
      'click #submit' : 'addTask'
    },

    addTask : function(event) {
      event.preventDefault();

      var task = {
        title : this.$el.find('#title').val(),
        description : this.$el.find('#description').val(),
        creator : app.currentUser
      };

      console.log( 'add this task: ', task);

      console.log( 'app.tasks before changes: ', app.tasks );
      app.tasks.add( task );
      console.log( 'app.tasks after changes: ', app.tasks );

      $('#app').removeClass('faded');
    }
  });

//=============================================
// 2. TaskView :
//      View for an individual task
//    Called by :
//      UnassignedTaskView
//      UserTaskView
//=============================================

  var TaskView = Backbone.View.extend({
    tagName: 'p',
    className: 'task',

    render: function(){

      if (this.model.get('status') === 'completed') {
        console.log("Changing to completed");
        var stuff = '
' + this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '

';
       this.$el.html(stuff);
      }
      else if (this.model.get('assignee') === app.currentUser) {
        var description = this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '
 <button id="unclaim">Unclaim This Task</button> <button id = "completed">Complete This Task</button>';
        this.$el.html(description);
      }
      else {
       var other = '
' + this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '
 <button id="claim">Claim This Task</button>
';
      this.$el.html(other);
    }
  },
    // rerender: function() {
    //   this.remove();
    //   var description = this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '
 <button id="unclaim">Unclaim This Task</button>';
    //   this.$el.html(description);
    //
    // },

    initialize: function(options){
      this.index = options.index;
      this.render();
    },
    events: {
      'click #claim' : 'change',
      'click #unclaim' : 'changeBack',
      'click #completed' : 'complete'
    },
    change: function() {
      console.log("Claiming A Task");
      // this.model.set('assignee') = app.currentUser;
      this.model.set({'assignee' : app.currentUser});
      this.model.set({'status' : 'assigned'});
      // this.rerender();
      console.log(this.model.get('status'));
    },
    changeBack: function() {
      this.model.set({'assignee' : ''});
      this.model.set({'status' : 'unassigned'});
      console.log("Unclaiming A Task");
    },
    complete: function() {
      this.model.set({'status' : 'completed'});
    }
  });

//=============================================
// 3. UnassignedTasksView:
//      View for all unassigned
//    Called by :
//      UserView
//=============================================

  var UnassignedTasksView = Backbone.View.extend({
  	tagName: 'div',
  	className: 'UnassignedTasksView',
  	initialize: function () {
      this.listenTo(app.tasks, 'change', this.render);

  },

    render: function () {
  		var btn = '<button id="newTask">Create A New Task</button>';
  		this.$el.html('
Unassigned Tasks
'+ btn);

      for(var i = 0; i < app.tasks.length; i++){
        if(app.tasks.at(i).get('status') == 'unassigned'){
          var viewB = new TaskView({index: i, model: app.tasks.at(i)});
          this.$el.append(viewB.$el);
        }
      }
    },
    changeBack: function() {
      this.model.set({'assignee' : ''});
      this.model.set({'status' : 'unassigned'});
      console.log("Unclaiming A Task");
    },
    complete: function() {
      console.log("Task Completed");
      this.model.set({'status' : 'completed'});
      this.addDiv();
    },
    addDiv: function() {
      console.log("Adding Div");
      this.remove();
      this.initialize();
    },
    events: {
  			'click #newTask' : 'newTask'
  	},

    newTask: function () {
      var addTask = new AddTaskView();
      addTask.render();
      this.$el.append(addTask.$el);
    }
  });

//=============================================
// 4. UserTasksView :
//    View for tasks filtered by active user
//    Called by :
//      UserView
//=============================================

  var UserTasksView = Backbone.View.extend({
    tagName: 'div',
  	className: 'UserTasksView',

  	render: function () {
			// var usernames = UserModel.model.get("value");
      console.log('UserTasksView');
			var btn = '<button id="removeTask">Remove A Task</button>';
			this.$el.html('
User Tasks
' + btn);

      for(var i = 0; i < app.tasks.length; i++){
        if(app.tasks.at(i).get('assignee') == app.currentUser){
          var viewB = new TaskView({index: i, model: app.tasks.at(i)});
          this.$el.append(viewB.$el);
        }
    }

  	},
  	initialize: function () {
			this.listenTo(app.tasks, 'change', this.removeTask);
  	},
  	events : {
  		'click #removeTask' : 'removeTask'
  	},
  	removeTask: function () {
  		console.log('pushed removeTask button');
      this.render();
  	},

  });

//=============================================
// 5. UserView:
//      View for whole page after logging in
//    Called by :
//      LoginView
//=============================================

  var UserView = Backbone.View.extend({
  	render: function() {
			var logout = '<button id = "logout">Log-Out</button>';
			var header = '
Welcome, '+app.currentUser+'!
';
			var userTasksViewHeader = '
User Tasks View
';
			var userTasksView = new UserTasksView();
			userTasksView.render();
			var unassignedTasksViewHeader = '
Unassigned Tasks View
';
			var unassignedTasksView = new UnassignedTasksView();
			unassignedTasksView.render();
			var stuff = header + logout;
      this.$el.append(unassignedTasksView.$el);
      this.$el.append(userTasksView.$el);
      this.$el.prepend( stuff );
	},
  	events: {
  		"click #logout" : "logout"
  	},
  	logout: function() {
  		console.log("logging out");
  		// this.$el.empty();
      $('#app').html('');
  		app.gui.switchToLogin();
  	}
});

//=============================================
// 6. LoginView :
//      View for initial login page
//    Called by :
//      GUI
//=============================================

var LoginView = Backbone.View.extend({
	render: function() {
		var button = '<button id = "login">Login</button>';
		var users = app.users.pluck("username");
		var dropdown = '<select id = "dropdown">';
    users.forEach(function(element){dropdown += "<option>"+element+"</option>";});
		dropdown += ('</select>');
		var title = '
Please Choose A Username
';
		var all =  title + dropdown + button;
		this.$el.html(  all );
	},
	delete: function() {
			this.$el.html('');
	},
	initialize: function() {
		console.log("initializing");
		// this.on("logout", this.delete, this);

	},
	events: {
		"click #logout" : "logout",
		"click #login" : "login"
	},
	login: function() {
		app.currentUser = $('#dropdown').val();
		console.log("loging in");
    this.remove();
			app.gui.switchToUser();
	},
	logout: function() {
		console.log("logging out");
		this.$el.empty();
		this.remove();
		app.gui.switchToLogin();
	}

});

//=============================================
// 7. GUI
//    Function that builds everything at the end
//=============================================

function GUI(users,tasks,el) {
	this.switchToUser = function (){
		var userView = new UserView();
		userView.render();
		$('#app').append(userView.$el);
	};
	 this.switchToLogin = function() {
		 var login = new LoginView();
		 login.render();
		 $("#app").append(login.$el);
   };
	  var currentUser = this.currentUser;
    this.switchToLogin();
}

  return GUI;

})();
<commit_msg>destroys remove button, changes modal append, includes classnames on views<commit_after>var GUI = (function(){ //IIFE for all Views

//=============================================
//              TABLE OF CONTENTS
//  -----------------------------------------
//  1. AddTaskView
//  2. TaskView
//  3. UnassignedTasksView
//  4. UserTasksView
//  5. UserView
//  6. LoginView
//  7. GUI
//
//=============================================

//=============================================
// 1. AddTaskView :
//      Modal view for adding a task to the model
//    Called by :
//      UnassignedTaskView
//=============================================

  var AddTaskView = Backbone.View.extend({
    className: 'modal',

    render: function(){
      var $form = $('<form>');
      var $title = $('<input type="text" name="title" id="title" placeholder="task title">');
      var $description = $('<input type="text" name="description" id="description" placeholder="task description">');
      var $submit = $('<button id="submit">Submit</button>');
      $form.append([$title, $description, $submit] );
      this.$el.html($form);
    },

    initialize: function(){
      $('#app').addClass('faded');
      this.render();
      $('#app').append(this.$el);
    },

    events: {
      'click #submit' : 'addTask'
    },

    addTask : function(event) {
      event.preventDefault();

      var task = {
        title : this.$el.find('#title').val(),
        description : this.$el.find('#description').val(),
        creator : app.currentUser
      };

      app.tasks.add( task );
      $('#app').removeClass('faded');
    }
  });

//=============================================
// 2. TaskView :
//      View for an individual task
//    Called by :
//      UnassignedTaskView
//      UserTaskView
//=============================================

  var TaskView = Backbone.View.extend({
    tagName: 'p',
    className: 'task',

    render: function(){

      if (this.model.get('status') === 'completed') {
        console.log("Changing to completed");
        var stuff = '
' + this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '

';
       this.$el.html(stuff);
      }
      else if (this.model.get('assignee') === app.currentUser) {
        var description = this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '
 <button id="unclaim">Unclaim This Task</button> <button id = "completed">Complete This Task</button>';
        this.$el.html(description);
      }
      else {
       var other = '
' + this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '
 <button id="claim">Claim This Task</button>
';
      this.$el.html(other);
    }
  },
    // rerender: function() {
    //   this.remove();
    //   var description = this.model.get('title') + '
description: ' + this.model.get('description') + '
creator: ' + this.model.get('creator') + '
assigned to: ' + this.model.get('assignee') + '
status: ' + this.model.get('status') + '
 <button id="unclaim">Unclaim This Task</button>';
    //   this.$el.html(description);
    //
    // },

    initialize: function(options){
      this.index = options.index;
      this.render();
    },
    events: {
      'click #claim' : 'change',
      'click #unclaim' : 'changeBack',
      'click #completed' : 'complete'
    },
    change: function() {
      console.log("Claiming A Task");
      // this.model.set('assignee') = app.currentUser;
      this.model.set({'assignee' : app.currentUser});
      this.model.set({'status' : 'assigned'});
      // this.rerender();
      console.log(this.model.get('status'));
    },
    changeBack: function() {
      this.model.set({'assignee' : ''});
      this.model.set({'status' : 'unassigned'});
      console.log("Unclaiming A Task");
    },
    complete: function() {
      this.model.set({'status' : 'completed'});
    }
  });

//=============================================
// 3. UnassignedTasksView:
//      View for all unassigned
//    Called by :
//      UserView
//=============================================

  var UnassignedTasksView = Backbone.View.extend({
  	tagName: 'div',
  	className: 'UnassignedTasksView',
  	initialize: function () {
      this.listenTo(app.tasks, 'change', this.render);
      this.listenTo(app.tasks, 'update', this.render);

  },

    render: function () {
  		var btn = '<button id="newTask">Create A New Task</button>';
  		this.$el.html('
Unassigned Tasks
'+ btn);

      for(var i = 0; i < app.tasks.length; i++){
        if(app.tasks.at(i).get('status') == 'unassigned'){
          var viewB = new TaskView({index: i, model: app.tasks.at(i)});
          this.$el.append(viewB.$el);
        }
      }
    },
    changeBack: function() {
      this.model.set({'assignee' : ''});
      this.model.set({'status' : 'unassigned'});
      console.log("Unclaiming A Task");
    },
    complete: function() {
      console.log("Task Completed");
      this.model.set({'status' : 'completed'});
      this.addDiv();
    },
    addDiv: function() {
      console.log("Adding Div");
      this.remove();
      this.initialize();
    },
    events: {
  			'click #newTask' : 'newTask'
  	},

    newTask: function () {
      var addTask = new AddTaskView();
      addTask.render();
    }
  });

//=============================================
// 4. UserTasksView :
//    View for tasks filtered by active user
//    Called by :
//      UserView
//=============================================

  var UserTasksView = Backbone.View.extend({
    tagName: 'div',
  	className: 'UserTasksView',

  	render: function () {
			// var usernames = UserModel.model.get("value");
      console.log('UserTasksView');
			this.$el.html('
User Tasks
');

      for(var i = 0; i < app.tasks.length; i++){
        if(app.tasks.at(i).get('assignee') == app.currentUser){
          var viewB = new TaskView({index: i, model: app.tasks.at(i)});
          this.$el.append(viewB.$el);
        }
    }

  	},
  	initialize: function () {
			this.listenTo(app.tasks, 'change', this.removeTask);
  	},
  	events : {
  	},
  });

//=============================================
// 5. UserView:
//      View for whole page after logging in
//    Called by :
//      LoginView
//=============================================

  var UserView = Backbone.View.extend({
    id : 'UserView',
  	render: function() {
			var logout = '<button id = "logout">Log-Out</button>';
			var header = '
Welcome, '+app.currentUser+'!
';
			var userTasksViewHeader = '
User Tasks View
';
			var userTasksView = new UserTasksView();
			userTasksView.render();
			var unassignedTasksViewHeader = '
Unassigned Tasks View
';
			var unassignedTasksView = new UnassignedTasksView();
			unassignedTasksView.render();
			var stuff = header + logout;
      this.$el.append(unassignedTasksView.$el);
      this.$el.append(userTasksView.$el);
      this.$el.prepend( stuff );
	},
  	events: {
  		"click #logout" : "logout"
  	},
  	logout: function() {
  		console.log("logging out");
  		// this.$el.empty();
      $('#app').html('');
  		app.gui.switchToLogin();
  	}
});

//=============================================
// 6. LoginView :
//      View for initial login page
//    Called by :
//      GUI
//=============================================

var LoginView = Backbone.View.extend({
  id : 'LoginView',
	render: function() {
		var button = '<button id = "login">Login</button>';
		var users = app.users.pluck("username");
		var dropdown = '<select id = "dropdown">';
    users.forEach(function(element){dropdown += "<option>"+element+"</option>";});
		dropdown += ('</select>');
		var title = '
Please Choose A Username
';
		var all =  title + dropdown + button;
		this.$el.html(  all );
	},
	delete: function() {
			this.$el.html('');
	},
	initialize: function() {
		console.log("initializing");
		// this.on("logout", this.delete, this);

	},
	events: {
		"click #logout" : "logout",
		"click #login" : "login"
	},
	login: function() {
		app.currentUser = $('#dropdown').val();
		console.log("loging in");
    this.remove();
			app.gui.switchToUser();
	},
	logout: function() {
		console.log("logging out");
		this.$el.empty();
		this.remove();
		app.gui.switchToLogin();
	}

});

//=============================================
// 7. GUI
//    Function that builds everything at the end
//=============================================

function GUI(users,tasks,el) {
	this.switchToUser = function (){
		var userView = new UserView();
		userView.render();
		$('#app').append(userView.$el);
	};
	 this.switchToLogin = function() {
		 var login = new LoginView();
		 login.render();
		 $("#app").append(login.$el);
   };
	  var currentUser = this.currentUser;
    this.switchToLogin();
}

  return GUI;

})();
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

'use strict';

var grpc = require('../');

var _ = require('lodash');

var health_proto = grpc.load(__dirname + '/health.proto');

var HealthClient = health_proto.grpc.health.v1alpha.Health;

function HealthImplementation(statusMap) {
  this.statusMap = _.clone(statusMap);
}

HealthImplementation.prototype.setStatus = function(service, status) {
  this.statusMap[service] = status;
};

HealthImplementation.prototype.check = function(call, callback){
  var service = call.request.service;
  callback(null, {status: _.get(this.statusMap, service, 'UNSPECIFIED')});
};

module.exports = {
  Client: HealthClient,
  Service: HealthClient.service,
  Implementation: HealthImplementation
};
<commit_msg>Added tests for health checking<commit_after>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

'use strict';

var grpc = require('../');

var _ = require('lodash');

var health_proto = grpc.load(__dirname + '/health.proto');

var HealthClient = health_proto.grpc.health.v1alpha.Health;

function HealthImplementation(statusMap) {
  this.statusMap = _.clone(statusMap);
}

HealthImplementation.prototype.setStatus = function(service, status) {
  this.statusMap[service] = status;
};

HealthImplementation.prototype.check = function(call, callback){
  var service = call.request.service;
  debugger;
  callback(null, {status: _.get(this.statusMap, service, 'UNSPECIFIED')});
};

module.exports = {
  Client: HealthClient,
  service: HealthClient.service,
  Implementation: HealthImplementation
};
<|endoftext|>


<commit_before>var path = require('path');
var ff = require('ff');
var fs = require('fs');
var color = require('cli-color');
var spawn = require('child_process').spawn;

var gitClient = require('../util/gitClient');
var logger = require('../util/logging').get('module');

/**
 * A module for a game has several properties:
 *  - app paths: defines a list of paths into a module's file structure for
 *    files that a game can import
 *  - build targets: defines a list of build targets this module can generate
 *  - extensions: defines devkit extension modules (e.g. "simulator")
 */

var Module = module.exports = Class(function () {
  this.init = function (info) {
    this.name = info.name;
    this.path = info.path;
    this.version = info.version || info.packageContents.version;
    this.parent = info.parent;
    this.isDependency = info.isDependency;

    // game-side js.io path for importing client code from this module
    this._clientPaths = {};

    var devkit = info.packageContents.devkit;
    if (devkit.clientPaths) {
      for (var key in devkit.clientPaths) {
        this._clientPaths[key] = devkit.clientPaths[key];
      }
    }

    this._buildTargets = {};
    if (devkit.buildTargets) {
      for (var target in devkit.buildTargets) {
        this._buildTargets[target] = path.join(this.path, devkit.buildTargets[target]);
      }
    }

    this._extensions = {};
    if (devkit.extensions) {
      for (var name in devkit.extensions) {
        this._extensions[name] = path.join(this.path, devkit.extensions[name]);
      }
    }
  }

  this.getClientPaths = function (relativeTo) {
    return this._clientPaths;
  }

  this.getBuildTargets = function () {
    return this._buildTargets;
  }

  this.getExtensions = function () {
    return this._extensions;
  }

  this.loadExtension = function (name) {
    var extension = this._extensions[name];
    return extension && require(extension) || null;
  }

  this.loadBuildTarget = function (name) {
    var buildTarget = this._buildTargets[name];
    return buildTarget && require(buildTarget) || null;
  }

  // defines the public JSON API for DevKit extensions
  this.toJSON = function () {
    return {
      name: this.name,
      path: this.path,
      version: this.version,
      parent: this.parent,
      isDependency: this.isDependency,
      clientPaths: this.getClientPaths(),
      extensions: this.getExtensions()
    };
  }
});

function strip(str) {
  return str.replace(/^\s+|\s+$/g, '');
}

Module.getURL = function (modulePath, cb) {
  var git = gitClient.get(modulePath);
  var f = ff(function () {
    git('remote', '-v', {extraSilent: true}, f());
  }, function (remotes) {
    var url = remotes.split('\n').map(function (line) {
        return line.match(/^origin\s+(.*?)\s+\(fetch\)/);
      }).filter(function (match) { return match; })
        .map(function (match) { return match[1]; })[0];
    f(url);
  }).cb(cb);
}

Module.describeVersion = function (modulePath, cb) {
  var git = gitClient.get(modulePath);
  var moduleName = path.basename(modulePath);
  var f = ff(function () {
    fs.exists(modulePath, f.slotPlain());
  }, function (exists) {
    if (!exists) {
      return f.fail({code: 'ENOENT', filename: moduleName});
    }

    git('describe', '--tags', '--exact-match', {extraSilent: true}, f.slotPlain(2));
    git('rev-parse', 'HEAD', {extraSilent: true}, f());
  }, function (noTag, tag, hash) {
    f({
      tag: !noTag && strip(tag),
      hash: strip(hash)
    });
  }).cb(cb);
}

Module.getVersions = function (modulePath, cb) {
  var git = gitClient.get(modulePath);
  var f = ff(function () {
    git.getLocalVersions(f());
    git('describe', '--tags', {extraSilent: true}, f());
  }, function (versions, currentVersion) {
    f({
      current: strip(currentVersion),
      versions: versions
    });
  }).cb(cb);
}

Module.setVersion = function (modulePath, versionOrOpts, cb) {
  var opts = typeof versionOrOpts == 'object' && versionOrOpts || {};
  var version = typeof versionOrOpts == 'string' && versionOrOpts || opts.version;

  var git = gitClient.get(modulePath);
  var moduleName = path.basename(modulePath);
  var info = {};
  var forceInstall = !!opts.install;

  var f = ff(function () {
    git.getLocalVersions(f());
    Module.describeVersion(modulePath, f());
    if (version) {
      // exits with code == 0 if the requested revision/tag/branch is present;
      // otherwise, returns a non-zero error code which means we should
      // probably run fetch first
      git('branch', '--list', version, {extraSilent: true}, f());
      git('log', '--pretty=format:%H', '-n', '1', version, {extraSilent: true}, f.slotPlain(2));
    }
    // git('describe', '--tags', {extraSilent: true}, f());
  }, function (versions, currentVersion, isBranch, notPresentErr, hash) {
    // if the version is a branch, we should always fetch
    info.currentTag = currentVersion.tag;
    info.currentHash = currentVersion.hash;
    info.isBranch = !!(isBranch && isBranch.replace(/^\s+|\s+$/g, ''));
    info.hash = hash && hash.replace(/^\s+|\s+$/g, '');
    info.tag = versions.indexOf(version) != -1 && version;
    info.name = info.tag || info.hash;

    // are we already on that version?
    if (!forceInstall && info.currentHash == info.hash) {
      logger.log(color.cyanBright("set version"), color.yellowBright(moduleName + "@" + info.name));
      return f.succeed(info.name);
    }

    // if no version was specified and skipFetch wasn't provided, fetch the
    // latest. Always fetch if the requested version isn't present in the tree
    // or if the requested version is a branch.
    if (!opts.skipFetch && !version || notPresentErr || isBranch) {
      // can't be silent in case it prompts for credentials
      git('fetch', '--tags', {silent: false, buffer: false, stdio: 'inherit'}, f());
    }
  }, function (isBranch) {
    git.getLocalVersions(f());
  }, function (versions) {
    if (!version) {
      // default to the latest tagged version
      info.tag = versions[0];
    }

    // if the tags match
    if (!forceInstall && info.currentTag == info.tag) {
      return f.succeed(version);
    }

    if (version) {
      logger.log(color.cyanBright("installing"), color.yellowBright(moduleName + "@" + version));
      git('checkout', version, f());
    } else {
      f.fail("no valid versions found");
    }
  }, function () {
    if (info.isBranch) {
      git('pull', f());
    }
  }, function () {
    logger.log("running install scripts...");

    var npmArgs = ['install'];
    if (process.getuid() == 0) {
      npmArgs.push('--unsafe-perm');
    }

    var npm = spawn('npm', npmArgs, {stdio: 'inherit', cwd: modulePath});
    npm.on('close', f.wait());
  }, function () {
    logger.log(color.cyanBright("set version"), color.yellowBright(moduleName + "@" + version));
    f(version);
  }).cb(cb);
};
<commit_msg>fix bug where installing a hash failed if both currentTag and info.tag are false<commit_after>var path = require('path');
var ff = require('ff');
var fs = require('fs');
var color = require('cli-color');
var spawn = require('child_process').spawn;

var gitClient = require('../util/gitClient');
var logger = require('../util/logging').get('module');

/**
 * A module for a game has several properties:
 *  - app paths: defines a list of paths into a module's file structure for
 *    files that a game can import
 *  - build targets: defines a list of build targets this module can generate
 *  - extensions: defines devkit extension modules (e.g. "simulator")
 */

var Module = module.exports = Class(function () {
  this.init = function (info) {
    this.name = info.name;
    this.path = info.path;
    this.version = info.version || info.packageContents.version;
    this.parent = info.parent;
    this.isDependency = info.isDependency;

    // game-side js.io path for importing client code from this module
    this._clientPaths = {};

    var devkit = info.packageContents.devkit;
    if (devkit.clientPaths) {
      for (var key in devkit.clientPaths) {
        this._clientPaths[key] = devkit.clientPaths[key];
      }
    }

    this._buildTargets = {};
    if (devkit.buildTargets) {
      for (var target in devkit.buildTargets) {
        this._buildTargets[target] = path.join(this.path, devkit.buildTargets[target]);
      }
    }

    this._extensions = {};
    if (devkit.extensions) {
      for (var name in devkit.extensions) {
        this._extensions[name] = path.join(this.path, devkit.extensions[name]);
      }
    }
  }

  this.getClientPaths = function (relativeTo) {
    return this._clientPaths;
  }

  this.getBuildTargets = function () {
    return this._buildTargets;
  }

  this.getExtensions = function () {
    return this._extensions;
  }

  this.loadExtension = function (name) {
    var extension = this._extensions[name];
    return extension && require(extension) || null;
  }

  this.loadBuildTarget = function (name) {
    var buildTarget = this._buildTargets[name];
    return buildTarget && require(buildTarget) || null;
  }

  // defines the public JSON API for DevKit extensions
  this.toJSON = function () {
    return {
      name: this.name,
      path: this.path,
      version: this.version,
      parent: this.parent,
      isDependency: this.isDependency,
      clientPaths: this.getClientPaths(),
      extensions: this.getExtensions()
    };
  }
});

function strip(str) {
  return str.replace(/^\s+|\s+$/g, '');
}

Module.getURL = function (modulePath, cb) {
  var git = gitClient.get(modulePath);
  var f = ff(function () {
    git('remote', '-v', {extraSilent: true}, f());
  }, function (remotes) {
    var url = remotes.split('\n').map(function (line) {
        return line.match(/^origin\s+(.*?)\s+\(fetch\)/);
      }).filter(function (match) { return match; })
        .map(function (match) { return match[1]; })[0];
    f(url);
  }).cb(cb);
}

Module.describeVersion = function (modulePath, cb) {
  var git = gitClient.get(modulePath);
  var moduleName = path.basename(modulePath);
  var f = ff(function () {
    fs.exists(modulePath, f.slotPlain());
  }, function (exists) {
    if (!exists) {
      return f.fail({code: 'ENOENT', filename: moduleName});
    }

    git('describe', '--tags', '--exact-match', {extraSilent: true}, f.slotPlain(2));
    git('rev-parse', 'HEAD', {extraSilent: true}, f());
  }, function (noTag, tag, hash) {
    f({
      tag: !noTag && strip(tag),
      hash: strip(hash)
    });
  }).cb(cb);
}

Module.getVersions = function (modulePath, cb) {
  var git = gitClient.get(modulePath);
  var f = ff(function () {
    git.getLocalVersions(f());
    git('describe', '--tags', {extraSilent: true}, f());
  }, function (versions, currentVersion) {
    f({
      current: strip(currentVersion),
      versions: versions
    });
  }).cb(cb);
}

Module.setVersion = function (modulePath, versionOrOpts, cb) {
  var opts = typeof versionOrOpts == 'object' && versionOrOpts || {};
  var version = typeof versionOrOpts == 'string' && versionOrOpts || opts.version;

  var git = gitClient.get(modulePath);
  var moduleName = path.basename(modulePath);
  var info = {};
  var forceInstall = !!opts.install;

  var f = ff(function () {
    git.getLocalVersions(f());
    Module.describeVersion(modulePath, f());
    if (version) {
      // exits with code == 0 if the requested revision/tag/branch is present;
      // otherwise, returns a non-zero error code which means we should
      // probably run fetch first
      git('branch', '--list', version, {extraSilent: true}, f());
      git('log', '--pretty=format:%H', '-n', '1', version, {extraSilent: true}, f.slotPlain(2));
    }
    // git('describe', '--tags', {extraSilent: true}, f());
  }, function (versions, currentVersion, isBranch, notPresentErr, hash) {
    // if the version is a branch, we should always fetch
    info.currentTag = currentVersion.tag;
    info.currentHash = currentVersion.hash;
    info.isBranch = !!(isBranch && isBranch.replace(/^\s+|\s+$/g, ''));
    info.hash = hash && hash.replace(/^\s+|\s+$/g, '');
    info.tag = versions.indexOf(version) != -1 && version;
    info.name = info.tag || info.hash;

    // are we already on that version?
    if (!forceInstall && info.currentHash == info.hash) {
      logger.log(color.cyanBright("set version"), color.yellowBright(moduleName + "@" + info.name));
      return f.succeed(info.name);
    }

    // if no version was specified and skipFetch wasn't provided, fetch the
    // latest. Always fetch if the requested version isn't present in the tree
    // or if the requested version is a branch.
    if (!opts.skipFetch && !version || notPresentErr || isBranch) {
      // can't be silent in case it prompts for credentials
      git('fetch', '--tags', {silent: false, buffer: false, stdio: 'inherit'}, f());
    }
  }, function (isBranch) {
    git.getLocalVersions(f());
  }, function (versions) {
    if (!version) {
      // default to the latest tagged version
      info.tag = versions[0];
    }

    // if the tags match
    if (!forceInstall && info.currentTag && info.currentTag == info.tag) {
      return f.succeed(version);
    }

    if (version) {
      logger.log(color.cyanBright("installing"), color.yellowBright(moduleName + "@" + version));
      git('checkout', version, f());
    } else {
      f.fail("no valid versions found");
    }
  }, function () {
    if (info.isBranch) {
      git('pull', f());
    }
  }, function () {
    logger.log("running install scripts...");

    var npmArgs = ['install'];
    if (process.getuid() == 0) {
      npmArgs.push('--unsafe-perm');
    }

    var npm = spawn('npm', npmArgs, {stdio: 'inherit', cwd: modulePath});
    npm.on('close', f.wait());
  }, function () {
    logger.log(color.cyanBright("set version"), color.yellowBright(moduleName + "@" + version));
    f(version);
  }).cb(cb);
};
<|endoftext|>


<commit_before>import Manifest from './manifest';

/**
 *
 * @param {String | Array} path path to the string
 */
export function getUrl(path) {
    if (typeof path === "string") {
        path = path.split('/');
    }

    // Check if path is empty
    if (path === []) {
        throw new Error("Path cannot be empty");
    }

    // prev = children (starts with the manifest)
    // current = what we are looking at now
    return path.reduce((prev, current) => {
        const entity = prev.find(entity => entity.id === current);
        if (entity === undefined) {
            throw new Error(`Could not find asset with path: ${path.join("/")}`);
        }

        if (entity.children) {
            // If there are still children left, return the children
            return entity.children;
        } else if (entity.url) {
            // When there are no more children left, return the url
            return entity.url;
        } else {
            throw new Error("Entity is of wrong type: " + entity);
        }
    }, Manifest);
}<commit_msg>Fixed bug in assetLoader where the path is not correctly checked to be empty<commit_after>import Manifest from './manifest';

/**
 *
 * @param {String | Array} path path to the string
 */
export function getUrl(path) {
    if (typeof path === "string") {
        path = path.split('/');
    }

    // Check if path is empty
    if (path.length === 0) {
        throw new Error("Path cannot be empty");
    }

    // prev = children (starts with the manifest)
    // current = what we are looking at now
    return path.reduce((prev, current) => {
        const entity = prev.find(entity => entity.id === current);
        if (entity === undefined) {
            throw new Error(`Could not find asset with path: ${path.join("/")}`);
        }

        if (entity.children) {
            // If there are still children left, return the children
            return entity.children;
        } else if (entity.url) {
            // When there are no more children left, return the url
            return entity.url;
        } else {
            throw new Error("Entity is of wrong type: " + entity);
        }
    }, Manifest);
}<|endoftext|>


<commit_before>let answer = document.getElementById('answer');
let attempt = document.getElementById('attempt');
let messageLabel = document.getElementById('message');

function guess() {
    let input = document.getElementById('user-guess');
    //add functionality to guess function here
    if (answer.value == '' || attempt.value == ''){
      setHiddenFields();
    }

        if(!validateInput(input)){
      return false;
    }
    {
      else attempt.value = attempt.value + 1;
    }

}

function setHiddenFields () {
    attempt.value = "0"
    answer.value = Math.floor(Math.random() * 10000).toString() ;

    while(answer.value.length < 4)
    {
      answer.value = "0" + answer.value;
    }
}

function setMessage(message){

    messageLabel.innerHTML = message;

}

function validateInput(input){

    if(input.length == 4){
          return true;
    }
    else{

      setMessage("Guesses must be exactly 4 characters long.");
      return false;
    }

}
<commit_msg>fix to guess<commit_after>let answer = document.getElementById('answer');
let attempt = document.getElementById('attempt');
let messageLabel = document.getElementById('message');

function guess() {
    let input = document.getElementById('user-guess');
    //add functionality to guess function here
    if (answer.value == '' || attempt.value == ''){
      setHiddenFields();
    }

      if(!validateInput(input.value))
      {
        return;
      }
      attempt.value++;

}

function setHiddenFields () {
    attempt.value = "0"
    answer.value = Math.floor(Math.random() * 10000).toString() ;

    while(answer.value.length < 4)
    {
      answer.value = "0" + answer.value;
    }
}

function setMessage(message){

    messageLabel.innerHTML = message;

}

function validateInput(input){

    if(input.length == 4){
          return true;
    }
    else{

      setMessage("Guesses must be exactly 4 characters long.");
      return false;
    }

}
<|endoftext|>