<commit_before>var user_margin={top:20,bottom:20,left:20,right:20},
	user_width=1300-user_margin.left-user_margin.right,
	user_height=630-user_margin.top-user_margin.bottom;

var user_lineColor=['#d62728', '#d62728','#d62728','#2ca02c','#2ca02c','#2ca02c','#9467bd','#1f77b4','#1f77b4','#1f77b4','#ff7f0e','#ff7f0e','#ff7f0e','#ff7f0e','#98df8a','#8c6d31','#8c6d31','#c7c7c7','#bcbd22','#bcbd22','#bcbd22'];

var user_lines = ['1','2','3','4','5','6','7','A','C','E','B','D','F','M','G','J','Z','L','N','Q','R'];

var user_font_size=15,
	subWayHeight=user_height*2/3,
	HeatMapHeight=user_height/3,
	gridWidth = Math.floor((user_width)/ 27),
	gridHeight=Math.floor(HeatMapHeight/8),
	cross=100,
	days = ["Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"];

var user_x,user_y;

var user_heatMap, user_subwayMap;

function user_initiate(){

	queue().defer(d3.json,'./data/nyc_boroughs.json')
		.defer(d3.csv,'./data/weekday_line.csv')
		.defer(d3.json,'./data/paths.json')
		.await(user_start());
}

function user_start()
{
	console.log('start user_start');
	user_drawSubmap();

	d3.csv("./data/weekday_line.csv",function(error, frequency)
	{
		if(error) throw error;
		frequency.forEach(function(d){d.percentage=+d.percentage;});
		user_drawHeatMap(frequency);
	});

}

function user_drawHeatMap(frequency)
{
	console.log('start user_drawHeatMap');
	console.log(frequency);
	var minFreq=d3.min(frequency, function(d){return d.percentage;}),
		maxFreq=d3.max(frequency, function(d){return d.percentage;});
	var rectColor=d3.scale.linear().range(['#fff9f9','#e50000']).domain([minFreq,maxFreq]);

    var Range = function(min, max, bucket)
    {
					  var interval = (max-min) / parseFloat(bucket);
					  var result = [];
					  var start = min;
					  while (start < max)
					  {
					    result.push(start)
					    start = start + interval;
  						}
  				return result;
	}

	user_x=d3.scale.ordinal().domain(user_lines).range(Range(cross,cross+21*gridWidth,21));
	user_y=d3.scale.ordinal().domain(days).range(Range(gridHeight/2,7*gridHeight+gridHeight/2,7));

	user_heatMap = d3.select('svg.user_heatmap')
					.attr('width',user_width)
					.attr('height',user_height/3)
					.append('g')
					.attr('class','user_heatMap')
					.attr('transform','translate(0,20)');

	var dayLabels = user_heatMap.append('g')
							.attr('class','user_dayLabels')
							.selectAll(".user_dayLabel")
					        .data(days)
					        .enter().append("text")
					        .text(function (d) { return d; })
					        .attr("x", cross-5)
					        .attr("y", function (d, i) { return i * gridHeight+user_font_size*2; })
					        .style('font-size',user_font_size)
					        .attr("class", "user_dayLabel")
					        .attr('text-anchor','end');

	var CircleLabel=user_heatMap.append('g')
							.attr('class','user_circleLabels')
							.selectAll('.user_circleLabel')
							.data(user_lineColor)
							.enter()
							.append('circle')
							.attr('cx',function(d,i) { return i * gridWidth+cross+gridWidth/2;})
							.attr('cy',-4)
							.attr('r',user_font_size)
							.style('fill',function(d){return d;})
							.attr("opacity", 0.5)
							.attr('tranform',"translate(" + gridWidth/2 + ", 0)")
							.attr('class','user_circleLabel');

	var lineLabels = user_heatMap.append('g')
							.attr('class','user_lineLabels')
							.selectAll(".user_lineLabel")
				            .data(user_lines)
				            .enter().append("text")
				            .text(function(d) { return d; })
				            .attr("x", function(d, i) { return i * gridWidth+cross+gridWidth/2+2; })
				            .attr("y", 0)
				            .style('font-size',user_font_size)
				            .attr("class", 'luser_ineLabel')
				            .attr('id',function(d){return d;})
				            .attr('text-anchor','end');

    var rects = user_heatMap.append('g')
						 .attr('class','user_freqRects')
						 .selectAll('.user_freqRect')
	    				 .data(frequency)
	    				 .enter()
	    				 .append('rect')
	    				 .attr('x',function(d){return user_x(d.Line);})
	    				 .attr('y',function(d){return user_y(d.Weekday)})
	    				 .attr('rx',4)
	    				 .attr('ry',4)
	    				 .attr('class',function(d){return 'user_freqRect.'+d.Line})
	    				 .attr('width',gridWidth-2)
	    				 .attr('height',gridHeight-5)
	    				 .style('fill',function(d){return rectColor(d.percentage)})
	    				 .on('mouseover',function(d){moveMarker(d.percentage);})
	    				 .on('mouseout',function(d){
	    				 	user_heatMap.selectAll('.user_temp').remove();
	    				 });

	addLineargradient();

	function addLineargradient(){
	  var linearGradient = user_heatMap.append('g')
							  		.attr('class','user_linearGradient')
							  		.attr('transform',"translate(" + (gridWidth*24)+ ","+ user_font_size*2+")")
							  		.append('linearGradient')
							        .attr('id', 'linearColor')
							        .attr('x1', '0%')
							        .attr('y1', '0%')
							        .attr('x2', '0%')
							        .attr('y2', '100%');

	  var stop1 = linearGradient.append('stop')
						        .attr('offset', '0%')
						        .style('stop-color', '#fff9f9');

	  var stop2 = linearGradient.append('stop')
						        .attr('offset', '100%')
						        .style('stop-color', '#e50000');

	  var colorRect = d3.select('.user_linearGradient')
				  		.append('rect')
				        .attr('width', gridWidth*2/3)
				        .attr('height', gridHeight*4)
				        .attr('x', 0)
				        .attr('y', 0)
				        .attr('stroke', 'gray')
				        .style('fill', 'url(#' + linearGradient.attr('id') + ')');
	}

    function moveMarker(pos){

      	var markerY=d3.scale.linear().range([0,gridHeight*4]).domain([minFreq,maxFreq]);

	    user_heatMap.select('.user_linearGradient')
			    .append('line')
			    .attr('class','user_temp')
			    .attr('id','line')
			    .attr('x1',0)
			    .attr('x2',gridWidth*2/3)
			    .attr('y1',markerY(pos))
			    .attr('y2',markerY(pos))
			    .attr('stroke-width','1.5px')
			    .attr('stroke','black');

	    user_heatMap.select('.user_linearGradient')
	    .append('text')
	    .attr('class','user_temp')
	    .attr('id','user_text')
	    .attr('x',gridWidth*2/3)
	    .attr('y',markerY(pos))
	    .text(pos+'%')
	    .attr('font-size',user_font_size);
  };
}

function user_drawSubmap(user_svg)
{
	console.log('start user_drawSubmap');
	var mapScale = 35000;

   // SUBWAY
	var projection = d3.geo.mercator()
					.center([-73.955, 40.678])
		            .translate([100,193])
		            .scale([mapScale]);

	var path = d3.geo.path()
            	.projection(projection);

	user_subwayMap=d3.select('svg.subway_map')
						.attr('height',user_height/2)
						.attr('width',user_width/3)
						.append('g')
						.attr('class','user_subwayMap');

	NYC();
	PATHS();
	lineStart();

	// NYC MAP
    function NYC()
    {
    	d3.json('./data/nyc_boroughs.json',function(err,nyc_boroughs)
    	{
    	if(err) console.log(err);
    	user_subwayMap.append('g')
					 .attr('class','user_NYC')
					 .selectAll("path.user_borough_map")
		             .data(topojson.feature(nyc_boroughs[0], nyc_boroughs[0].objects.new_york_city_boroughs).features)
		             .enter()
		             .append("path")
		             .attr("d", path)
		             .attr("class", "user_borough_map")
		             .style('opacity',0.1);
    	});
    }

    function PATHS(){
    // lines
    d3.json("./data/paths.json",function(error, subway)
	{
		if(error) throw error;
    	var subwayLines=user_subwayMap.append('g')
    				.attr('class','user_subwayLines')
    				.selectAll('.user_subWayLine')
    				 .data(subway.features)
    				 .enter()
    				 .append('path')
    				 .attr('class','user_subWayLine')
    				 .attr('d',path)
    				 .attr('id',function(d){return 'user_'+d.properties.lines[0];})
    				 .style('stroke',function(d){return getColor(d.properties.lines[0]);})
    				 .style('stroke-width',3)
    				 .style('fill-opacity',0)
    				 .style('stroke-opacity',0.6)
    				 .style('cursor','pointer')
    				 .on('mouseover',function(d){
	        			console.log(d);
	        			console.log('stops: '+d.properties.lines[0]);
	   					user_highLightLine(d.properties.lines[0]);
	        		})
	        		.on('mouseout',function(){
	    				d3.select('.user_temp_rect').remove();
	    			});
    });
}

  function lineStart(){
    //line_starts
    d3.csv('./data/stops.csv',function(err,stops){
    	if(err) console.log(err);
        user_subwayMap.append('g')
        		.attr('class','user_starts')
        		.selectAll('.user_start')
        		.data(stops)
        		.enter()
        		.append('text')
        		.attr('class','user_start')
        		.attr('x',function(d){
        			return projection([d.Long,d.Lat])[0]})
        		.attr('y',function(d){
        			return projection([d.Long,d.Lat])[1]})
        		.attr('id',function(d,i){return d.Line;})
        		.attr('fill',function(d){return user_lineColor[getIndex(d.Line)]})
        		.text(function(d){return d.Line;})
        		.style('cursor','pointer')
        		.on('mouseover',function(d){
        			console.log(d);
        			console.log('stops: '+d.Line);
   					user_highLightLine(d.Line);
        		})
        		.on('mouseout',function(){
    				d3.select('.user_temp_rect').remove();
    			});
    });
}
    //   //stops
    // d3.csv('subway_map.csv',function(err,stops){
    // 	if(err) console.log(err);
    // 	console.log(stops);
    //     user_subwayMap.append('g')
    //     		.attr('class','stops')
    //     		.selectAll('.station')
    //     		.data(stops)
    //     		.enter()
    //     		.append('circle')
    //     		.attr('class','station')
    //     		.attr('cx',function(d){return projection([d.Long,d.Lat])[0]})
    //     		.attr('cy',function(d){return projection([d.Long,d.Lat])[1]})
    //     		.attr('r',3)
    //     		.attr('id',function(d,i){return d.Line+' '+i;})
    //     		.attr('fill',function(d){return user_lineColor[getIndex(d.Line)]})
    //     		.on('mouseover',function(d){
    //     			console.log(d);
    //     			console.log('stops: '+d.Line);
   	// 				highLightLine(d.Line);
    //     		})
    //     		.on('mouseout',function(){
    // 				d3.select('.temp_rect').remove();
    // 			});
    // })

   function getColor(line)
   {
	   	return user_lineColor[getIndex(line)];
   	}

   function getIndex(line)
   {
   	for(var i=0;i<user_lines.length;i++)
   	   {
   	   	if(line.localeCompare(user_lines[i])==0)
   	   	{
   	   		return i;
   	   	}
   	   }
   }
}

function user_highLightLine(line)
{
	user_heatMap.append('rect')
			.attr('class','user_temp_rect')
			.attr('x',function(){return user_x(line);})
			.attr('y',gridHeight/2)
			.attr('width',gridWidth)
			.attr('height',7*gridHeight)
			.attr('fill-opacity',0)
			.attr('stroke-width',3)
			.attr('stroke','black');
}

<commit_msg>concise user.js<commit_after>var user_margin={top:20,bottom:20,left:20,right:20},
	user_width=1300-user_margin.left-user_margin.right,
	user_height=630-user_margin.top-user_margin.bottom;

var user_lineColor=['#d62728', '#d62728','#d62728','#2ca02c','#2ca02c','#2ca02c','#9467bd','#1f77b4','#1f77b4','#1f77b4','#ff7f0e','#ff7f0e','#ff7f0e','#ff7f0e','#98df8a','#8c6d31','#8c6d31','#c7c7c7','#bcbd22','#bcbd22','#bcbd22'];

var user_lines = ['1','2','3','4','5','6','7','A','C','E','B','D','F','M','G','J','Z','L','N','Q','R'];

var user_font_size=15,
	subWayHeight=user_height*2/3,
	HeatMapHeight=user_height/3,
	gridWidth = Math.floor((user_width)/ 27),
	gridHeight=Math.floor(HeatMapHeight/8),
	cross=100,
	days = ["Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"];

var user_x,user_y;

var user_heatMap, user_subwayMap;

function user_initiate(){

	queue().defer(d3.json,'./data/nyc_boroughs.json')
		.defer(d3.csv,'./data/weekday_line.csv')
		.defer(d3.json,'./data/paths.json')
		.await(user_start());
}

function user_start()
{
	user_drawSubmap();

	d3.csv("./data/weekday_line.csv",function(error, frequency)
	{
		if(error) throw error;
		frequency.forEach(function(d){d.percentage=+d.percentage;});
		user_drawHeatMap(frequency);
	});

}

function user_drawHeatMap(frequency)
{
	console.log('start user_drawHeatMap');
	var minFreq=d3.min(frequency, function(d){return d.percentage;}),
		maxFreq=d3.max(frequency, function(d){return d.percentage;});
	var rectColor=d3.scale.linear().range(['#fff9f9','#e50000']).domain([minFreq,maxFreq]);

    var Range = function(min, max, bucket)
    {
					  var interval = (max-min) / parseFloat(bucket);
					  var result = [];
					  var start = min;
					  while (start < max)
					  {
					    result.push(start)
					    start = start + interval;
  						}
  				return result;
	}

	user_x=d3.scale.ordinal().domain(user_lines).range(Range(cross,cross+21*gridWidth,21));
	user_y=d3.scale.ordinal().domain(days).range(Range(gridHeight/2,7*gridHeight+gridHeight/2,7));

	user_heatMap = d3.select('svg.user_heatmap')
					.attr('width',user_width)
					.attr('height',user_height/3)
					.append('g')
					.attr('class','user_heatMap')
					.attr('transform','translate(0,20)');

	var dayLabels = user_heatMap.append('g')
							.attr('class','user_dayLabels')
							.selectAll(".user_dayLabel")
					        .data(days)
					        .enter().append("text")
					        .text(function (d) { return d; })
					        .attr("x", cross-5)
					        .attr("y", function (d, i) { return i * gridHeight+user_font_size*2; })
					        .style('font-size',user_font_size)
					        .attr("class", "user_dayLabel")
					        .attr('text-anchor','end');

	var CircleLabel=user_heatMap.append('g')
							.attr('class','user_circleLabels')
							.selectAll('.user_circleLabel')
							.data(user_lineColor)
							.enter()
							.append('circle')
							.attr('cx',function(d,i) { return i * gridWidth+cross+gridWidth/2;})
							.attr('cy',-4)
							.attr('r',user_font_size)
							.style('fill',function(d){return d;})
							.attr("opacity", 0.5)
							.attr('tranform',"translate(" + gridWidth/2 + ", 0)")
							.attr('class','user_circleLabel');

	var lineLabels = user_heatMap.append('g')
							.attr('class','user_lineLabels')
							.selectAll(".user_lineLabel")
				            .data(user_lines)
				            .enter().append("text")
				            .text(function(d) { return d; })
				            .attr("x", function(d, i) { return i * gridWidth+cross+gridWidth/2+2; })
				            .attr("y", 0)
				            .style('font-size',user_font_size)
				            .attr("class", 'luser_ineLabel')
				            .attr('id',function(d){return d;})
				            .attr('text-anchor','end');

    var rects = user_heatMap.append('g')
						 .attr('class','user_freqRects')
						 .selectAll('.user_freqRect')
	    				 .data(frequency)
	    				 .enter()
	    				 .append('rect')
	    				 .attr('x',function(d){return user_x(d.Line);})
	    				 .attr('y',function(d){return user_y(d.Weekday)})
	    				 .attr('rx',4)
	    				 .attr('ry',4)
	    				 .attr('class',function(d){return 'user_freqRect.'+d.Line})
	    				 .attr('width',gridWidth-2)
	    				 .attr('height',gridHeight-5)
	    				 .style('fill',function(d){return rectColor(d.percentage)})
	    				 .on('mouseover',function(d){moveMarker(d.percentage);})
	    				 .on('mouseout',function(d){
	    				 	user_heatMap.selectAll('.user_temp').remove();
	    				 });

	addLineargradient();

	function addLineargradient(){
	  var linearGradient = user_heatMap.append('g')
							  		.attr('class','user_linearGradient')
							  		.attr('transform',"translate(" + (gridWidth*24)+ ","+ user_font_size*2+")")
							  		.append('linearGradient')
							        .attr('id', 'linearColor')
							        .attr('x1', '0%')
							        .attr('y1', '0%')
							        .attr('x2', '0%')
							        .attr('y2', '100%');

	  var stop1 = linearGradient.append('stop')
						        .attr('offset', '0%')
						        .style('stop-color', '#fff9f9');

	  var stop2 = linearGradient.append('stop')
						        .attr('offset', '100%')
						        .style('stop-color', '#e50000');

	  var colorRect = d3.select('.user_linearGradient')
				  		.append('rect')
				        .attr('width', gridWidth*2/3)
				        .attr('height', gridHeight*4)
				        .attr('x', 0)
				        .attr('y', 0)
				        .attr('stroke', 'gray')
				        .style('fill', 'url(#' + linearGradient.attr('id') + ')');
	}

    function moveMarker(pos){

      	var markerY=d3.scale.linear().range([0,gridHeight*4]).domain([minFreq,maxFreq]);

	    user_heatMap.select('.user_linearGradient')
			    .append('line')
			    .attr('class','user_temp')
			    .attr('id','line')
			    .attr('x1',0)
			    .attr('x2',gridWidth*2/3)
			    .attr('y1',markerY(pos))
			    .attr('y2',markerY(pos))
			    .attr('stroke-width','1.5px')
			    .attr('stroke','black');

	    user_heatMap.select('.user_linearGradient')
	    .append('text')
	    .attr('class','user_temp')
	    .attr('id','user_text')
	    .attr('x',gridWidth*2/3)
	    .attr('y',markerY(pos))
	    .text(pos+'%')
	    .attr('font-size',user_font_size);
  };
}

function user_drawSubmap(user_svg)
{
	var mapScale = 35000;

   // SUBWAY
	var projection = d3.geo.mercator()
					.center([-73.955, 40.678])
		            .translate([100,193])
		            .scale([mapScale]);

	var path = d3.geo.path()
            	.projection(projection);

	user_subwayMap=d3.select('svg.subway_map')
						.attr('height',user_height/2)
						.attr('width',user_width/3)
						.append('g')
						.attr('class','user_subwayMap');

	NYC();
	PATHS();
	lineStart();

	// NYC MAP
    function NYC()
    {
    	d3.json('./data/nyc_boroughs.json',function(err,nyc_boroughs)
    	{
    	if(err) console.log(err);
    	user_subwayMap.append('g')
					 .attr('class','user_NYC')
					 .selectAll("path.user_borough_map")
		             .data(topojson.feature(nyc_boroughs[0], nyc_boroughs[0].objects.new_york_city_boroughs).features)
		             .enter()
		             .append("path")
		             .attr("d", path)
		             .attr("class", "user_borough_map")
		             .style('opacity',0.1);
    	});
    }

    function PATHS(){
    // lines
    d3.json("./data/paths.json",function(error, subway)
	{
		if(error) throw error;
    	var subwayLines=user_subwayMap.append('g')
    				.attr('class','user_subwayLines')
    				.selectAll('.user_subWayLine')
    				 .data(subway.features)
    				 .enter()
    				 .append('path')
    				 .attr('class','user_subWayLine')
    				 .attr('d',path)
    				 .attr('id',function(d){return 'user_'+d.properties.lines[0];})
    				 .style('stroke',function(d){return getColor(d.properties.lines[0]);})
    				 .style('stroke-width',3)
    				 .style('fill-opacity',0)
    				 .style('stroke-opacity',0.6)
    				 .style('cursor','pointer')
    				 .on('mouseover',function(d){
	   					user_highLightLine(d.properties.lines[0]);
	        		})
	        		.on('mouseout',function(){
	    				d3.select('.user_temp_rect').remove();
	    			});
    });
}

  function lineStart(){
    //line_starts
    d3.csv('./data/stops.csv',function(err,stops){
    	if(err) console.log(err);
        user_subwayMap.append('g')
        		.attr('class','user_starts')
        		.selectAll('.user_start')
        		.data(stops)
        		.enter()
        		.append('text')
        		.attr('class','user_start')
        		.attr('x',function(d){
        			return projection([d.Long,d.Lat])[0]})
        		.attr('y',function(d){
        			return projection([d.Long,d.Lat])[1]})
        		.attr('id',function(d,i){return d.Line;})
        		.attr('fill',function(d){return user_lineColor[getIndex(d.Line)]})
        		.text(function(d){return d.Line;})
        		.style('cursor','pointer')
        		.on('mouseover',function(d){
   					user_highLightLine(d.Line);
        		})
        		.on('mouseout',function(){
    				d3.select('.user_temp_rect').remove();
    			});
    });
}
    //   //stops
    // d3.csv('subway_map.csv',function(err,stops){
    // 	if(err) console.log(err);
    // 	console.log(stops);
    //     user_subwayMap.append('g')
    //     		.attr('class','stops')
    //     		.selectAll('.station')
    //     		.data(stops)
    //     		.enter()
    //     		.append('circle')
    //     		.attr('class','station')
    //     		.attr('cx',function(d){return projection([d.Long,d.Lat])[0]})
    //     		.attr('cy',function(d){return projection([d.Long,d.Lat])[1]})
    //     		.attr('r',3)
    //     		.attr('id',function(d,i){return d.Line+' '+i;})
    //     		.attr('fill',function(d){return user_lineColor[getIndex(d.Line)]})
    //     		.on('mouseover',function(d){
    //     			console.log(d);
    //     			console.log('stops: '+d.Line);
   	// 				highLightLine(d.Line);
    //     		})
    //     		.on('mouseout',function(){
    // 				d3.select('.temp_rect').remove();
    // 			});
    // })

   function getColor(line)
   {
	   	return user_lineColor[getIndex(line)];
   	}

   function getIndex(line)
   {
   	for(var i=0;i<user_lines.length;i++)
   	   {
   	   	if(line.localeCompare(user_lines[i])==0)
   	   	{
   	   		return i;
   	   	}
   	   }
   }
}

function user_highLightLine(line)
{
	user_heatMap.append('rect')
			.attr('class','user_temp_rect')
			.attr('x',function(){return user_x(line);})
			.attr('y',gridHeight/2)
			.attr('width',gridWidth)
			.attr('height',7*gridHeight)
			.attr('fill-opacity',0)
			.attr('stroke-width',3)
			.attr('stroke','black');
}

<|endoftext|>


<commit_before>var roleHarvester = {

	/** @param {Creep} creep **/
	run: function(creep) {

		if (creep.memory.harvesting) {
			var sources = creep.room.find(FIND_SOURCES);

			if (!creep.memory.source) {
				for (source in sources) {
					if (_.filter(Game.creeps, (creep) =>
							(creep.memory.role == 'harvester') &&
							(creep.memory.source == source)
					).length != 2) {
						creep.memory.source = source;
					}
				}
			}
			if (creep.harvest(sources[creep.memory.source]) == ERR_NOT_IN_RANGE) {
				creep.moveTo(sources[creep.memory.source]);
			}
			else if (creep.carry.energy == creep.carryCapacity) {
				creep.say('Depositing');
			  creep.memory.harvesting = false;
			}
		}
		else {
			var targets = creep.room.find(FIND_STRUCTURES, {
				filter: (structure) => {
					return (structure.structureType == STRUCTURE_SPAWN);
				}
			});

			if (targets.length > 0) {
				if (creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
					creep.moveTo(targets[0]);
				}
			}
			if (creep.carry.energy == 0) {
				creep.say('Harvesting');
			  creep.memory.harvesting = true;
			}
		}

	} // function

}; // roleHarvester

module.exports = roleHarvester;<commit_msg>Adjust changes<commit_after>var roleHarvester = {

	/** @param {Creep} creep **/
	run: function(creep) {

		if (creep.memory.harvesting) {
			var sources = creep.room.find(FIND_SOURCES);

			if (!creep.memory.source) {
				for (source in sources) {
					if (_.filter(Game.creeps, (creep) =>
							(creep.memory.role == 'harvester') &&
							(creep.memory.source == source)
					).length != 2) {
						creep.memory.source = source;
					}
				}
			}
			if (creep.harvest(sources[creep.memory.source]) == ERR_NOT_IN_RANGE) {
				creep.moveTo(sources[creep.memory.source]);
			}
			else if (creep.carry.energy == creep.carryCapacity) {
				creep.say('Depositing');
			  creep.memory.harvesting = false;
			}
		}
		else {
			var targets = creep.pos.findInRange(FIND_STRUCTURES, 1, {
				filter: (structure) => {
					return (structure.structureType == STRUCTURE_CONTAINER);
				}
			});

			if (targets.length == 0) {
				var targets = creep.room.find(FIND_STRUCTURES, {
					filter: (structure) => {
						return (
							((structure.structureType == STRUCTURE_SPAWN) ||
							 (structure.structureType == STRUCTURE_EXTENSION)) &&
							(structure.energy < structure.energyCapacity));
					}
				});
			}
			if (creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
				creep.moveTo(targets[0]);
			}
			if (creep.carry.energy == 0) {
				creep.say('Harvesting');
			  creep.memory.harvesting = true;
			}
		}

	} // function

}; // roleHarvester

module.exports = roleHarvester;<|endoftext|>


<commit_before><commit_msg>:fire: Removed empty file<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var _minuteInMilliseconds = 60 * 1000;
var _hourInMilliseconds = _minuteInMilliseconds * 60;

exports.getCurrentDateTime = function() {
  return new tizen.TZDate();
};

exports.getLocalTimezone = function() {
  return _sendSyncMessage('GetLocalTimeZone').value;
};

var _availableTimezonesCache = [];

exports.getAvailableTimezones = function() {
  if (_availableTimezonesCache.length)
    return _availableTimezonesCache;
  _availableTimezonesCache = _sendSyncMessage('GetAvailableTimeZones').value;
  return _availableTimezonesCache;
};

exports.getDateFormat = function(shortformat) {
  if (shortformat)
    return 'd/m/y';
  return 'D, M d y';
};

exports.getTimeFormat = function() {
  return _sendSyncMessage('GetTimeFormat').value;
};

exports.isLeapYear = function(year) {
  if (!(year % 400))
    return true;
  if (!(year % 100))
    return false;
  if (!(year % 4))
    return true;
  return false;
};

function _throwProperTizenException(e) {
  if (e instanceof TypeError)
    throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
  else if (e instanceof RangeError)
    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR);
  else
    throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
}

function _sendSyncMessage(cmd, timezone, value, trans, locale) {
  var msg = {
    'cmd': cmd,
    'timezone': timezone || '',
    'value': value || '',
    'trans': trans || '',
    'locale': locale || false
  };
  return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(msg)));
}

var TimeDurationUnit = [
  'MSECS',
  'SECS',
  'MINS',
  'HOURS',
  'DAYS'
];

tizen.TimeDuration = function(length, unit) {
  // FIXME(cmarcelo): This is a best effort to ensure that this function is
  // called as a constructor only. We may need to implement some native
  // primitive to ensure that.
  if (!this || this.constructor != tizen.TimeDuration)
    throw new TypeError;

  var length_ = length || 0;
  var unit_ = unit || 'MSECS';

  Object.defineProperty(this, 'length', {
    get: function() {
      return length_; },
    set: function(NewValue) {
      if (NewValue != null)
        length_ = NewValue; }});

  Object.defineProperty(this, 'unit', {
    get: function() {
      return unit_; },
    set: function(NewValue) {
      if (TimeDurationUnit.indexOf(NewValue) >= 0)
        unit_ = NewValue; }});

  if (TimeDurationUnit.indexOf(this.unit) == -1)
    this.unit = 'MSECS';
};

function getMultiplier(unit) {
  if (unit == 'MSECS')
    return 1.0;
  if (unit == 'SECS')
    return 1.0 * 1000.0;
  if (unit == 'MINS')
    return 60.0 * 1000.0;
  if (unit == 'HOURS')
    return 3600.0 * 1000.0;
  return 86400.0 * 1000.0;
}

function makeMillisecondsDurationObject(length) {
  var dayInMsecs = _hourInMilliseconds * 24;

  if ((length % dayInMsecs) == 0)
    return new tizen.TimeDuration(length / dayInMsecs, 'DAYS');

  return new tizen.TimeDuration(length, 'MSECS');
}

tizen.TimeDuration.prototype.getMilliseconds = function() {
  return getMultiplier(this.unit) * this.length;
};

tizen.TimeDuration.prototype.difference = function(other) {
  try {
    return makeMillisecondsDurationObject(this.getMilliseconds() -
                                          other.getMilliseconds());
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.equalsTo = function(other) {
  try {
    return this.getMilliseconds() == other.getMilliseconds();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.lessThan = function(other) {
  try {
    return this.getMilliseconds() < other.getMilliseconds();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.greaterThan = function(other) {
  try {
    return this.getMilliseconds() > other.getMilliseconds();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.toString = function() {
  return this.length + ' ' + this.unit;
};

tizen.TZDate = function(year, month, day, hours, minutes, seconds, milliseconds, timezone) {
  // FIXME(cmarcelo): This is a best effort to ensure that this function is
  // called as a constructor only. We may need to implement some native
  // primitive to ensure that.
  if (!this || this.constructor != tizen.TZDate)
    throw new TypeError;

  this.date_;
  this.timezone_ = timezone || tizen.time.getLocalTimezone();

  var hours = hours || 0;
  var minutes = minutes || 0;
  var seconds = seconds || 0;
  var milliseconds = milliseconds || 0;

  if (!arguments.length)
    this.date_ = new Date();
  else if (arguments.length == 1 || arguments.length == 2) {
    if (arguments[0] instanceof Date)
      this.date_ = arguments[0];
    else
      this.date_ = new Date();
    if (arguments[1])
      this.timezone_ = arguments[1];
  }
  else
    this.date_ = new Date(year, month, day, hours, minutes, seconds, milliseconds);

  if (tizen.time.getAvailableTimezones().indexOf(this.timezone_) < 0)
    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR);
};

function getTimezoneOffset(timezone, timeInMs) {
  return _sendSyncMessage('GetTimeZoneOffset', timezone, timeInMs).value;
}

function _getTimeWithOffset(date) {
  var OffsetInMilliseconds = date.getTimezoneOffset() * _minuteInMilliseconds * -1;
  return date.getTime() + OffsetInMilliseconds;
}

tizen.TZDate.prototype.getDate = function() {
  return this.date_.getDate();
};

tizen.TZDate.prototype.setDate = function(date) {
  this.date_.setDate(date);
};

tizen.TZDate.prototype.getDay = function() {
  return this.date_.getDay();
};

tizen.TZDate.prototype.getFullYear = function() {
  return this.date_.getFullYear();
};

tizen.TZDate.prototype.setFullYear = function(year) {
  this.date_.setFullYear(year);
};

tizen.TZDate.prototype.getHours = function() {
  return this.date_.getHours();
};

tizen.TZDate.prototype.setHours = function(hours) {
  this.date_.setHours(hours);
};

tizen.TZDate.prototype.getMilliseconds = function() {
  return this.date_.getMilliseconds();
};

tizen.TZDate.prototype.setMilliseconds = function(ms) {
  this.date_.setMilliseconds(ms);
};

tizen.TZDate.prototype.getMonth = function() {
  return this.date_.getMonth();
};

tizen.TZDate.prototype.setMonth = function(month) {
  this.date_.setMonth(month);
};

tizen.TZDate.prototype.getMinutes = function() {
  return this.date_.getMinutes();
};

tizen.TZDate.prototype.setMinutes = function(minutes) {
  this.date_.setMinutes(minutes);
};

tizen.TZDate.prototype.getSeconds = function() {
  return this.date_.getSeconds();
};

tizen.TZDate.prototype.setSeconds = function(seconds) {
  this.date_.setSeconds(seconds);
};

tizen.TZDate.prototype.getUTCDate = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                          _getTimeWithOffset(this.date_)) * -1));
  return d.getDate();
};

tizen.TZDate.prototype.setUTCDate = function(date) {
  this.date_.setUTCDate(date);
};

tizen.TZDate.prototype.getUTCDay = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                         _getTimeWithOffset(this.date_)) * -1));
  return d.getDay();
};

tizen.TZDate.prototype.getUTCFullYear = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                          _getTimeWithOffset(this.date_)) * -1));
  return d.getFullYear();
};

tizen.TZDate.prototype.setUTCFullYear = function(year) {
  this.date_.setUTCFullYear(year);
};

tizen.TZDate.prototype.getUTCHours = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                           _getTimeWithOffset(this.date_)) * -1));
  return d.getHours();
};

tizen.TZDate.prototype.setUTCHours = function(hours) {
  var offset_hours = getTimezoneOffset(this.timezone_, _getTimeWithOffset(this.date_)) /
                     _hourInMilliseconds;
  this.date_.setHours(hours + offset_hours);
};

tizen.TZDate.prototype.getUTCMilliseconds = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                              _getTimeWithOffset(this.date_)) * -1));
  return d.getMilliseconds();
};

tizen.TZDate.prototype.setUTCMilliseconds = function(ms) {
  this.date_.setUTCMilliseconds(ms);
};

tizen.TZDate.prototype.getUTCMinutes = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                             _getTimeWithOffset(this.date_)) * -1));
  return d.getMinutes();
};

tizen.TZDate.prototype.setUTCMinutes = function(minutes) {
  this.date_.setUTCMinutes(minutes);
};

tizen.TZDate.prototype.getUTCMonth = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                           _getTimeWithOffset(this.date_)) * -1));
  return d.getMonth();
};

tizen.TZDate.prototype.setUTCMonth = function(month) {
  this.date_.setUTCMonth(month);
};

tizen.TZDate.prototype.getUTCSeconds = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                         _getTimeWithOffset(this.date_)) * -1));
  return d.getSeconds();
};

tizen.TZDate.prototype.setUTCSeconds = function(secs) {
  this.date_.setUTCSeconds(secs);
};

tizen.TZDate.prototype.getTime = function() {
  return this.date_.getTime();
};

tizen.TZDate.prototype.getTimezone = function() {
  return this.timezone_;
};

tizen.TZDate.prototype.toTimezone = function(timezone) {
  if (!timezone)
    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR);
  var d = new tizen.TZDate(new Date(this.date_.getTime()), timezone);
  return d.addDuration(new tizen.TimeDuration((getTimezoneOffset(timezone) * 1) +
                                              (getTimezoneOffset(this.timezone_) * -1)));
};

tizen.TZDate.prototype.toLocalTimezone = function() {
  return this.toTimezone(tizen.time.getLocalTimezone());
};

tizen.TZDate.prototype.toUTC = function() {
  return this.toTimezone('GMT');
};

tizen.TZDate.prototype.difference = function(other) {
  try {
    return makeMillisecondsDurationObject(this.getTime() - other.getTime());
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.equalsTo = function(other) {
  try {
    return this.getTime() == other.getTime();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.earlierThan = function(other) {
  try {
    return this.getTime() < other.getTime();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.laterThan = function(other) {
  try {
    return this.getTime() > other.getTime();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.addDuration = function(duration) {
  try {
    var date = new tizen.TZDate(new Date(this.date_.getTime()), this.timezone_);
    date.setMilliseconds(duration.getMilliseconds() + date.getMilliseconds());
    return date;
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.toLocaleDateString = function() {
  var result = _sendSyncMessage('ToDateString', this.timezone_,
                                this.date_.getTime(), '', true);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toLocaleTimeString = function() {
  var result = _sendSyncMessage('ToTimeString', this.timezone_,
                                this.date_.getTime(), '', true);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toLocaleString = function() {
  var result = _sendSyncMessage('ToString', this.timezone_,
                                this.date_.getTime(), '', true);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toDateString = function() {
  var result = _sendSyncMessage('ToDateString', this.timezone_,
                                this.date_.getTime(), '', false);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toTimeString = function() {
  var result = _sendSyncMessage('ToTimeString', this.timezone_,
                                this.date_.getTime(), '', false);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toString = function() {
  var result = _sendSyncMessage('ToString', this.timezone_,
                                this.date_.getTime(), '', false);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.getTimezoneAbbreviation = function() {
  var result = _sendSyncMessage('GetTimeZoneAbbreviation', this.timezone_,
                                this.date_.getTime());

  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.secondsFromUTC = function() {
  return this.date_.getTimezoneOffset() * 60;
};

tizen.TZDate.prototype.isDST = function() {
  var result = _sendSyncMessage('IsDST', this.timezone_,
                                _getTimeWithOffset(this.date_));

  if (result.error)
    return false;
  return result.value;
};

tizen.TZDate.prototype.getPreviousDSTTransition = function() {
  var OffsetInMilliseconds = this.date_.getTimezoneOffset() * _minuteInMilliseconds * -1;
  var result = _sendSyncMessage('GetDSTTransition', this.timezone_,
                                _getTimeWithOffset(this.date_), 'NEXT_TRANSITION');

  if (result.error || result.value == 0)
    return null;
  return new tizen.TZDate(new Date(result.value - OffsetInMilliseconds), this.timezone_);
};

tizen.TZDate.prototype.getNextDSTTransition = function() {
  var OffsetInMilliseconds = this.date_.getTimezoneOffset() * _minuteInMilliseconds * -1;
  var result = _sendSyncMessage('GetDSTTransition', this.timezone_,
                                _getTimeWithOffset(this.date_), 'PREV_TRANSITION');

  if (result.error || result.value == 0)
    return null;
  return new tizen.TZDate(new Date(result.value - OffsetInMilliseconds), this.timezone_);
};
<commit_msg>[Time] Truncate TimeDuration length attribute to integer<commit_after>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var _minuteInMilliseconds = 60 * 1000;
var _hourInMilliseconds = _minuteInMilliseconds * 60;

exports.getCurrentDateTime = function() {
  return new tizen.TZDate();
};

exports.getLocalTimezone = function() {
  return _sendSyncMessage('GetLocalTimeZone').value;
};

var _availableTimezonesCache = [];

exports.getAvailableTimezones = function() {
  if (_availableTimezonesCache.length)
    return _availableTimezonesCache;
  _availableTimezonesCache = _sendSyncMessage('GetAvailableTimeZones').value;
  return _availableTimezonesCache;
};

exports.getDateFormat = function(shortformat) {
  if (shortformat)
    return 'd/m/y';
  return 'D, M d y';
};

exports.getTimeFormat = function() {
  return _sendSyncMessage('GetTimeFormat').value;
};

exports.isLeapYear = function(year) {
  if (!(year % 400))
    return true;
  if (!(year % 100))
    return false;
  if (!(year % 4))
    return true;
  return false;
};

function _throwProperTizenException(e) {
  if (e instanceof TypeError)
    throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
  else if (e instanceof RangeError)
    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR);
  else
    throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
}

function _sendSyncMessage(cmd, timezone, value, trans, locale) {
  var msg = {
    'cmd': cmd,
    'timezone': timezone || '',
    'value': value || '',
    'trans': trans || '',
    'locale': locale || false
  };
  return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(msg)));
}

var TimeDurationUnit = [
  'MSECS',
  'SECS',
  'MINS',
  'HOURS',
  'DAYS'
];

tizen.TimeDuration = function(length, unit) {
  // FIXME(cmarcelo): This is a best effort to ensure that this function is
  // called as a constructor only. We may need to implement some native
  // primitive to ensure that.
  if (!this || this.constructor != tizen.TimeDuration)
    throw new TypeError;

  var length_ = Math.floor(length) || 0;
  var unit_ = unit || 'MSECS';

  Object.defineProperty(this, 'length', {
    get: function() {
      return length_; },
    set: function(NewValue) {
      if (NewValue != null)
        length_ = Math.floor(NewValue); }});

  Object.defineProperty(this, 'unit', {
    get: function() {
      return unit_; },
    set: function(NewValue) {
      if (TimeDurationUnit.indexOf(NewValue) >= 0)
        unit_ = NewValue; }});

  if (TimeDurationUnit.indexOf(this.unit) == -1)
    this.unit = 'MSECS';
};

function getMultiplier(unit) {
  if (unit == 'MSECS')
    return 1.0;
  if (unit == 'SECS')
    return 1.0 * 1000.0;
  if (unit == 'MINS')
    return 60.0 * 1000.0;
  if (unit == 'HOURS')
    return 3600.0 * 1000.0;
  return 86400.0 * 1000.0;
}

function makeMillisecondsDurationObject(length) {
  var dayInMsecs = _hourInMilliseconds * 24;
  length = Math.floor(length);

  if ((length % dayInMsecs) == 0)
    return new tizen.TimeDuration(length / dayInMsecs, 'DAYS');

  return new tizen.TimeDuration(length, 'MSECS');
}

tizen.TimeDuration.prototype.getMilliseconds = function() {
  return getMultiplier(this.unit) * this.length;
};

tizen.TimeDuration.prototype.difference = function(other) {
  try {
    return makeMillisecondsDurationObject(this.getMilliseconds() -
                                          other.getMilliseconds());
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.equalsTo = function(other) {
  try {
    return this.getMilliseconds() == other.getMilliseconds();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.lessThan = function(other) {
  try {
    return this.getMilliseconds() < other.getMilliseconds();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.greaterThan = function(other) {
  try {
    return this.getMilliseconds() > other.getMilliseconds();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TimeDuration.prototype.toString = function() {
  return this.length + ' ' + this.unit;
};

tizen.TZDate = function(year, month, day, hours, minutes, seconds, milliseconds, timezone) {
  // FIXME(cmarcelo): This is a best effort to ensure that this function is
  // called as a constructor only. We may need to implement some native
  // primitive to ensure that.
  if (!this || this.constructor != tizen.TZDate)
    throw new TypeError;

  this.date_;
  this.timezone_ = timezone || tizen.time.getLocalTimezone();

  var hours = hours || 0;
  var minutes = minutes || 0;
  var seconds = seconds || 0;
  var milliseconds = milliseconds || 0;

  if (!arguments.length)
    this.date_ = new Date();
  else if (arguments.length == 1 || arguments.length == 2) {
    if (arguments[0] instanceof Date)
      this.date_ = arguments[0];
    else
      this.date_ = new Date();
    if (arguments[1])
      this.timezone_ = arguments[1];
  }
  else
    this.date_ = new Date(year, month, day, hours, minutes, seconds, milliseconds);

  if (tizen.time.getAvailableTimezones().indexOf(this.timezone_) < 0)
    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR);
};

function getTimezoneOffset(timezone, timeInMs) {
  return _sendSyncMessage('GetTimeZoneOffset', timezone, timeInMs).value;
}

function _getTimeWithOffset(date) {
  var OffsetInMilliseconds = date.getTimezoneOffset() * _minuteInMilliseconds * -1;
  return date.getTime() + OffsetInMilliseconds;
}

tizen.TZDate.prototype.getDate = function() {
  return this.date_.getDate();
};

tizen.TZDate.prototype.setDate = function(date) {
  this.date_.setDate(date);
};

tizen.TZDate.prototype.getDay = function() {
  return this.date_.getDay();
};

tizen.TZDate.prototype.getFullYear = function() {
  return this.date_.getFullYear();
};

tizen.TZDate.prototype.setFullYear = function(year) {
  this.date_.setFullYear(year);
};

tizen.TZDate.prototype.getHours = function() {
  return this.date_.getHours();
};

tizen.TZDate.prototype.setHours = function(hours) {
  this.date_.setHours(hours);
};

tizen.TZDate.prototype.getMilliseconds = function() {
  return this.date_.getMilliseconds();
};

tizen.TZDate.prototype.setMilliseconds = function(ms) {
  this.date_.setMilliseconds(ms);
};

tizen.TZDate.prototype.getMonth = function() {
  return this.date_.getMonth();
};

tizen.TZDate.prototype.setMonth = function(month) {
  this.date_.setMonth(month);
};

tizen.TZDate.prototype.getMinutes = function() {
  return this.date_.getMinutes();
};

tizen.TZDate.prototype.setMinutes = function(minutes) {
  this.date_.setMinutes(minutes);
};

tizen.TZDate.prototype.getSeconds = function() {
  return this.date_.getSeconds();
};

tizen.TZDate.prototype.setSeconds = function(seconds) {
  this.date_.setSeconds(seconds);
};

tizen.TZDate.prototype.getUTCDate = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                          _getTimeWithOffset(this.date_)) * -1));
  return d.getDate();
};

tizen.TZDate.prototype.setUTCDate = function(date) {
  this.date_.setUTCDate(date);
};

tizen.TZDate.prototype.getUTCDay = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                         _getTimeWithOffset(this.date_)) * -1));
  return d.getDay();
};

tizen.TZDate.prototype.getUTCFullYear = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                          _getTimeWithOffset(this.date_)) * -1));
  return d.getFullYear();
};

tizen.TZDate.prototype.setUTCFullYear = function(year) {
  this.date_.setUTCFullYear(year);
};

tizen.TZDate.prototype.getUTCHours = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                           _getTimeWithOffset(this.date_)) * -1));
  return d.getHours();
};

tizen.TZDate.prototype.setUTCHours = function(hours) {
  var offset_hours = getTimezoneOffset(this.timezone_, _getTimeWithOffset(this.date_)) /
                     _hourInMilliseconds;
  this.date_.setHours(hours + offset_hours);
};

tizen.TZDate.prototype.getUTCMilliseconds = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                              _getTimeWithOffset(this.date_)) * -1));
  return d.getMilliseconds();
};

tizen.TZDate.prototype.setUTCMilliseconds = function(ms) {
  this.date_.setUTCMilliseconds(ms);
};

tizen.TZDate.prototype.getUTCMinutes = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                             _getTimeWithOffset(this.date_)) * -1));
  return d.getMinutes();
};

tizen.TZDate.prototype.setUTCMinutes = function(minutes) {
  this.date_.setUTCMinutes(minutes);
};

tizen.TZDate.prototype.getUTCMonth = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                           _getTimeWithOffset(this.date_)) * -1));
  return d.getMonth();
};

tizen.TZDate.prototype.setUTCMonth = function(month) {
  this.date_.setUTCMonth(month);
};

tizen.TZDate.prototype.getUTCSeconds = function() {
  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
                                         _getTimeWithOffset(this.date_)) * -1));
  return d.getSeconds();
};

tizen.TZDate.prototype.setUTCSeconds = function(secs) {
  this.date_.setUTCSeconds(secs);
};

tizen.TZDate.prototype.getTime = function() {
  return this.date_.getTime();
};

tizen.TZDate.prototype.getTimezone = function() {
  return this.timezone_;
};

tizen.TZDate.prototype.toTimezone = function(timezone) {
  if (!timezone)
    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR);
  var d = new tizen.TZDate(new Date(this.date_.getTime()), timezone);
  return d.addDuration(new tizen.TimeDuration((getTimezoneOffset(timezone) * 1) +
                                              (getTimezoneOffset(this.timezone_) * -1)));
};

tizen.TZDate.prototype.toLocalTimezone = function() {
  return this.toTimezone(tizen.time.getLocalTimezone());
};

tizen.TZDate.prototype.toUTC = function() {
  return this.toTimezone('GMT');
};

tizen.TZDate.prototype.difference = function(other) {
  try {
    return makeMillisecondsDurationObject(this.getTime() - other.getTime());
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.equalsTo = function(other) {
  try {
    return this.getTime() == other.getTime();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.earlierThan = function(other) {
  try {
    return this.getTime() < other.getTime();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.laterThan = function(other) {
  try {
    return this.getTime() > other.getTime();
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.addDuration = function(duration) {
  try {
    var date = new tizen.TZDate(new Date(this.date_.getTime()), this.timezone_);
    date.setMilliseconds(duration.getMilliseconds() + date.getMilliseconds());
    return date;
  } catch (e) {
    _throwProperTizenException(e);
  }
};

tizen.TZDate.prototype.toLocaleDateString = function() {
  var result = _sendSyncMessage('ToDateString', this.timezone_,
                                this.date_.getTime(), '', true);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toLocaleTimeString = function() {
  var result = _sendSyncMessage('ToTimeString', this.timezone_,
                                this.date_.getTime(), '', true);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toLocaleString = function() {
  var result = _sendSyncMessage('ToString', this.timezone_,
                                this.date_.getTime(), '', true);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toDateString = function() {
  var result = _sendSyncMessage('ToDateString', this.timezone_,
                                this.date_.getTime(), '', false);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toTimeString = function() {
  var result = _sendSyncMessage('ToTimeString', this.timezone_,
                                this.date_.getTime(), '', false);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.toString = function() {
  var result = _sendSyncMessage('ToString', this.timezone_,
                                this.date_.getTime(), '', false);
  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.getTimezoneAbbreviation = function() {
  var result = _sendSyncMessage('GetTimeZoneAbbreviation', this.timezone_,
                                this.date_.getTime());

  if (result.error)
    return '';
  return result.value;
};

tizen.TZDate.prototype.secondsFromUTC = function() {
  return this.date_.getTimezoneOffset() * 60;
};

tizen.TZDate.prototype.isDST = function() {
  var result = _sendSyncMessage('IsDST', this.timezone_,
                                _getTimeWithOffset(this.date_));

  if (result.error)
    return false;
  return result.value;
};

tizen.TZDate.prototype.getPreviousDSTTransition = function() {
  var OffsetInMilliseconds = this.date_.getTimezoneOffset() * _minuteInMilliseconds * -1;
  var result = _sendSyncMessage('GetDSTTransition', this.timezone_,
                                _getTimeWithOffset(this.date_), 'NEXT_TRANSITION');

  if (result.error || result.value == 0)
    return null;
  return new tizen.TZDate(new Date(result.value - OffsetInMilliseconds), this.timezone_);
};

tizen.TZDate.prototype.getNextDSTTransition = function() {
  var OffsetInMilliseconds = this.date_.getTimezoneOffset() * _minuteInMilliseconds * -1;
  var result = _sendSyncMessage('GetDSTTransition', this.timezone_,
                                _getTimeWithOffset(this.date_), 'PREV_TRANSITION');

  if (result.error || result.value == 0)
    return null;
  return new tizen.TZDate(new Date(result.value - OffsetInMilliseconds), this.timezone_);
};
<|endoftext|>


<commit_before>/**
 * @namespace
 * UTF8 handling functions.
 */
UTF8 = new Object();
/**
 * @param {String} str Unicode string to be UTF8 encoded.
 * @throws Will throw an error if the string contains non-unicode chars.
 * @returns The UTF8 encoded string.
 */
UTF8.encode = function(str) {
    var ret = "";
    var mark = 0;

    for (var i = 0; i < str.length; i++) {
	var c = str.charCodeAt(i);

	if (c > 0x7f) {
	    if (mark != i) {
		var t = str.substring(mark, i);
		ret += t;
	    }

	    if (c >= 0x80 && c <= 0x07ff) { // 2 byte
		ret += String.fromCharCode(0xc0 | (c>>6), 0x80 | (c & 0x3f));
	    } else if ((c >= 0x0800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) { // 3 byte split by non u-chars
		ret += String.fromCharCode(0xe0 | (c>>12), 0x80 | (0x3f & (c>>6)), 0x80 | (c & 0x3f));
	    } else if (c >= 0x10000 && c <= 0x10ffff) { // 4 byte
		ret += String.fromCharCode(0xf0 | (c>>18), 0x80 | (0x3f & (c>>12)), x80 | (0x3f & (c>>6)), 0x80 | (c & 0x3f));
	    } else {
		throw("trying to encode non-unicode char " + c);
	    }

	    mark = i+1;
	}
    }

    if (mark != str.length) {
	if (mark == 0) {
	    return str;
	} else {
	    ret += str.substring(mark, str.length);
	}
    }

    return ret;
};
/**
 * @param {String} str UTF8 encoded Unicode string.
 * @throws Will throw an error if the string does not contain valid UTF8.
 * @returns The decoded Unicode string.
 */
UTF8.decode = function(str) {
    var ret = "";
    var mark = 0;

    for (var i = 0; i < str.length; i++) {
		var c = str.charCodeAt(i);

		if (c > 0x7f) {
			if (mark != i) ret += str.substring(mark, i);

			if (c >= 0xc2 && c <= 0xdf && i+1 < str.length) { // 2 byte
				var c2 = str.charCodeAt(i+1);
				ret += String.fromCharCode(((c & 0x1f) << 6) | (c2 & 0x3f));
				i++;
			} else if (c >= 0xe0 && c <= 0xef && i+2 < str.length) { // 3 byte
				var c2 = str.charCodeAt(i+1);
				var c3 = str.charCodeAt(i+2);

				ret += String.fromCharCode(((c & 0x0f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));

				i+=2;
			} else if (c >= 0xf0 && c <= 0xf4 && i+3 < str.length) { // 4 byte
				var c2 = str.charCodeAt(i+1);
				var c3 = str.charCodeAt(i+2);
				var c4 = str.charCodeAt(i+3);

				ret += String.fromCharCode(  ((c  & 0x07) << 18)
							   | ((c2 & 0x3f) << 12)
							   | ((c3 & 0x3f) << 6)
							   | (c4 & 0x3f));
				i+=3;
			} else {
				throw("Invalid UTF8 sequence at pos "+i);
			}

			mark = i+1;
		}
    }

    if (mark != str.length) {
		if (mark == 0) {
			return str;
		} else {
			ret += str.substring(mark, str.length);
		}
    }

    return ret;
};
<commit_msg>better error<commit_after>/**
 * @namespace
 * UTF8 handling functions.
 */
UTF8 = new Object();
/**
 * @param {String} str Unicode string to be UTF8 encoded.
 * @throws Will throw an error if the string contains non-unicode chars.
 * @returns The UTF8 encoded string.
 */
UTF8.encode = function(str) {
    var ret = "";
    var mark = 0;

    for (var i = 0; i < str.length; i++) {
	var c = str.charCodeAt(i);

	if (c > 0x7f) {
	    if (mark != i) {
		var t = str.substring(mark, i);
		ret += t;
	    }

	    if (c >= 0x80 && c <= 0x07ff) { // 2 byte
		ret += String.fromCharCode(0xc0 | (c>>6), 0x80 | (c & 0x3f));
	    } else if ((c >= 0x0800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) { // 3 byte split by non u-chars
		ret += String.fromCharCode(0xe0 | (c>>12), 0x80 | (0x3f & (c>>6)), 0x80 | (c & 0x3f));
	    } else if (c >= 0x10000 && c <= 0x10ffff) { // 4 byte
		ret += String.fromCharCode(0xf0 | (c>>18), 0x80 | (0x3f & (c>>12)), x80 | (0x3f & (c>>6)), 0x80 | (c & 0x3f));
	    } else {
		throw("trying to encode non-unicode char " + c);
	    }

	    mark = i+1;
	}
    }

    if (mark != str.length) {
	if (mark == 0) {
	    return str;
	} else {
	    ret += str.substring(mark, str.length);
	}
    }

    return ret;
};
/**
 * @param {String} str UTF8 encoded Unicode string.
 * @throws Will throw an error if the string does not contain valid UTF8.
 * @returns The decoded Unicode string.
 */
UTF8.decode = function(str) {
    var ret = "";
    var mark = 0;

    for (var i = 0; i < str.length; i++) {
		var c = str.charCodeAt(i);

		if (c > 0x7f) {
			if (mark != i) ret += str.substring(mark, i);

			if (c >= 0xc2 && c <= 0xdf && i+1 < str.length) { // 2 byte
				var c2 = str.charCodeAt(i+1);
				ret += String.fromCharCode(((c & 0x1f) << 6) | (c2 & 0x3f));
				i++;
			} else if (c >= 0xe0 && c <= 0xef && i+2 < str.length) { // 3 byte
				var c2 = str.charCodeAt(i+1);
				var c3 = str.charCodeAt(i+2);

				ret += String.fromCharCode(((c & 0x0f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));

				i+=2;
			} else if (c >= 0xf0 && c <= 0xf4 && i+3 < str.length) { // 4 byte
				var c2 = str.charCodeAt(i+1);
				var c3 = str.charCodeAt(i+2);
				var c4 = str.charCodeAt(i+3);

				ret += String.fromCharCode(  ((c  & 0x07) << 18)
							   | ((c2 & 0x3f) << 12)
							   | ((c3 & 0x3f) << 6)
							   | (c4 & 0x3f));
				i+=3;
			} else {
				throw("Invalid UTF8 sequence ("+c.toString()+") at pos "+i);
			}

			mark = i+1;
		}
    }

    if (mark != str.length) {
		if (mark == 0) {
			return str;
		} else {
			ret += str.substring(mark, str.length);
		}
    }

    return ret;
};
<|endoftext|>


<commit_before>var emptyArray = [];
var AssignableDisposable = require("./../AssignableDisposable");
var GetResponse = require("./../get/GetResponse");
var setGroupsIntoCache = require("./setGroupsIntoCache");
var getWithPathsAsPathMap = require("./../../get").getWithPathsAsPathMap;
var InvalidSourceError = require("./../../errors/InvalidSourceError");
var MaxRetryExceededError = require("./../../errors/MaxRetryExceededError");

/**
 * The request cycle for set.  This is responsible for requesting to dataSource
 * and allowing disposing inflight requests.
 */
module.exports = function setRequestCycle(model, observer, groups,
                                          isJSONGraph, isProgressive, count) {
    // we have exceeded the maximum retry limit.
    if (count === 1) {
        observer.onError(new MaxRetryExceededError());
        return null;
    }

    var requestedAndOptimizedPaths = setGroupsIntoCache(model, groups);
    var optimizedPaths = requestedAndOptimizedPaths.optimizedPaths;
    var requestedPaths = requestedAndOptimizedPaths.requestedPaths;
    var isMaster = model._source === undefined;

    // Local set only.  We perform a follow up get.  If performance is ever
    // a requirement simply requiring in checkCacheAndReport and use get request
    // internals.  Figured this is more "pure".
    if (isMaster) {
        return subscribeToFollowupGet(model, observer, requestedPaths,
                              isJSONGraph, isProgressive);
    }

    // Progressively output the data from the first set.
    if (isProgressive) {
        var results = getWithPathsAsPathMap(model, requestedPaths, [{}]);
        if (results.criticalError) {
            observer.onError(results.criticalError);
            return null;
        }
        observer.onNext(results.values[0]);
    }

    var currentJSONGraph = getJSONGraph(model, optimizedPaths);
    var disposable = new AssignableDisposable();

    // Sends out the setRequest.  The Queue will call the callback with the
    // JSONGraph envelope / error.
    var requestDisposable = model._request.
        // TODO: There is error handling that has not been addressed yet.

        // If disposed before this point then the sendSetRequest will not
        // further any callbacks.  Therefore, if we are at this spot, we are
        // not disposed yet.
        set(currentJSONGraph, function(error, jsonGraphEnv) {
            if (typeof error === InvalidSourceError) {
                observer.onError(error);
                return;
            }

            // TODO: This seems like there are errors with this approach, but
            // for sanity sake I am going to keep this logic in here until a
            // rethink can be done.
            var isCompleted = false;
            if (error || optimizedPaths.length === jsonGraphEnv.paths.length) {
                isCompleted = true;
            }

            // Happy case.  One request to the dataSource will fulfill the
            // required paths.
            if (isCompleted) {
                disposable.currentDisposable =
                    subscribeToFollowupGet(model, observer, requestedPaths,
                                          isJSONGraph, isProgressive);
            }

            // TODO: The unhappy case.  I am unsure how this can even be
            // achieved.
            else {
                // We need to restart the setRequestCycle.
                setRequestCycle(model, observer, groups, isJSONGraph,
                                isProgressive, count + 1);
            }
        });

    // Sets the current disposable as the requestDisposable.
    disposable.currentDisposable = requestDisposable;

    return disposable;
};

function getJSONGraph(model, optimizedPaths) {
    var boundPath = model._path;
    var envelope = {};
    model._path = emptyArray;
    model._getPathValuesAsJSONG(model._materialize().withoutDataSource(), optimizedPaths, [envelope]);
    model._path = boundPath;

    return envelope;
}

function subscribeToFollowupGet(model, observer, requestedPaths, isJSONGraph,
                               isProgressive) {

    // Creates a new response and subscribes to it with the original observer.
    // Also sets forceCollect to true, incase the operation is synchronous and
    // exceeds the cache limit size
    var response = new GetResponse(model, requestedPaths, isJSONGraph,
                                   isProgressive, true);
    return response.subscribe(observer);
}
<commit_msg>Revert "Update setRequestCycle.js"<commit_after>var emptyArray = [];
var AssignableDisposable = require("./../AssignableDisposable");
var GetResponse = require("./../get/GetResponse");
var setGroupsIntoCache = require("./setGroupsIntoCache");
var getWithPathsAsPathMap = require("./../../get").getWithPathsAsPathMap;
var InvalidSourceError = require("./../../errors/InvalidSourceError");
var MaxRetryExceededError = require("./../../errors/MaxRetryExceededError");

/**
 * The request cycle for set.  This is responsible for requesting to dataSource
 * and allowing disposing inflight requests.
 */
module.exports = function setRequestCycle(model, observer, groups,
                                          isJSONGraph, isProgressive, count) {
    // we have exceeded the maximum retry limit.
    if (count === 10) {
        throw new MaxRetryExceededError();
    }

    var requestedAndOptimizedPaths = setGroupsIntoCache(model, groups);
    var optimizedPaths = requestedAndOptimizedPaths.optimizedPaths;
    var requestedPaths = requestedAndOptimizedPaths.requestedPaths;
    var isMaster = model._source === undefined;

    // Local set only.  We perform a follow up get.  If performance is ever
    // a requirement simply requiring in checkCacheAndReport and use get request
    // internals.  Figured this is more "pure".
    if (isMaster) {
        return subscribeToFollowupGet(model, observer, requestedPaths,
                              isJSONGraph, isProgressive);
    }

    // Progressively output the data from the first set.
    if (isProgressive) {
        var results = getWithPathsAsPathMap(model, requestedPaths, [{}]);
        if (results.criticalError) {
            observer.onError(results.criticalError);
            return null;
        }
        observer.onNext(results.values[0]);
    }

    var currentJSONGraph = getJSONGraph(model, optimizedPaths);
    var disposable = new AssignableDisposable();

    // Sends out the setRequest.  The Queue will call the callback with the
    // JSONGraph envelope / error.
    var requestDisposable = model._request.
        // TODO: There is error handling that has not been addressed yet.

        // If disposed before this point then the sendSetRequest will not
        // further any callbacks.  Therefore, if we are at this spot, we are
        // not disposed yet.
        set(currentJSONGraph, function(error, jsonGraphEnv) {
            if (typeof error === InvalidSourceError) {
                observer.onError(error);
                return;
            }

            // TODO: This seems like there are errors with this approach, but
            // for sanity sake I am going to keep this logic in here until a
            // rethink can be done.
            var isCompleted = false;
            if (error || optimizedPaths.length === jsonGraphEnv.paths.length) {
                isCompleted = true;
            }

            // Happy case.  One request to the dataSource will fulfill the
            // required paths.
            if (isCompleted) {
                disposable.currentDisposable =
                    subscribeToFollowupGet(model, observer, requestedPaths,
                                          isJSONGraph, isProgressive);
            }

            // TODO: The unhappy case.  I am unsure how this can even be
            // achieved.
            else {
                // We need to restart the setRequestCycle.
                setRequestCycle(model, observer, groups, isJSONGraph,
                                isProgressive, count + 1);
            }
        });

    // Sets the current disposable as the requestDisposable.
    disposable.currentDisposable = requestDisposable;

    return disposable;
};

function getJSONGraph(model, optimizedPaths) {
    var boundPath = model._path;
    var envelope = {};
    model._path = emptyArray;
    model._getPathValuesAsJSONG(model._materialize().withoutDataSource(), optimizedPaths, [envelope]);
    model._path = boundPath;

    return envelope;
}

function subscribeToFollowupGet(model, observer, requestedPaths, isJSONGraph,
                               isProgressive) {

    // Creates a new response and subscribes to it with the original observer.
    // Also sets forceCollect to true, incase the operation is synchronous and
    // exceeds the cache limit size
    var response = new GetResponse(model, requestedPaths, isJSONGraph,
                                   isProgressive, true);
    return response.subscribe(observer);
}
<|endoftext|>


<commit_before>/**
 * ExceptionOccurrenceController
 *
 * @module      :: Controller
 * @description	:: A set of functions called `actions`.
 *
 *                 Actions contain code telling Sails how to respond to a certain type of request.
 *                 (i.e. do stuff, then send some JSON, show an HTML page, or redirect to another URL)
 *
 *                 You can configure the blueprint URLs which trigger these actions (`config/controllers.js`)
 *                 and/or override them with custom routes (`config/routes.js`)
 *
 *                 NOTE: The code you write here supports both HTTP and Socket.io automatically.
 *
 * @docs        :: http://sailsjs.org/#!documentation/controllers
 */

var _ = require('lodash');
var deferred = require('deferred');
var uaParser = require('ua-parser');
var moment = require('moment');
var email = require('../../lib/mail');

module.exports = {

  /**
   * Overrides for the settings in `config/controllers.js`
   * (specific to ExceptionOccurrenceController)
   */
  _config: {},

  'jsFail': function(req, res) {
    var data;

    var respond = function() {
      var img = new Buffer('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', 'base64');
      res.contentType = 'image/gif';
      res.send(img);
    };

    try {
      data = JSON.parse(req.query.json);
    } catch(e) {
      respond();
      return;
    }

    module.exports._create(data, respond);
  },

  _create: function(json, cb) {
    var exceptions = [];
    var exceptionOccurrences = [];

    json.FailOccurrences.forEach(function(failOccurrence) {
      failOccurrence.Exceptions.forEach(function(aException) {
        var exception = {
          type: json.ApplicationType,
          stack: aException.StackTrace || '',
          name: aException.ExceptionMessage,
          appId: json.ID,
          username: failOccurrence.User
        };

        exceptions.push(exception);

        var exceptionOccurrence = {
          type: json.ApplicationType,
          name: aException.ExceptionMessage,
          appId: json.ID,
          username: failOccurrence.User,
          exceptionId: null,
          path: failOccurrence.XHRRequestURL || failOccurrence.RequestUrl
        };

        var client = uaParser.parse(failOccurrence.UserAgent);
        exceptionOccurrence.client_ua = client.ua.toString();
        exceptionOccurrence.client_os = client.os.toString();

        exceptionOccurrences.push(exceptionOccurrence);
      });
    });

    var insertException = function(exception, i) {
      return Exception.findOneByName(exception.name).
        then(function(aException) {
          if (!aException) {
            return Exception.create(exception);
          }
          return aException;
        }).
        catch(function(err) {
          // Ignore E11000 duplicate key error
          if (err.code == '11000') {
            return Exception.findOneByName(exception.name);
          }
        }).
        then(function(exception) {
          var exceptionOccurrence = exceptionOccurrences[i];
          exceptionOccurrence.exceptionId = exception.id;
          return ExceptionOccurrence.create(exceptionOccurrence);
        });
    };

    if (json.ID !== 'demo') {
      Application.findOne(json.ID).
        done(function(app) {
          if (!app.reportFailureEmail) return;

          email.sendNotificationEmail(app.reportFailureEmail, null, {
            appId: json.ID
          });
        });
    }

    deferred.map(exceptions, insertException)(function() {
      cb();
    }).
    catch(function(err) {
      sails.log.error(err);
      cb(err);
    });
  },

  'create': function(req, res) {
    // TODO: First , let's verify the payload's integrity?

    var body = req.body;

    module.exports._create(body, function(err) {
      if (err) {
        res.send({
          success: false,
          error: err.toString()
        });
      } else {
        res.send({
          success: true
        });
      }
    });
  },

  'filterByFailure': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

//    sails-mongo do not support `aggregate`
//    and we have no access to sails-mongo adpater's connection,
//    so we have to open connection to mongodb directly

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { name: '$name', type: '$type', exceptionId: '$exceptionId' },
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                name: '$_id.name',
                type: '$_id.type',
                id: '$_id.exceptionId',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
//          the simple approach is using `count distinct`,
//          but mongo throw exception `distinct too big` if dataset is bigger than 16MB,
//          so we prefer aggregation
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { name: '$name', type: '$type', exceptionId: '$exceptionId' }
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByUser': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$username',
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                username: '$_id',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$username'
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByUrl': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$path',
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                path: '$_id',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$path'
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByClient': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { client_ua: '$client_ua', client_os: '$client_os' },
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                client_ua: '$_id.client_ua',
                client_os: '$_id.client_os',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { client_ua: '$client_ua', client_os: '$client_os' }
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByType': function(req, res) {

    var dateRange = {
      begin: new Date(+req.query.begin),
      end: new Date(+req.query.end)
    };
    var $match = {
      appId: req.query.appId,
      createdAt: {
        $gt: dateRange.begin,
        $lt: dateRange.end
      }
    };

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: {
                  year : { $year : "$createdAt" },
                  month : { $month : "$createdAt" },
                  day : { $dayOfMonth : "$createdAt" },
                  type: '$type'
                },
                occurrence: { $sum: 1 }
              }
            },

            { $sort: { '_id.type': -1, '_id.year': 1, '_id.month': 1, '_id.day': 1 } },

            {
              $group: {
                _id: {
                  type: '$_id.type'
                },
                occurrenceSeries: { $push: '$occurrence' },
                yearSeries: { $push: '$_id.year' },
                monthSeries: { $push: '$_id.month' },
                daySeries: { $push: '$_id.day' }
              }
            },

            {
              $project: {
                _id: 0,
                type: '$_id.type',
                occurrenceSeries: 1,
                yearSeries: 1,
                monthSeries: 1,
                daySeries: 1
              }
            }
          ],

          {},

          cb);
      };

      var defAggregate = deferred.promisify(aggregate);

      defAggregate().
        then(function(resp) {
          if (resp.length > 0) {
            var index = 0;
            var i = 0;

            for (var date = moment(dateRange.begin).startOf('day'); ;i++) {
              if (!date.isSame(moment([resp[0].yearSeries[index], resp[0].monthSeries[index] - 1, resp[0].daySeries[index]]), 'day')) {
                resp.forEach(function(item) {
                  item.occurrenceSeries.splice(i, 0, 0);
                  item.yearSeries.splice(i, 0, date.year());
                  item.monthSeries.splice(i, 0, date.month() + 1);
                  item.daySeries.splice(i, 0, date.date());
                });
              }
              index++;
              if (date.isSame(moment(dateRange.end).startOf('day'), 'day')) break;
              date.add('d', 1);
            }
          }

          res.send(resp);
        }, function(err) {
          res.serverError(err);
        });

    });
  }

};
<commit_msg>Fixed<commit_after>/**
 * ExceptionOccurrenceController
 *
 * @module      :: Controller
 * @description	:: A set of functions called `actions`.
 *
 *                 Actions contain code telling Sails how to respond to a certain type of request.
 *                 (i.e. do stuff, then send some JSON, show an HTML page, or redirect to another URL)
 *
 *                 You can configure the blueprint URLs which trigger these actions (`config/controllers.js`)
 *                 and/or override them with custom routes (`config/routes.js`)
 *
 *                 NOTE: The code you write here supports both HTTP and Socket.io automatically.
 *
 * @docs        :: http://sailsjs.org/#!documentation/controllers
 */

var _ = require('lodash');
var deferred = require('deferred');
var uaParser = require('ua-parser');
var moment = require('moment');
var email = require('../../lib/mail');

module.exports = {

  /**
   * Overrides for the settings in `config/controllers.js`
   * (specific to ExceptionOccurrenceController)
   */
  _config: {},

  'jsFail': function(req, res) {
    var data;

    var respond = function() {
      var img = new Buffer('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', 'base64');
      res.contentType = 'image/gif';
      res.send(img);
    };

    try {
      data = JSON.parse(req.query.json);
    } catch(e) {
      respond();
      return;
    }

    module.exports._create(data, respond);
  },

  _create: function(json, cb) {
    var exceptions = [];
    var exceptionOccurrences = [];

    json.FailOccurrences.forEach(function(failOccurrence) {
      failOccurrence.Exceptions.forEach(function(aException) {
        var exception = {
          type: json.ApplicationType,
          stack: aException.StackTrace || '',
          name: aException.ExceptionMessage,
          appId: json.ID,
          username: failOccurrence.User
        };

        exceptions.push(exception);

        var exceptionOccurrence = {
          type: json.ApplicationType,
          name: aException.ExceptionMessage,
          appId: json.ID,
          username: failOccurrence.User,
          exceptionId: null,
          path: failOccurrence.XHRRequestURL || failOccurrence.RequestUrl
        };

        var client = uaParser.parse(failOccurrence.UserAgent);
        exceptionOccurrence.client_ua = client.ua.toString();
        exceptionOccurrence.client_os = client.os.toString();

        exceptionOccurrences.push(exceptionOccurrence);
      });
    });

    var insertException = function(exception, i) {
      return Exception.findOneByName(exception.name).
        then(function(aException) {
          if (!aException) {
            return Exception.create(exception);
          }
          return aException;
        }).
        catch(function(err) {
          // Ignore E11000 duplicate key error
          if (err.code == '11000') {
            return Exception.findOneByName(exception.name);
          }
        }).
        then(function(exception) {
          var exceptionOccurrence = exceptionOccurrences[i];
          exceptionOccurrence.exceptionId = exception.id;
          return ExceptionOccurrence.create(exceptionOccurrence);
        });
    };

    if (json.ID !== 'demo') {
      Application.findOne(json.ID).
        done(function(err, app) {
          if (err || !app || app.reportFailureEmail) return;

          email.sendNotificationEmail(app.reportFailureEmail, null, {
            appId: json.ID
          });
        });
    }

    deferred.map(exceptions, insertException)(function() {
      cb();
    }).
    catch(function(err) {
      sails.log.error(err);
      cb(err);
    });
  },

  'create': function(req, res) {
    // TODO: First , let's verify the payload's integrity?

    var body = req.body;

    module.exports._create(body, function(err) {
      if (err) {
        res.send({
          success: false,
          error: err.toString()
        });
      } else {
        res.send({
          success: true
        });
      }
    });
  },

  'filterByFailure': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

//    sails-mongo do not support `aggregate`
//    and we have no access to sails-mongo adpater's connection,
//    so we have to open connection to mongodb directly

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { name: '$name', type: '$type', exceptionId: '$exceptionId' },
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                name: '$_id.name',
                type: '$_id.type',
                id: '$_id.exceptionId',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
//          the simple approach is using `count distinct`,
//          but mongo throw exception `distinct too big` if dataset is bigger than 16MB,
//          so we prefer aggregation
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { name: '$name', type: '$type', exceptionId: '$exceptionId' }
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByUser': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$username',
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                username: '$_id',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$username'
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByUrl': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$path',
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                path: '$_id',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: '$path'
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByClient': function(req, res) {

    var limit = parseInt(req.query.limit || 10, 10);
    var skip = parseInt(req.query.skip || 0, 10);

    var $match = {
      appId: req.query.appId
    };

    if (typeof req.query.type != 'undefined') {
      $match.type = req.query.type;
    }

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(options, cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { client_ua: '$client_ua', client_os: '$client_os' },
                occurrence: { $sum: 1 },
                createdAt: { $max: '$createdAt' }
              }
            },

            { $sort: { occurrence: -1 } },

            { $skip : options.skip },

            { $limit : options.limit },

            {
              $project: {
                _id: 0,
                client_ua: '$_id.client_ua',
                client_os: '$_id.client_os',
                latestOccurrenceAt: '$createdAt',
                occurrence: 1
              }
            }
          ],

          {},

          cb);
      };

      var countTotal = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: { client_ua: '$client_ua', client_os: '$client_os' }
              }
            },

            {
              $group: {
                _id: 0,
                total: { $sum: 1 }
              }
            }
          ], {}, cb);
      };

      var defAggregate = deferred.promisify(aggregate);
      var defCountTotal = deferred.promisify(countTotal);

      deferred(defAggregate({ skip: skip, limit: limit }), defCountTotal()).
        then(function(resp) {
          var total = resp[1];
          total = total.length > 0 ? total[0].total : 0;

          res.send({
            list: resp[0],
            total: total
          });
        }, function(err) {
          res.serverError(err);
        });

    });
  },

  'filterByType': function(req, res) {

    var dateRange = {
      begin: new Date(+req.query.begin),
      end: new Date(+req.query.end)
    };
    var $match = {
      appId: req.query.appId,
      createdAt: {
        $gt: dateRange.begin,
        $lt: dateRange.end
      }
    };

    sails.adapters['sails-mongo'].native('exceptionoccurrence', function(err, collection) {
      if (err) return res.serverError(err);

      var aggregate = function(cb) {
        collection.aggregate(
          [
            { $match: $match },

            {
              $group: {
                _id: {
                  year : { $year : "$createdAt" },
                  month : { $month : "$createdAt" },
                  day : { $dayOfMonth : "$createdAt" },
                  type: '$type'
                },
                occurrence: { $sum: 1 }
              }
            },

            { $sort: { '_id.type': -1, '_id.year': 1, '_id.month': 1, '_id.day': 1 } },

            {
              $group: {
                _id: {
                  type: '$_id.type'
                },
                occurrenceSeries: { $push: '$occurrence' },
                yearSeries: { $push: '$_id.year' },
                monthSeries: { $push: '$_id.month' },
                daySeries: { $push: '$_id.day' }
              }
            },

            {
              $project: {
                _id: 0,
                type: '$_id.type',
                occurrenceSeries: 1,
                yearSeries: 1,
                monthSeries: 1,
                daySeries: 1
              }
            }
          ],

          {},

          cb);
      };

      var defAggregate = deferred.promisify(aggregate);

      defAggregate().
        then(function(resp) {
          if (resp.length > 0) {
            var index = 0;
            var i = 0;

            for (var date = moment(dateRange.begin).startOf('day'); ;i++) {
              if (!date.isSame(moment([resp[0].yearSeries[index], resp[0].monthSeries[index] - 1, resp[0].daySeries[index]]), 'day')) {
                resp.forEach(function(item) {
                  item.occurrenceSeries.splice(i, 0, 0);
                  item.yearSeries.splice(i, 0, date.year());
                  item.monthSeries.splice(i, 0, date.month() + 1);
                  item.daySeries.splice(i, 0, date.date());
                });
              }
              index++;
              if (date.isSame(moment(dateRange.end).startOf('day'), 'day')) break;
              date.add('d', 1);
            }
          }

          res.send(resp);
        }, function(err) {
          res.serverError(err);
        });

    });
  }

};
<|endoftext|>