<commit_before>var socket;
var grid;
var user;
var users;
var canvasSize = 700; // Same as on server
var nrOfRows = 15; // Same as on server
var cellWidth = cellHeight = canvasSize / nrOfRows;

var offset = 4; // Small offset for smaller user box

var thisUserColor = '#e67e22';
var othersColor = '#c0392b';

function setup() {
    createCanvas(canvasSize, canvasSize);

    socket = io.connect();

    user = {
        i: 0,
        j: 0,
        name: 'SomeName'
    }

    socket.emit('start', user);

    // Getting the grid && setting the user.id
    socket.on('theGrid', function(_grid){
        grid = _grid;
        user.id = socket.id;
        loop();
    });

    socket.on('tick', function(_users){
        users = _users;
    });

    noLoop();
}

function draw() {
    background('#3498db');

    if(grid){
        drawGrid();
    }

    if(users){
        drawUsers();
    }

    // Drawing this user
    drawAUser(user, thisUserColor);

    socket.emit('userNewLocation', user);
}

function drawGrid(){
    grid.forEach(cell => {

        noStroke();
        if(cell.visited){
            fill('#3498db');
            rect(cell.x, cell.y, cell.size, cell.size);
        }

        // Draw final cell
        if(cell.final){
            fill(255, 0, 255);
            rect(cell.x, cell.y, cell.size, cell.size);
        }

        stroke('#000000');
        strokeWeight(2);
        // The top wall
        if(cell.walls[0]){
            line(cell.x, cell.y, cell.x + cell.size, cell.y);
        }

        // The right wall
        if(cell.walls[1]){
            line(cell.x + cell.size, cell.y, cell.x + cell.size, cell.y + cell.size);
        }

        // The bottom wall
        if(cell.walls[2]){
            line(cell.x, cell.y + cell.size, cell.x + cell.size, cell.y + cell.size);
        }

        // The left wall
        if(cell.walls[3]){
            line(cell.x, cell.y, cell.x, cell.y + cell.size);
        }

    });
}

function drawUsers(){
    users.forEach(user => {
        if(user.id !== socket.id) {// only draw the other users
            drawAUser(user, othersColor);
        }
    });
}

function drawAUser(_user, color){
    noStroke();
    fill(color);
    ellipse(_user.i * cellWidth + cellWidth/2, _user.j * cellHeight + cellHeight/2, cellWidth - 2*offset, cellHeight - 2*offset);
}

function keyPressed() {

    // Check if that cell exists and if there isn't a wall opposite to the key pressed
    if(keyCode === UP_ARROW){
        if(grid[getIndex(user.i, user.j - 1)] && !grid[getIndex(user.i, user.j - 1)].walls[2]){
            user.j--;
        }
    }

    if(keyCode === RIGHT_ARROW){
        if(grid[getIndex(user.i + 1, user.j)] && !grid[getIndex(user.i + 1, user.j)].walls[3]){
            user.i++;
        }
    }

    if(keyCode === DOWN_ARROW){
        if(grid[getIndex(user.i, user.j + 1)] && !grid[getIndex(user.i, user.j + 1)].walls[0]){
            user.j++;
        }
    }

    if(keyCode === LEFT_ARROW){
        if(grid[getIndex(user.i - 1, user.j)] && !grid[getIndex(user.i - 1, user.j)].walls[1]){
            user.i--;
        }
    }
}

function getIndex(i, j){
    // Same function as on the server
    if(i < 0 || j < 0 || i > nrOfRows - 1 || j > nrOfRows - 1)
        return -1;

    return j + i * nrOfRows;
}<commit_msg>checkIfUserWon<commit_after>var socket;
var grid;
var user;
var users;
var canvasSize = 700; // Same as on server
var nrOfRows = 15; // Same as on server
var cellWidth = cellHeight = canvasSize / nrOfRows;

var offset = 4; // Small offset for smaller user box

var thisUserColor = '#e67e22';
var othersColor = '#c0392b';

function setup() {
    createCanvas(canvasSize, canvasSize);

    socket = io.connect();

    user = {
        i: 0,
        j: 0,
        name: 'SomeName'
    }

    socket.emit('start', user);

    // Getting the grid && setting the user.id
    socket.on('theGrid', function(_grid){
        grid = _grid;
        user.id = socket.id;
        loop();
    });

    socket.on('tick', function(_users){
        users = _users;
    });

    noLoop();
}

function draw() {
    background('#3498db');

    if(grid){
        drawGrid();
    }

    if(users){
        drawUsers();
    }

    // Drawing this user
    drawAUser(user, thisUserColor);

    socket.emit('userNewLocation', user);
}

function drawGrid(){
    grid.forEach(cell => {

        noStroke();
        if(cell.visited){
            fill('#3498db');
            rect(cell.x, cell.y, cell.size, cell.size);
        }

        // Draw final cell
        if(cell.final){
            fill(255, 0, 255);
            rect(cell.x, cell.y, cell.size, cell.size);
        }

        stroke('#000000');
        strokeWeight(2);
        // The top wall
        if(cell.walls[0]){
            line(cell.x, cell.y, cell.x + cell.size, cell.y);
        }

        // The right wall
        if(cell.walls[1]){
            line(cell.x + cell.size, cell.y, cell.x + cell.size, cell.y + cell.size);
        }

        // The bottom wall
        if(cell.walls[2]){
            line(cell.x, cell.y + cell.size, cell.x + cell.size, cell.y + cell.size);
        }

        // The left wall
        if(cell.walls[3]){
            line(cell.x, cell.y, cell.x, cell.y + cell.size);
        }

    });
}

function drawUsers(){
    users.forEach(user => {
        if(user.id !== socket.id) {// only draw the other users
            drawAUser(user, othersColor);
        }
    });
}

function drawAUser(_user, color){
    noStroke();
    fill(color);
    ellipse(_user.i * cellWidth + cellWidth/2, _user.j * cellHeight + cellHeight/2, cellWidth - 2*offset, cellHeight - 2*offset);
}

function keyPressed() {

    // Check if that cell exists and if there isn't a wall opposite to the key pressed
    if(keyCode === UP_ARROW){
        if(grid[getIndex(user.i, user.j - 1)] && !grid[getIndex(user.i, user.j - 1)].walls[2]){
            user.j--;
        }
    }

    if(keyCode === RIGHT_ARROW){
        if(grid[getIndex(user.i + 1, user.j)] && !grid[getIndex(user.i + 1, user.j)].walls[3]){
            user.i++;
        }
    }

    if(keyCode === DOWN_ARROW){
        if(grid[getIndex(user.i, user.j + 1)] && !grid[getIndex(user.i, user.j + 1)].walls[0]){
            user.j++;
        }
    }

    if(keyCode === LEFT_ARROW){
        if(grid[getIndex(user.i - 1, user.j)] && !grid[getIndex(user.i - 1, user.j)].walls[1]){
            user.i--;
        }
    }

    checkIfUserWon(user.i, user.j);
}

function getIndex(i, j){
    // Same function as on the server
    if(i < 0 || j < 0 || i > nrOfRows - 1 || j > nrOfRows - 1)
        return -1;

    return j + i * nrOfRows;
}

function checkIfUserWon(i, j) {
    if(grid[getIndex(i, j)].final){
        console.log('wonnnnnnn');
    }
}<|endoftext|>


<commit_before>// stub for a proper class
var maki = {
    angular: angular.module('maki', ['ngRoute', 'ngResource'])
  , socket: null
  , sockets: {
      disconnect: function() {
        maki.socket.onclose = null;
        maki.socket.onmessage = null;
        maki.socket = null;
      },
      connect: function() {
        if (maki.socket) {
          maki.sockets.disconnect();
        }

        var retryTimes = [1000, 5000, 10000, 30000, 60000, 120000, 300000, 600000, 86400000]; //in ms
        var retryIndex = 0;

        var path = 'ws://' + window.location.host + window.location.pathname;
        maki.socket = new WebSocket( path );
        maki.socket.onclose = function onClose() {
          console.log('lost connection, reconnect... ');
          // TODO: randomize reconnection timeout buffer
          if (retryIndex < retryTimes.length) {
            console.log('retrying in ' + retryTimes[ retryIndex ] + 'ms');
            setTimeout( maki.sockets.connect , retryTimes[ retryIndex ] );
          } else {
            console.log('failed for the last time.  not attempting again.');
            retryTimes[ retryIndex++ ];
          }
        };
        maki.socket.onmessage = function onMessage(msg) {
          try {
            var data = JSON.parse( msg.data );
          } catch (e) {
            var data = {};
          }

          console.log(data);
          // experimental JSON-RPC implementation
          if (data.jsonrpc === '2.0') {
            switch (data.method) {
              case 'ping':
                console.log('was ping, sending response');
                maki.socket.send(JSON.stringify({
                  'jsonrpc': '2.0',
                  'result': 'pong',
                  'id': data.id
                }));
              break;
            }
          }
        };
      }
    }
};

maki.angular.config(function($routeProvider, $locationProvider, $resourceProvider) {

  var pages = [];
  $.ajax({
    async: false,
    type: 'OPTIONS',
    url: '/',
    success: function(data) {
      pages = data;
    }
  });

  pages.forEach(function(page) {
    $routeProvider.when.apply( this , [ page.path , {
      template: function( params ) {
        var self = this;
        var obj = {};

        $.ajax({
            url: self.location
          , success: function( results ) {
              obj[ page.name ] = results;
            }
          , async: false
        });

        // TODO: subscribe

        return Templates[ page.template ]( obj );
      }
    } ] );
    $routeProvider.otherwise({
      template: function() {
        return Templates['404']();
      }
    });
  });

  // use the HTML5 History API
  $locationProvider.html5Mode(true);

});

maki.angular.controller('mainController', function( $scope ) {
  // TODO: use pubsub
  /*/$scope.$on('$locationChangeStart', function(event) {
    maki.sockets.connect();
  });/**/
  $scope.$on('$locationChangeSuccess', function(event) {
    maki.sockets.connect();
  });
}).directive('tooltipped', function() {
  return {
      restrict: 'C'
    , link: function( scope , element ) {
        $( element ).tooltip({
          container: 'body'
        });
      }
  }
}).directive('code', function() {
  return {
    restrict: 'E',
    link: function( scope , element ) {
      $( element ).each(function(i, block) {
        hljs.highlightBlock(block);
      });
    }
  }
}).directive('headroom', function() {
  return {
    restrict: 'EA',
    scope: {
      tolerance: '=',
      offset: '=',
      classes: '='
    },
    link: function(scope, element) {
      var options = {};
      angular.forEach(Headroom.options, function(value, key) {
        options[key] = scope[key] || Headroom.options[key];
      });
      var headroom = new Headroom(element[0], options);
      headroom.init();
      scope.$on('destroy', function() {
        headroom.destroy();
      });
    }
  };
});
maki.angular.controller('headerController', function( $scope , $location ) {
  $scope.isActive = function (viewLocation) {
    return viewLocation === $location.path();
  };
});
<commit_msg>Correctly close websockets where possible.<commit_after>// stub for a proper class
var maki = {
    angular: angular.module('maki', ['ngRoute', 'ngResource'])
  , socket: null
  , sockets: {
      disconnect: function() {
        if (maki.socket) {
          // unbind onclose, onmessage
          maki.socket.onclose = null;
          maki.socket.onmessage = null;

          // must happen after onclose event is unbound
          maki.socket.close();
          maki.socket = null;
        }
      },
      connect: function() {
        maki.sockets.disconnect();

        var retryTimes = [1000, 5000, 10000, 30000, 60000, 120000, 300000, 600000, 86400000]; //in ms
        var retryIndex = 0;

        var path = 'ws://' + window.location.host + window.location.pathname;
        maki.socket = new WebSocket( path );
        maki.socket.onclose = function onClose() {
          console.log('lost connection, reconnect... ');
          // TODO: randomize reconnection timeout buffer
          if (retryIndex < retryTimes.length) {
            console.log('retrying in ' + retryTimes[ retryIndex ] + 'ms');
            setTimeout( maki.sockets.connect , retryTimes[ retryIndex ] );
          } else {
            console.log('failed for the last time.  not attempting again.');
            retryTimes[ retryIndex++ ];
          }
        };
        maki.socket.onmessage = function onMessage(msg) {
          try {
            var data = JSON.parse( msg.data );
          } catch (e) {
            var data = {};
          }

          console.log(data);
          // experimental JSON-RPC implementation
          if (data.jsonrpc === '2.0') {
            switch (data.method) {
              case 'ping':
                console.log('was ping, sending response');
                maki.socket.send(JSON.stringify({
                  'jsonrpc': '2.0',
                  'result': 'pong',
                  'id': data.id
                }));
              break;
            }
          }
        };
      }
    }
};

maki.angular.config(function($routeProvider, $locationProvider, $resourceProvider) {

  var pages = [];
  $.ajax({
    async: false,
    type: 'OPTIONS',
    url: '/',
    success: function(data) {
      pages = data;
    }
  });

  pages.forEach(function(page) {
    $routeProvider.when.apply( this , [ page.path , {
      template: function( params ) {
        var self = this;
        var obj = {};

        $.ajax({
            url: self.location
          , success: function( results ) {
              obj[ page.name ] = results;
            }
          , async: false
        });

        // TODO: subscribe

        return Templates[ page.template ]( obj );
      }
    } ] );
    $routeProvider.otherwise({
      template: function() {
        return Templates['404']();
      }
    });
  });

  // use the HTML5 History API
  $locationProvider.html5Mode(true);

});

maki.angular.controller('mainController', function( $scope ) {
  // TODO: use pubsub
  $scope.$on('$locationChangeStart', function(event) {
    maki.sockets.disconnect();
  });
  $scope.$on('$locationChangeSuccess', function(event) {
    maki.sockets.connect();
  });
}).directive('tooltipped', function() {
  return {
      restrict: 'C'
    , link: function( scope , element ) {
        $( element ).tooltip({
          container: 'body'
        });
      }
  }
}).directive('code', function() {
  return {
    restrict: 'E',
    link: function( scope , element ) {
      $( element ).each(function(i, block) {
        hljs.highlightBlock(block);
      });
    }
  }
}).directive('headroom', function() {
  return {
    restrict: 'EA',
    scope: {
      tolerance: '=',
      offset: '=',
      classes: '='
    },
    link: function(scope, element) {
      var options = {};
      angular.forEach(Headroom.options, function(value, key) {
        options[key] = scope[key] || Headroom.options[key];
      });
      var headroom = new Headroom(element[0], options);
      headroom.init();
      scope.$on('destroy', function() {
        headroom.destroy();
      });
    }
  };
});
maki.angular.controller('headerController', function( $scope , $location ) {
  $scope.isActive = function (viewLocation) {
    return viewLocation === $location.path();
  };
});
<|endoftext|>


<commit_before>function setPage(newPage) {
	$(".page.open-page").removeClass("open-page");
	if ($("#" + newPage).length != 0) {
		// yay, it exists. go to it
		$("#" + newPage).addClass("open-page");
		if ($(".upsell[data-feature=" + newPage + "]").length == 0) {
			$("#" + newPage).trigger("tabOpened");
		}
		window.location.hash = newPage;
	} else {
		// fetch it!
		window.page.showLoading();
		window.api.get("pageHandler/fetchPage/" + newPage, function(response) {
			// check for error
			if (response.status === "error") {
				console.error("Error loading page!");
				return;
			}

			// and load it
			var $page = $(response);

			var $scripts = $page.children("#page-scripts");
			$("head").append($scripts);

			var $styles = $page.children("#page-styles");
			$("head").append($styles);

			var $modals = $page.children("#page-modals");
			$("body").append($modals);

			var $upsell = $page.children("#page-upsell");
				$upsell.attr("id", newPage + "-upsell");
				$upsell.addClass("upsell");
				$upsell.addClass("row");
				$upsell.attr("data-feature", newPage);
			var $content = $page.children("#page-content");
				$content.attr("id", newPage);
				$content.addClass("page");
				if (window.page.features.indexOf(newPage) == -1) {
					$content.append($upsell);
				}
			$(".pages").append($content);

			upsellTrigger();
			window.page.hideLoading();
			setPage(newPage); // and show it
		});
	}
}

window.page = {
	features: [],
	loadTimeout: null,
	loadWarnTimeout: null
};

window.page.getBasePath = function() {
	return $("#basePath").text();
};

window.page.showLoading = function() {
	window.page.loadTimeout = setTimeout(function() {
		$(".loadOverlay").addClass("showLoadOverlay");
		$(".loadWarn").removeClass("showingLoadWarn");
		window.page.loadWarnTimeout = setTimeout(function() {
			console.warn("Loading is taking time...");
			$(".loadWarn").addClass("showingLoadWarn");
		}, 10000);
	}, 400);
};

window.page.hideLoading = function() {
	$(".loadOverlay").removeClass("showLoadOverlay");
	if (window.page.loadTimeout != null) {
		clearTimeout(window.page.loadTimeout);
	}
	if (window.page.loadWarnTimeout != null) {
		clearTimeout(window.page.loadWarnTimeout);
	}
	window.page.loadTimeout = 0;
	window.page.loadWarnTimeout = 0;
};

window.page.getFeatures = function(callback) {
	window.api.get("features/get/", function(data) {
		callback(data.features);
	});
};

window.page.addFeature = function(feature, callback) {
	window.api.post("features/add/", { feature: feature }, function(data) {
		callback();
	});
};

window.page.getOpenPage = function() {
	return $(".page.open-page").attr("id");
};

// default color is #333333 and complement is #222222
window.page.setColor = function(color) {
	var complements = {
		"#333333": "#222222",
		"#990f0f": "#880e0e",
		"#0f993b": "#0e882a",
		"#1c19c2": "#0b08b1",
		"#c93e3e": "#b82d2d",
		"#37c464": "#26b353",
		"#3834fa": "#2723e9",
		"#00c8d8": "#00b7c7"
	};

	var complement = complements[color];

	window.page.color = color;
	window.page.complement = complement;

	$(".tabs").css("background-color", color);
	$(".navbar-default").css("background-color", color);
	$("#page-pref-btn").css("background-color", color);
	$(".navbar-default .dropdown-menu").css("background-color", color);

	$(".tabs").css("border-right", "solid 1px " + complement);
	$("#page-pref-btn").css("border-color", complement);

	$.each(["#page-pref-btn", ".tabs li", ".navbar-default .navbar-nav>li>a", ".navbar-default .dropdown-menu>li>a"], function() {
		$(this.toString()).css("background-color", window.page.color).off("mouseenter").off("mouseleave").mouseenter(function() {
			$(this).css("background-color", window.page.complement);
		}).mouseleave(function() {
			$(this).css("background-color", window.page.color);
		});
	});
};

window.page.sendFeedback = function(type, msg, name, username, webpage, callback) {
	// if the user does not want to send the webpage, the variable will be set to undefined, so don't do any checks here.
	window.api.post("feedback/post/", {
		type: type,
		msg: msg,
		name: name,
		username: username,
		webpage: webpage
	}, function(data) {
		callback();
	});
};

window.page.openFeedbackModal = function(type) {
	var desc = "Liked a feature? Found something helpful? Tell us what you like! We'd love to hear it, and your feedback helps us make even better things in the future!";
	if (type == "frown") {
		desc = "Annoyed by something? Found a glitch? Hate how something works? Tell us! We'd love to help you and improve PlanHub.";
	} else if (type == "idea") {
		desc = "Have an idea for a new feature? Something that helps you? A tweak to make your life easier? Tell us! We'd love to include it and make PlanHub even better!";
	}

	$("#feedback-modal-title-first").text("Send a ");
	if (type == "idea") {
		$("#feedback-modal-title-first").text("Send an ");
	}
	$(".feedback-type").text(type);
	$(".feedback-desc").text(desc);

	$("#feedback-modal").modal();
};

function upsellTrigger() {
	$(".upsell-btn").off("click").on("click", function() {
		var feature = $(this).attr("data-feature");

		window.page.showLoading();

		window.page.addFeature(feature, function() {
			window.location.hash = feature;
			window.location.reload();
		});

		//$(".upsell[data-feature=" + feature + "]").remove();
	});
}

$(document).ready(function() {
	window.page.showLoading();

	$('[data-toggle="tooltip"]').tooltip({
		container: 'body'
	});

	$(".tabs li").click(function() {
		setPage($(this).attr("data-page"));
	});

	$(".go-dropdown li a").click(function() {
		setPage($(this).attr("data-page"));
	});

	$(".admin-link").click(function() {
		setPage($(this).attr("data-page"));
	});

	$("#page-pref-btn").click(function() {
		window.prefs.openModal(window.page.getOpenPage());
	});

	upsellTrigger();

	$(".ideaBtn").click(function() {
		window.page.openFeedbackModal("idea");
	});

	$(".smileBtn").click(function() {
		window.page.openFeedbackModal("smile");
	});

	$(".frownBtn").click(function() {
		window.page.openFeedbackModal("frown");
	});

	$(".loadWarn button").click(function() {
		window.location.reload();
	})

	$("#feedback-submit").click(function() {
		var webpage = undefined;
		if ($("#feedback-snapshot").prop("checked")) {
			// if checkbox is checked, send copy of the webpage
			webpage = window.utils.b64EncodeUnicode($("html").html().toString());
		}
		$(".feedback-footer-normal").addClass("hidden");
		$(".feedback-footer-load").removeClass("hidden");
		window.page.sendFeedback($(".feedback-type:first").text(), $("#feedback-msg").val(), $(".user-name:first").text(), $("#username").text(), webpage, function() {
			$(".feedback-footer-load").addClass("hidden");
			$(".feedback-footer-normal").removeClass("hidden");
			$("#feedback-msg").val("");
			$("#feedback-modal").modal("hide");
			swal("Awesome!", "Your feedback has been sent successfully! We'll try to respond to you as soon as possible.", "success")
		});
	});

	// this is used by topTabs to move the prefs button
	$(".username-menu").on("show.bs.dropdown", function() {
		$("#page-pref-btn").addClass("moved");
	});
	$(".username-menu").on("hide.bs.dropdown", function() {
		$("#page-pref-btn").removeClass("moved");
	});

	window.api.ready(function() {
		console.log("Nonce pool ready!");

		window.prefs.getBatch(["topTabs", "hideTawk", "themeColor"], function(prefs) {
			if (prefs.topTabs == "1") {
				$("head").append('<link href=" ' + $("#basePath").text() + '/css/topTabs.css" rel="stylesheet" />');
			}

			if (prefs.hideTawk == "1") {
				if (Tawk_API && Tawk_API.hideWidget) {
					Tawk_API.hideWidget();
				}
				$("#tawkchat-iframe-container").remove();
				$("#tawk-script").remove();
			}

			if (prefs.themeColor != undefined && prefs.themeColor != "") {
				window.page.setColor(prefs.themeColor);
				$(".selBox.themeColor.selected").removeClass("selected");
				$(".selBox.themeColor[data-selBoxVal=" + prefs.themeColor + "]").addClass("selected");
			}
		});

		window.page.getFeatures(function(features) {
			for (var i = features.length - 1; i >= 0; i--) {
				$(".upsell[data-feature=" + features[i] + "]").remove();
			}
			$(".upsell").each(function() {
				$(this).parent().addClass("hasUpsell");
			});

			window.page.features = features;
			window.page.hideLoading();

			if (window.location.hash != "") {
				setPage(window.location.hash.substr(1));
			} else {
				setPage("overview");
			}

			if (features.length == 0) {
				introJs().setOption("showStepNumbers", false).start();
			}
		});
	});

	window.api.init();
});
<commit_msg>race condition<commit_after>function setPage(newPage) {
	$(".page.open-page").removeClass("open-page");
	if ($("#" + newPage).length != 0) {
		// yay, it exists. go to it
		$("#" + newPage).addClass("open-page");
		if ($(".upsell[data-feature=" + newPage + "]").length == 0) {
			$("#" + newPage).trigger("tabOpened");
		}
		window.location.hash = newPage;
	} else {
		// fetch it!
		window.page.showLoading();
		window.api.get("pageHandler/fetchPage/" + newPage, function(response) {
			// check for error
			if (response.status === "error") {
				console.error("Error loading page!");
				return;
			}

			// and load it
			var $page = $(response);

			var $styles = $page.children("#page-styles");
			$("head").append($styles);

			var $modals = $page.children("#page-modals");
			$("body").append($modals);

			var $upsell = $page.children("#page-upsell");
				$upsell.attr("id", newPage + "-upsell");
				$upsell.addClass("upsell");
				$upsell.addClass("row");
				$upsell.attr("data-feature", newPage);
			var $content = $page.children("#page-content");
				$content.attr("id", newPage);
				$content.addClass("page");
				if (window.page.features.indexOf(newPage) == -1) {
					$content.append($upsell);
				}
			$(".pages").append($content);

			var $scripts = $page.children("#page-scripts");
			$("head").append($scripts);

			upsellTrigger();
			window.page.hideLoading();
			setPage(newPage); // and show it
		});
	}
}

window.page = {
	features: [],
	loadTimeout: null,
	loadWarnTimeout: null
};

window.page.getBasePath = function() {
	return $("#basePath").text();
};

window.page.showLoading = function() {
	window.page.loadTimeout = setTimeout(function() {
		$(".loadOverlay").addClass("showLoadOverlay");
		$(".loadWarn").removeClass("showingLoadWarn");
		window.page.loadWarnTimeout = setTimeout(function() {
			console.warn("Loading is taking time...");
			$(".loadWarn").addClass("showingLoadWarn");
		}, 10000);
	}, 400);
};

window.page.hideLoading = function() {
	$(".loadOverlay").removeClass("showLoadOverlay");
	if (window.page.loadTimeout != null) {
		clearTimeout(window.page.loadTimeout);
	}
	if (window.page.loadWarnTimeout != null) {
		clearTimeout(window.page.loadWarnTimeout);
	}
	window.page.loadTimeout = 0;
	window.page.loadWarnTimeout = 0;
};

window.page.getFeatures = function(callback) {
	window.api.get("features/get/", function(data) {
		callback(data.features);
	});
};

window.page.addFeature = function(feature, callback) {
	window.api.post("features/add/", { feature: feature }, function(data) {
		callback();
	});
};

window.page.getOpenPage = function() {
	return $(".page.open-page").attr("id");
};

// default color is #333333 and complement is #222222
window.page.setColor = function(color) {
	var complements = {
		"#333333": "#222222",
		"#990f0f": "#880e0e",
		"#0f993b": "#0e882a",
		"#1c19c2": "#0b08b1",
		"#c93e3e": "#b82d2d",
		"#37c464": "#26b353",
		"#3834fa": "#2723e9",
		"#00c8d8": "#00b7c7"
	};

	var complement = complements[color];

	window.page.color = color;
	window.page.complement = complement;

	$(".tabs").css("background-color", color);
	$(".navbar-default").css("background-color", color);
	$("#page-pref-btn").css("background-color", color);
	$(".navbar-default .dropdown-menu").css("background-color", color);

	$(".tabs").css("border-right", "solid 1px " + complement);
	$("#page-pref-btn").css("border-color", complement);

	$.each(["#page-pref-btn", ".tabs li", ".navbar-default .navbar-nav>li>a", ".navbar-default .dropdown-menu>li>a"], function() {
		$(this.toString()).css("background-color", window.page.color).off("mouseenter").off("mouseleave").mouseenter(function() {
			$(this).css("background-color", window.page.complement);
		}).mouseleave(function() {
			$(this).css("background-color", window.page.color);
		});
	});
};

window.page.sendFeedback = function(type, msg, name, username, webpage, callback) {
	// if the user does not want to send the webpage, the variable will be set to undefined, so don't do any checks here.
	window.api.post("feedback/post/", {
		type: type,
		msg: msg,
		name: name,
		username: username,
		webpage: webpage
	}, function(data) {
		callback();
	});
};

window.page.openFeedbackModal = function(type) {
	var desc = "Liked a feature? Found something helpful? Tell us what you like! We'd love to hear it, and your feedback helps us make even better things in the future!";
	if (type == "frown") {
		desc = "Annoyed by something? Found a glitch? Hate how something works? Tell us! We'd love to help you and improve PlanHub.";
	} else if (type == "idea") {
		desc = "Have an idea for a new feature? Something that helps you? A tweak to make your life easier? Tell us! We'd love to include it and make PlanHub even better!";
	}

	$("#feedback-modal-title-first").text("Send a ");
	if (type == "idea") {
		$("#feedback-modal-title-first").text("Send an ");
	}
	$(".feedback-type").text(type);
	$(".feedback-desc").text(desc);

	$("#feedback-modal").modal();
};

function upsellTrigger() {
	$(".upsell-btn").off("click").on("click", function() {
		var feature = $(this).attr("data-feature");

		window.page.showLoading();

		window.page.addFeature(feature, function() {
			window.location.hash = feature;
			window.location.reload();
		});

		//$(".upsell[data-feature=" + feature + "]").remove();
	});
}

$(document).ready(function() {
	window.page.showLoading();

	$('[data-toggle="tooltip"]').tooltip({
		container: 'body'
	});

	$(".tabs li").click(function() {
		setPage($(this).attr("data-page"));
	});

	$(".go-dropdown li a").click(function() {
		setPage($(this).attr("data-page"));
	});

	$(".admin-link").click(function() {
		setPage($(this).attr("data-page"));
	});

	$("#page-pref-btn").click(function() {
		window.prefs.openModal(window.page.getOpenPage());
	});

	upsellTrigger();

	$(".ideaBtn").click(function() {
		window.page.openFeedbackModal("idea");
	});

	$(".smileBtn").click(function() {
		window.page.openFeedbackModal("smile");
	});

	$(".frownBtn").click(function() {
		window.page.openFeedbackModal("frown");
	});

	$(".loadWarn button").click(function() {
		window.location.reload();
	})

	$("#feedback-submit").click(function() {
		var webpage = undefined;
		if ($("#feedback-snapshot").prop("checked")) {
			// if checkbox is checked, send copy of the webpage
			webpage = window.utils.b64EncodeUnicode($("html").html().toString());
		}
		$(".feedback-footer-normal").addClass("hidden");
		$(".feedback-footer-load").removeClass("hidden");
		window.page.sendFeedback($(".feedback-type:first").text(), $("#feedback-msg").val(), $(".user-name:first").text(), $("#username").text(), webpage, function() {
			$(".feedback-footer-load").addClass("hidden");
			$(".feedback-footer-normal").removeClass("hidden");
			$("#feedback-msg").val("");
			$("#feedback-modal").modal("hide");
			swal("Awesome!", "Your feedback has been sent successfully! We'll try to respond to you as soon as possible.", "success")
		});
	});

	// this is used by topTabs to move the prefs button
	$(".username-menu").on("show.bs.dropdown", function() {
		$("#page-pref-btn").addClass("moved");
	});
	$(".username-menu").on("hide.bs.dropdown", function() {
		$("#page-pref-btn").removeClass("moved");
	});

	window.api.ready(function() {
		console.log("Nonce pool ready!");

		window.prefs.getBatch(["topTabs", "hideTawk", "themeColor"], function(prefs) {
			if (prefs.topTabs == "1") {
				$("head").append('<link href=" ' + $("#basePath").text() + '/css/topTabs.css" rel="stylesheet" />');
			}

			if (prefs.hideTawk == "1") {
				if (Tawk_API && Tawk_API.hideWidget) {
					Tawk_API.hideWidget();
				}
				$("#tawkchat-iframe-container").remove();
				$("#tawk-script").remove();
			}

			if (prefs.themeColor != undefined && prefs.themeColor != "") {
				window.page.setColor(prefs.themeColor);
				$(".selBox.themeColor.selected").removeClass("selected");
				$(".selBox.themeColor[data-selBoxVal=" + prefs.themeColor + "]").addClass("selected");
			}
		});

		window.page.getFeatures(function(features) {
			for (var i = features.length - 1; i >= 0; i--) {
				$(".upsell[data-feature=" + features[i] + "]").remove();
			}
			$(".upsell").each(function() {
				$(this).parent().addClass("hasUpsell");
			});

			window.page.features = features;
			window.page.hideLoading();

			if (window.location.hash != "") {
				setPage(window.location.hash.substr(1));
			} else {
				setPage("overview");
			}

			if (features.length == 0) {
				introJs().setOption("showStepNumbers", false).start();
			}
		});
	});

	window.api.init();
});
<|endoftext|>


<commit_before>function matchMaker(userList) {
    var likeUsers = [];
    userList.unshift(userList.pop());
    for (var i = 1; i < userList.length; i++) {
        var likenessCounter = 0;
        var j = 1;
        while (j <= 4) {
            if (userList[0][j] == userList[i][j]) {
                likenessCounter++;
            }
            j++;
        }
        if (likenessCounter === 4) {
            likeUsers.push(userList[i]);
        }
    }
    return likeUsers;
};

var jose = {0: 'Jose', 1: 'tuesday', 2: '3 AM', 3: 'anytime fitness', 4: 'legs'};
var brady = {0: 'Brady',1: 'tuesday', 2: '3 AM', 3: 'anytime fitness', 4: 'legs'};
var chonson = {0: 'Chonson', 1: 'tuesday', 2: '5 AM', 3: 'anytime fitness', 4: 'legs'};
var jabroni = {0: 'Jabroni', 1: 'tuesday', 2: '5 AM', 3: 'anytime fitness', 4: 'legs'};
var users = [jose, brady, chonson, jabroni];

<commit_msg>Add comments for probable refactor<commit_after>function matchMaker(userList) {
    var likeUsers = [];
    userList.unshift(userList.pop());
    for (var i = 1; i < userList.length; i++) {
        var likenessCounter = 0;
        var j = 1;
        while (j <= 4) {
            if (userList[0][j] == userList[i][j]) {
                likenessCounter++;
            }
            j++;
        }
        if (likenessCounter === 4) {
            likeUsers.push(userList[i]);
        }
    }
    return likeUsers;
};

var jose = {0: 'Jose', 1: 'tuesday', 2: '3 AM', 3: 'anytime fitness', 4: 'legs'};
var brady = {0: 'Brady',1: 'tuesday', 2: '3 AM', 3: 'anytime fitness', 4: 'legs'};
var chonson = {0: 'Chonson', 1: 'tuesday', 2: '5 AM', 3: 'anytime fitness', 4: 'legs'};
var jabroni = {0: 'Jabroni', 1: 'tuesday', 2: '5 AM', 3: 'anytime fitness', 4: 'legs'};
var users = [jose, brady, chonson, jabroni];

// Remove user from [users]
// Put into its own array
// Compare that with every entry in [users]
// Put user back into [users] after search

<|endoftext|>


<commit_before>var Flow = require('./flow');
var utils = require('./utils');
var isPublicPath = new RegExp("^\/[^/]");
var cbBuffer = {};
var instances = {};

// call callbacks
function callbacks (err, instance, cbs) {
    cbs.forEach(function (callback) {
        callback(err, instance);
    });
}

//reset caches
exports.reset = function () {
    instances = {};
    cbBuffer = {};
};

exports.instances = instances;

/**
 * Create a new module instance.
 *
 * @public
 * @param {object} The CommonJS module.
 * @param {object} The composition config.
 * @param {function} Callback handler.
 */
exports.factory = function (name, session,  callback) {

    if (!name) {
        return callback(new Error('Instance.factory: No name.'));
    }

    process.nextTick(_factory.bind(this), name, session, callback);
};

function _factory (name, session, callback) {

    session = session || {};
    callback = callback || function (err) {err && console.error(err)};

    // check instance cache
    if (name !== '*' && instances[name]) {

        if (!utils.access(instances[name], session)) {
            return callback(console.log('E', new Error('Access denied for instance:' + name)));
        }

        // buffer callback
        if (instances[name] === 1 || !instances[name]._ready) {
            return cbBuffer[name].push(callback);
        }

        return callback(null, instances[name]);
    }

    // save callback and mark instance as loading
    cbBuffer[name] = [callback];
    instances[name] = 1;

    var flow = this;

    // get composition
    flow.composition(name, function (err, composition) {

        if (err) {
            return callback(err);
        }

        if (!composition || !composition.module) {
            return callback(new Error('Invalid composition'));
        }

        if (!utils.access(composition, session)) {
            return callback(new Error('Access denied for instance:' + composition.name));
        }

        // load styles
        if (flow.styles && composition.styles) {
            flow.styles(composition.styles);
        }

        // pre load instances
        if (composition.load) {
            composition.load.forEach(function (iName) {
                flow.load(iName);
            });
        }

        var count = 1;
        var module;
        var readHandler = function (err, cjsMod) {

            module = module || cjsMod;

            if (--count === 0) {
                build.call(flow, module, composition, callback, (name === '*'));
            }
        };

        // load markup
        if (flow.markup && composition.markup) {
            ++count;
            flow.markup(composition.markup, readHandler);
        }

        // get CommonJS module
        flow.module(composition.module, readHandler);
    });
};

function build (module, config, callback, isEntrypoint) {

    // create new flow emitter
    var flow = this;
    var instance = flow.factory(module);

    // extend instance
    instance._module = config.module;
    instance._config = config.config || {};
    instance._name = config.name;
    instance._roles = config.roles || {};
    instance._flow = {};
    instance._markups = {};
    instance._events = {};

    // setup flow
    if (config.flow) {
        config.flow.forEach(function (flow) {
            if (flow.constructor === Array) {

                // create event streams cache
                if (!instance._flow[flow[0]]) {
                    instance._flow[flow[0]] = [];
                }

                // push flow stream config to stream cache
                instance._flow[flow[0]].push(flow.slice(1));
            }
        });
    }

    // init loader instance
    if (instance.init) {
        instance.init();
    }

    // mark instance as ready
    instance._ready = true;

    // save module instance in cache
    instances[instance._name] = instance;

    if (isEntrypoint) {
        instances['*'] = instance;
    }

    callbacks(null, instance, cbBuffer[isEntrypoint ? '*' : instance._name]);
}
<commit_msg>only one stream per event<commit_after>var Flow = require('./flow');
var utils = require('./utils');
var isPublicPath = new RegExp("^\/[^/]");
var cbBuffer = {};
var instances = {};

// call callbacks
function callbacks (err, instance, cbs) {
    cbs.forEach(function (callback) {
        callback(err, instance);
    });
}

//reset caches
exports.reset = function () {
    instances = {};
    cbBuffer = {};
};

exports.instances = instances;

/**
 * Create a new module instance.
 *
 * @public
 * @param {object} The CommonJS module.
 * @param {object} The composition config.
 * @param {function} Callback handler.
 */
exports.factory = function (name, session,  callback) {

    if (!name) {
        return callback(new Error('Instance.factory: No name.'));
    }

    process.nextTick(_factory.bind(this), name, session, callback);
};

function _factory (name, session, callback) {

    session = session || {};
    callback = callback || function (err) {err && console.error(err)};

    // check instance cache
    if (name !== '*' && instances[name]) {

        if (!utils.access(instances[name], session)) {
            return callback(console.log('E', new Error('Access denied for instance:' + name)));
        }

        // buffer callback
        if (instances[name] === 1 || !instances[name]._ready) {
            return cbBuffer[name].push(callback);
        }

        return callback(null, instances[name]);
    }

    // save callback and mark instance as loading
    cbBuffer[name] = [callback];
    instances[name] = 1;

    var flow = this;

    // get composition
    flow.composition(name, function (err, composition) {

        if (err) {
            return callback(err);
        }

        if (!composition || !composition.module) {
            return callback(new Error('Invalid composition'));
        }

        if (!utils.access(composition, session)) {
            return callback(new Error('Access denied for instance:' + composition.name));
        }

        // load styles
        if (flow.styles && composition.styles) {
            flow.styles(composition.styles);
        }

        // pre load instances
        if (composition.load) {
            composition.load.forEach(function (iName) {
                flow.load(iName);
            });
        }

        var count = 1;
        var module;
        var readHandler = function (err, cjsMod) {

            module = module || cjsMod;

            if (--count === 0) {
                build.call(flow, module, composition, callback, (name === '*'));
            }
        };

        // load markup
        if (flow.markup && composition.markup) {
            ++count;
            flow.markup(composition.markup, readHandler);
        }

        // get CommonJS module
        flow.module(composition.module, readHandler);
    });
};

function build (module, config, callback, isEntrypoint) {

    // create new flow emitter
    var flow = this;
    var instance = flow.factory(module);

    // extend instance
    instance._module = config.module;
    instance._config = config.config || {};
    instance._name = config.name;
    instance._roles = config.roles || {};
    instance._flow = {};
    instance._markups = {};
    instance._events = {};

    // setup flow
    if (config.flow) {
        config.flow.forEach(function (flow) {
            if (flow.constructor === Array) {

                // push flow stream config to stream cache
                //instance._flow[flow[0]].push(flow.slice(1));
                instance._flow[flow[0]] = flow.slice(1);
            }
        });
    }

    // init loader instance
    if (instance.init) {
        instance.init();
    }

    // mark instance as ready
    instance._ready = true;

    // save module instance in cache
    instances[instance._name] = instance;

    if (isEntrypoint) {
        instances['*'] = instance;
    }

    callbacks(null, instance, cbBuffer[isEntrypoint ? '*' : instance._name]);
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 The Regents of the University of Michigan.
// All Rights Reserved. Licensed according to the terms of the Revised
// BSD License. See LICENSE.txt for details.

let treeNode = (address, setUp) => new Promise(
    function(resolve, reject) {
  let node = {};
  let obj = {};
  let children = [];

  obj.runBefore = () => {};
  obj.run = () => {};
  obj.runAfter = () => {};

  obj.add = function(childSetUp) {
    children.push(treeNode(address.concat(children.length),
                           childSetUp))
  };

  node.run = logger => new Promise(function(resolveRun, rejectRun) {
    obj.log = (code, message) => new Promise(
        function(resolveLog, rejectLog) {
      let a = [Date.now(), code].concat(address);
      a.push(message || "");

      Promise.resolve(
        logger.log(a)

      ).then(value => {
        resolveLog(value);
      });
    });

    obj.log("begin");

    Promise.resolve(obj.runBefore()).then(function() {
      return Promise.resolve(obj.run());

    }).then(function() {
      let runningChildren = [];
      for (let child of node.children)
        runningChildren.push(child.run(logger));

      return Promise.all(runningChildren);

    }).then(function() {
      return Promise.resolve(obj.runAfter());

    }).then(function() {
      obj.log("done");
      resolveRun();
    });
  });

  Promise.resolve(setUp(obj)).then(function(value) {
    return Promise.all(children);

  }).then(function(childIterator) {
    node.children = [...childIterator];
    node.getLogTree = function() {
      let result = {};

      if (obj.description)
        result.d = obj.description;

      result.c = [];
      for (let leaf of node.children)
        result.c.push(leaf.getLogTree());

      return result;
    };

    resolve(node);
  });
});

let newRootNode = (newLogger, setUp) => new Promise(
    function(resolve, reject) {
  treeNode([], setUp).then(function(root) {
    let logger = newLogger(root.getLogTree());
    logger.storeProcess(root.run(logger));

    resolve(logger);
  });
});

module.exports = newRootNode;
<commit_msg>:muscle: Rename obj to userProxy<commit_after>// Copyright (c) 2017 The Regents of the University of Michigan.
// All Rights Reserved. Licensed according to the terms of the Revised
// BSD License. See LICENSE.txt for details.

let treeNode = (address, setUp) => new Promise(
    function(resolve, reject) {
  let node = {};
  let userProxy = {};
  let children = [];

  userProxy.runBefore = () => {};
  userProxy.run = () => {};
  userProxy.runAfter = () => {};

  userProxy.add = function(childSetUp) {
    children.push(treeNode(address.concat(children.length),
                           childSetUp))
  };

  node.run = logger => new Promise(function(resolveRun, rejectRun) {
    userProxy.log = (code, message) => new Promise(
        function(resolveLog, rejectLog) {
      let a = [Date.now(), code].concat(address);
      a.push(message || "");

      Promise.resolve(
        logger.log(a)

      ).then(value => {
        resolveLog(value);
      });
    });

    userProxy.log("begin");

    Promise.resolve(userProxy.runBefore()).then(function() {
      return Promise.resolve(userProxy.run());

    }).then(function() {
      let runningChildren = [];
      for (let child of node.children)
        runningChildren.push(child.run(logger));

      return Promise.all(runningChildren);

    }).then(function() {
      return Promise.resolve(userProxy.runAfter());

    }).then(function() {
      userProxy.log("done");
      resolveRun();
    });
  });

  Promise.resolve(setUp(userProxy)).then(function(value) {
    return Promise.all(children);

  }).then(function(childIterator) {
    node.children = [...childIterator];
    node.getLogTree = function() {
      let result = {};

      if (userProxy.description)
        result.d = userProxy.description;

      result.c = [];
      for (let leaf of node.children)
        result.c.push(leaf.getLogTree());

      return result;
    };

    resolve(node);
  });
});

let newRootNode = (newLogger, setUp) => new Promise(
    function(resolve, reject) {
  treeNode([], setUp).then(function(root) {
    let logger = newLogger(root.getLogTree());
    logger.storeProcess(root.run(logger));

    resolve(logger);
  });
});

module.exports = newRootNode;
<|endoftext|>


<commit_before>const ytdl = require('ytdl-core');
const streamOptions = { seek: 0, volume: 1 };

//id canal musica = 375842517566095360
module.exports = (client, message, args) => {

    let channel = client.channels.get('375842517566095360');
    if ((channel) && (args[1]))
    {
      channel.join()
      .then(connection =>
      {
        message.reply('A música no **Youtube** escolhida foi iniciada com sucesso! :musical_note:').then(msg => {
          msg.delete(60000) });
        //const dispatcher = connection.playStream(ytdl(args[1]));
        const stream = ytdl(URL, { filter : 'audioonly' });
        const dispatcher = connection.playStream(stream, streamOptions);
        //dispatcher.setVolumeLogarithmic(5 / 5);
      })
    .catch(console.log);
    }
    else if ((channel) && (args[0]))
    { message.reply('Por favor, informe uma **URL** para tocar.').then(msg => {
        msg.delete(60000) });; }
    message.delete(60000);
};<commit_msg><commit_after>const ytdl = require('ytdl-core');
const streamOptions = { seek: 0, volume: 1 };

//id canal musica = 375842517566095360
module.exports = (client, message, args) => {

    let channel = client.channels.get('375842517566095360');
    if (channel)
    {
      channel.join()
      .then(connection =>
      {
        message.reply('A música no **Youtube** escolhida foi iniciada com sucesso! :musical_note:').then(msg => {
          msg.delete(60000) });
        //const dispatcher = connection.playStream(ytdl(args[1]));
        const stream = ytdl(URL, { filter : 'audioonly' });
        const dispatcher = connection.playStream(stream, streamOptions);
        //dispatcher.setVolumeLogarithmic(5 / 5);
      })
    .catch(console.log);
    }
    message.delete(60000);
};<|endoftext|>


<commit_before>var Path = require('path'),
    _ = require('underscore'),
    httpErrors = require('httperrors'),
    getFilterInfosAndTargetContentTypeFromQueryString = require('./getFilterInfosAndTargetContentTypeFromQueryString'),
    mime = require('mime');

var hijackResponse = require('hijackresponse');

var isImageByExtension = {};

Object.keys(mime.extensions).forEach(function (contentType) {
    if (/^image\//.test(contentType)) {
        var extension = mime.extensions[contentType];
        isImageByExtension[extension] = true;
    }
});

isImageByExtension.jpg = true;

function isImageExtension(extension) {
    return isImageByExtension[extension.toLowerCase()];
}

module.exports = function (options) {
    options = options || {};
    return function (req, res, next) {
        var matchExtensionAndQueryString = req.url.match(/\.(\w+)\?(.*)$/);
        if (matchExtensionAndQueryString && isImageExtension(matchExtensionAndQueryString[1]) && req.accepts('image/*')) {
            // Prevent If-None-Match revalidation with the downstream middleware with ETags that aren't suffixed with "-processimage":
            var queryString = matchExtensionAndQueryString[2],
                ifNoneMatch = req.headers['if-none-match'];
            if (ifNoneMatch) {
                var validIfNoneMatchTokens = ifNoneMatch.split(' ').filter(function (etag) {
                    return (/-processimage["-]/).test(etag);
                });
                if (validIfNoneMatchTokens.length > 0) {
                    req.headers['if-none-match'] = validIfNoneMatchTokens.join(' ');
                } else {
                    delete req.headers['if-none-match'];
                }
            }
            delete req.headers['if-modified-since']; // Prevent false positive conditional GETs after enabling processimage
            hijackResponse(res, function (err, res) {
                var contentType = res.getHeader('Content-Type'),
                    etagFragments = [],
                    seenData = false,
                    hasEnded = false;

                function sendErrorResponse(err) {
                    if (!hasEnded) {
                        hasEnded = true;
                        if ('commandLine' in this) {
                            err.message = this.commandLine + ': ' + err.message;
                        }
                        if (err.message === 'Input buffer contains unsupported image format') {
                            // ?metadata with an unrecognized image format
                            err = new httpErrors.UnsupportedMediaType(err.message);
                        }
                        if (err.message === 'Input image exceeds pixel limit') {
                            // ?metadata with an unrecognized image format
                            err = new httpErrors.RequestEntityTooLarge(err.message);
                        }
                        res.unhijack();
                        next(err);
                    }
                }

                if (contentType && contentType.indexOf('image/') === 0) {
                    var filterInfosAndTargetFormat = getFilterInfosAndTargetContentTypeFromQueryString(queryString, _.defaults({
                            sourceFilePath: options.root && Path.resolve(options.root, req.url.substr(1)),
                            sourceContentType: contentType
                        }, options)),
                        targetContentType = filterInfosAndTargetFormat.targetContentType;
                    if (filterInfosAndTargetFormat.filterInfos.length === 0) {
                        return res.unhijack(true);
                    }
                    if (targetContentType) {
                        res.setHeader('Content-Type', targetContentType);
                    }
                    res.removeHeader('Content-Length');
                    var oldETag = res.getHeader('ETag'),
                        newETag;
                    if (oldETag) {
                        newETag = '"' + oldETag.replace(/^"|"$/g, '') + '-processimage"';
                        res.setHeader('ETag', newETag);

                        if (ifNoneMatch && ifNoneMatch.indexOf(newETag) !== -1) {
                            return res.status(304).end();
                        }
                    }

                    var filters = filterInfosAndTargetFormat.filterInfos.map(function (filterInfo) {
                        return filterInfo.create();
                    });

                    for (var i = 0 ; i < filters.length ; i += 1) {
                        if (i < filters.length - 1) {
                            filters[i].pipe(filters[i + 1]);
                        }
                        filters[i].on('etagFragment', function (etagFragment) {
                            etagFragments.push(etagFragment);
                        });
                        filters[i].on('error', sendErrorResponse);
                    }

                    res.pipe(filters[0]);
                    filters[filters.length - 1].on('end', function () {
                        hasEnded = true;
                    }).pipe(res);

                    res.on('error', function () {
                        res.unhijack();
                        next(500);
                    });
                } else {
                    res.unhijack();
                }
            });
            next();
        } else {
            next();
        }
    };
};
<commit_msg>remove unused var<commit_after>var Path = require('path'),
    _ = require('underscore'),
    httpErrors = require('httperrors'),
    getFilterInfosAndTargetContentTypeFromQueryString = require('./getFilterInfosAndTargetContentTypeFromQueryString'),
    mime = require('mime');

var hijackResponse = require('hijackresponse');

var isImageByExtension = {};

Object.keys(mime.extensions).forEach(function (contentType) {
    if (/^image\//.test(contentType)) {
        var extension = mime.extensions[contentType];
        isImageByExtension[extension] = true;
    }
});

isImageByExtension.jpg = true;

function isImageExtension(extension) {
    return isImageByExtension[extension.toLowerCase()];
}

module.exports = function (options) {
    options = options || {};
    return function (req, res, next) {
        var matchExtensionAndQueryString = req.url.match(/\.(\w+)\?(.*)$/);
        if (matchExtensionAndQueryString && isImageExtension(matchExtensionAndQueryString[1]) && req.accepts('image/*')) {
            // Prevent If-None-Match revalidation with the downstream middleware with ETags that aren't suffixed with "-processimage":
            var queryString = matchExtensionAndQueryString[2],
                ifNoneMatch = req.headers['if-none-match'];
            if (ifNoneMatch) {
                var validIfNoneMatchTokens = ifNoneMatch.split(' ').filter(function (etag) {
                    return (/-processimage["-]/).test(etag);
                });
                if (validIfNoneMatchTokens.length > 0) {
                    req.headers['if-none-match'] = validIfNoneMatchTokens.join(' ');
                } else {
                    delete req.headers['if-none-match'];
                }
            }
            delete req.headers['if-modified-since']; // Prevent false positive conditional GETs after enabling processimage
            hijackResponse(res, function (err, res) {
                var contentType = res.getHeader('Content-Type'),
                    etagFragments = [],
                    hasEnded = false;

                function sendErrorResponse(err) {
                    if (!hasEnded) {
                        hasEnded = true;
                        if ('commandLine' in this) {
                            err.message = this.commandLine + ': ' + err.message;
                        }
                        if (err.message === 'Input buffer contains unsupported image format') {
                            // ?metadata with an unrecognized image format
                            err = new httpErrors.UnsupportedMediaType(err.message);
                        }
                        if (err.message === 'Input image exceeds pixel limit') {
                            // ?metadata with an unrecognized image format
                            err = new httpErrors.RequestEntityTooLarge(err.message);
                        }
                        res.unhijack();
                        next(err);
                    }
                }

                if (contentType && contentType.indexOf('image/') === 0) {
                    var filterInfosAndTargetFormat = getFilterInfosAndTargetContentTypeFromQueryString(queryString, _.defaults({
                            sourceFilePath: options.root && Path.resolve(options.root, req.url.substr(1)),
                            sourceContentType: contentType
                        }, options)),
                        targetContentType = filterInfosAndTargetFormat.targetContentType;
                    if (filterInfosAndTargetFormat.filterInfos.length === 0) {
                        return res.unhijack(true);
                    }
                    if (targetContentType) {
                        res.setHeader('Content-Type', targetContentType);
                    }
                    res.removeHeader('Content-Length');
                    var oldETag = res.getHeader('ETag'),
                        newETag;
                    if (oldETag) {
                        newETag = '"' + oldETag.replace(/^"|"$/g, '') + '-processimage"';
                        res.setHeader('ETag', newETag);

                        if (ifNoneMatch && ifNoneMatch.indexOf(newETag) !== -1) {
                            return res.status(304).end();
                        }
                    }

                    var filters = filterInfosAndTargetFormat.filterInfos.map(function (filterInfo) {
                        return filterInfo.create();
                    });

                    for (var i = 0 ; i < filters.length ; i += 1) {
                        if (i < filters.length - 1) {
                            filters[i].pipe(filters[i + 1]);
                        }
                        filters[i].on('etagFragment', function (etagFragment) {
                            etagFragments.push(etagFragment);
                        });
                        filters[i].on('error', sendErrorResponse);
                    }

                    res.pipe(filters[0]);
                    filters[filters.length - 1].on('end', function () {
                        hasEnded = true;
                    }).pipe(res);

                    res.on('error', function () {
                        res.unhijack();
                        next(500);
                    });
                } else {
                    res.unhijack();
                }
            });
            next();
        } else {
            next();
        }
    };
};
<|endoftext|>


<commit_before>'use strict';

var os = require('os');
var path = require('path');

var _ = require('lodash');

var getConfigFromFile = require(path.resolve(`${__dirname}/getConfigFromFile`));
var getConfigFromConsul = require(path.resolve(`${__dirname}/getConfigFromConsul`));
var processConfig = require(path.resolve(`${__dirname}/processConfig`));
var validateConfig = require(path.resolve(`${__dirname}/validateConfig`));

var ConfigError = require(path.resolve(`${__dirname}/Error`));

/**
 * service configuration from consul or json file
 *
 * @see http://consul.io
 */
class ServiceConfig {

    /**
     * @constructor
     * @param {logger} logger
     * @param {Object} options
     */
    constructor (logger, options) {
        this._logger = logger;

        this.Error = ConfigError;

        this._options = {};

        if (options) {
            this._options = options;
        }

        this._config = null;
    }

    /**
     * load config
     *
     * @return {Promise}
     */
    load () {
        return new Promise((resolve, reject) => {

            getConfigFromConsul(this._logger, this._options)
                .then((config) => {
                    if (!config) {
                        return getConfigFromFile(this._logger, this._options);
                    }

                    return config;
                })
                .then((config) => {
                    return processConfig(this._logger, this._options, config);
                })
                .then((config) => {
                    if (this._options.schema) {
                        this._logger.debug('validate config by schema');

                        return validateConfig(
                            this._logger,
                            config,
                            this._options.schema
                        );
                    }

                    return config;
                })
                .then((config) => {
                    this._config = config;
                    this._config.service = {
                        hostname: os.hostname()
                    };
                    resolve();
                })
                .catch((error) => {
                    reject(ConfigError.ensureError(error));
                });

        });
    }

    /**
     * get config using lodash get method
     *
     * @param  {String} name
     * @param  {*} defaultValue
     * @return {*}
     */
    get (name, defaultValue) {
        if (typeof defaultValue === 'undefined') {
            defaultValue = null;
        }

        return _.get(this._config, name, defaultValue);
    }

    /**
     * return full config object
     *
     * @return {Object}
     */
    toObject () {
        return JSON.parse(JSON.stringify(this._config));
    }

}

module.exports = ServiceConfig;
<commit_msg>new: Service/Config new 'set' method<commit_after>'use strict';

var os = require('os');
var path = require('path');

var _ = require('lodash');

var getConfigFromFile = require(path.resolve(`${__dirname}/getConfigFromFile`));
var getConfigFromConsul = require(path.resolve(`${__dirname}/getConfigFromConsul`));
var processConfig = require(path.resolve(`${__dirname}/processConfig`));
var validateConfig = require(path.resolve(`${__dirname}/validateConfig`));

var ConfigError = require(path.resolve(`${__dirname}/Error`));

/**
 * service configuration from consul or json file
 *
 * @see http://consul.io
 */
class ServiceConfig {

    /**
     * @constructor
     * @param {logger} logger
     * @param {Object} options
     */
    constructor (logger, options) {
        this._logger = logger;

        this.Error = ConfigError;

        this._options = {};

        if (options) {
            this._options = options;
        }

        this._config = null;
    }

    /**
     * load config
     *
     * @return {Promise}
     */
    load () {
        return new Promise((resolve, reject) => {

            getConfigFromConsul(this._logger, this._options)
                .then((config) => {
                    if (!config) {
                        return getConfigFromFile(this._logger, this._options);
                    }

                    return config;
                })
                .then((config) => {
                    return processConfig(this._logger, this._options, config);
                })
                .then((config) => {
                    if (this._options.schema) {
                        this._logger.debug('validate config by schema');

                        return validateConfig(
                            this._logger,
                            config,
                            this._options.schema
                        );
                    }

                    return config;
                })
                .then((config) => {
                    this._config = config;
                    this._config.service = {
                        hostname: os.hostname()
                    };
                    resolve();
                })
                .catch((error) => {
                    reject(ConfigError.ensureError(error));
                });

        });
    }

    /**
     * get config using lodash get method
     *
     * @param  {String} name
     * @param  {*} defaultValue
     * @return {*}
     */
    get (name, defaultValue) {
        if (typeof defaultValue === 'undefined') {
            defaultValue = null;
        }

        return _.get(this._config, name, defaultValue);
    }

    /**
     * set config variable
     *
     * @param {String} name
     * @param {*} value
     * @return {*}
     */
    set (name, value) {
        return _.set(this._config, name, value);
    }

    /**
     * return full config object
     *
     * @return {Object}
     */
    toObject () {
        return JSON.parse(JSON.stringify(this._config));
    }

}

module.exports = ServiceConfig;
<|endoftext|>


<commit_before>var debug      = require('debug')('pulldasher:pull-manager'),
    pullQueue  = require('./pull-queue'),
    dbManager  = require('./db-manager'),
    _          = require('underscore'),
    utils      = require('./utils');

var sockets = [];
var pulls = [];

var pullManager = module.exports = {
   addSocket: function(socket) {
      sockets.push(socket);
      sendInitialData(socket);
      socket.on('disconnect', function() {
         removeSocket(socket);
      });
   },

   updatePull: function(updatedPull) {
      var pull = getPull(updatedPull.data.repo, updatedPull.data.number);

      if (pull) {
         _.extend(pull, updatedPull);
         if (!pull.isOpen()) {
            pulls = _.without(pulls, pull);
         }
      } else {
         pull = updatedPull;
         if (pull.isOpen()) {
            pulls.push(pull);
         }
      }

      notifyAboutPullStateChange(pull);
   }
};

function sendInitialData(socket) {
   debug('Emitting `allPulls`: %s pulls altogether', pulls.length);
   socket.emit('allPulls', _.invoke(pulls, 'toObject'));
}

function notifyAboutPullStateChange(pull) {
   debug('Emitting `pullChange`: sending Pull #%s to %s sockets',
   pull.data.number, sockets.length);
   sockets.forEach(function(socket) {
      socket.emit('pullChange', pull.toObject());
   });
}

/**
 * Removes the given socket from the collection
 */
function removeSocket(socket) {
   var index = sockets.indexOf(socket);
   if (index !== -1) {
      sockets.splice(index, 1);
   }
}

function getPull(repo, number) {
   return _.find(pulls, function(pull) {
      return pull.data.repo == repo && pull.data.number == number;
   });
}

pullQueue.on('pullsChanged', function(pulls) {
   pulls.forEach(function(pullId) {
      var pull = getPull(pullId.repo, pullId.number);
      if (pull !== null) {
         pullManager.updatePull(pull);
      }
   });
});
<commit_msg>Remove unused requires<commit_after>var debug      = require('debug')('pulldasher:pull-manager'),
    pullQueue  = require('./pull-queue'),
    _          = require('underscore');

var sockets = [];
var pulls = [];

var pullManager = module.exports = {
   addSocket: function(socket) {
      sockets.push(socket);
      sendInitialData(socket);
      socket.on('disconnect', function() {
         removeSocket(socket);
      });
   },

   updatePull: function(updatedPull) {
      var pull = getPull(updatedPull.data.repo, updatedPull.data.number);

      if (pull) {
         _.extend(pull, updatedPull);
         if (!pull.isOpen()) {
            pulls = _.without(pulls, pull);
         }
      } else {
         pull = updatedPull;
         if (pull.isOpen()) {
            pulls.push(pull);
         }
      }

      notifyAboutPullStateChange(pull);
   }
};

function sendInitialData(socket) {
   debug('Emitting `allPulls`: %s pulls altogether', pulls.length);
   socket.emit('allPulls', _.invoke(pulls, 'toObject'));
}

function notifyAboutPullStateChange(pull) {
   debug('Emitting `pullChange`: sending Pull #%s to %s sockets',
   pull.data.number, sockets.length);
   sockets.forEach(function(socket) {
      socket.emit('pullChange', pull.toObject());
   });
}

/**
 * Removes the given socket from the collection
 */
function removeSocket(socket) {
   var index = sockets.indexOf(socket);
   if (index !== -1) {
      sockets.splice(index, 1);
   }
}

function getPull(repo, number) {
   return _.find(pulls, function(pull) {
      return pull.data.repo == repo && pull.data.number == number;
   });
}

pullQueue.on('pullsChanged', function(pulls) {
   pulls.forEach(function(pullId) {
      var pull = getPull(pullId.repo, pullId.number);
      if (pull !== null) {
         pullManager.updatePull(pull);
      }
   });
});
<|endoftext|>


<commit_before>/* Autocomplete.js v1.3.0 unstable developed by Baptiste Donaux | Under MIT Licence | (c) 2014, Baptiste Donaux */
var AutoComplete=function(e){this.Ajax=function(e,t,n,r,i){if(e){e.abort()}var s=t.method,o=t.url;if(s=="GET"){o+="?"+n}e=XMLHttpRequest();e.open(s,o,true);e.setRequestHeader("Content-type","application/x-www-form-urlencoded");e.setRequestHeader("Content-length",n.length);e.setRequestHeader("Connection","close");e.onreadystatechange=function(){if(e.readyState==4&&e.status==200){var n=e.response;switch(t.type){case"HTML":i.innerHTML=n;break;default:n=JSON.parse(n);var s,o=n.length,u=document.createElement("li"),a=document.createElement("ul");if(Object.prototype.toString.call(n)=="[object Array]"){if(o){for(var f=0;f<o;f++){u.innerHTML=n[f];a.appendChild(u);u=document.createElement("li")}}else{s=true;u.setAttribute("class","locked");u.innerHTML=t.noResult;a.appendChild(u)}}else{for(var l in n){if(n.hasOwnProperty(l)){u.innerHTML=n[l];u.setAttribute("data-autocomplete-value",l);a.appendChild(u);u=document.createElement("li")}}}if(i.hasChildNodes()){i.childNodes[0].remove()}i.appendChild(a)}if(s!==true){Open(r,i)}}};e.send(n);return e};this.BindCollection=function(e){var t,n=document.querySelectorAll(e);for(var r=n.length-1;r>=0;r--){t=n[r];if(t.nodeName.toUpperCase()=="INPUT"&&t.type.toUpperCase()=="TEXT"){BindOne(t)}}};this.BindOne=function(e){if(e!=null){var t="data-autocomplete-old-value",n=document.createElement("div"),r;n.setAttribute("class","resultsAutocomplete");n.setAttribute("style","top:"+(e.offsetTop+e.offsetHeight)+"px;left:"+e.offsetLeft+"px;width:"+e.clientWidth+"px;");e.parentNode.appendChild(n);e.setAttribute("autocomplete","off");e.addEventListener("focus",function(){var r=e.getAttribute(t);if(!r||e.value!=r){n.setAttribute("class","resultsAutocomplete open")}});e.addEventListener("blur",function(){Close(n)});e.addEventListener("keyup",function(e){var i=e.currentTarget,s=i.value;if(s){var o=CustParams(i),u=o.paramName+"="+s;if(o.url){var a=i.getAttribute(t);if(!a||s!=a){n.setAttribute("class","resultsAutocomplete open")}r=Ajax(r,o,u,i,n)}}})}};this.Close=function(e,t){t?e.setAttribute("class","resultsAutocomplete"):setTimeout(function(){Close(e,true)},150)};this.Initialize=function(){var e={method:"GET",paramName:"q",selector:["input[data-autocomplete]"],type:"JSON",noResult:"No result"};if(this.params===undefined){this.params={}}this.params=Merge(e,this.params);this.params.method=this.params.method.toUpperCase();this.params.type=this.params.type.toUpperCase();if(!this.params.method.match("^GET|POST$")){this.params.method=e.method}if(!this.params.type.match("^JSON|HTML$")){this.params.type=e.type}if(!Array.isArray(this.params.selector)){this.params.selector=e.selector}};this.CreateCustParams=function(e){var t={url:e.getAttribute("data-autocomplete"),method:e.getAttribute("data-autocomplete-method"),paramName:e.getAttribute("data-autocomplete-param-name"),type:e.getAttribute("data-autocomplete-type"),noResult:e.getAttribute("data-autocomplete-no-result")};for(var n in t){if(t.hasOwnProperty(n)&&!t[n]){delete t[n]}}if(t.method){!t.method.match("^GET|POST$")?delete t.method:t.method=t.method.toUpperCase()}if(t.type){!t.type.match("^JSON|HTML$")?delete t.type:t.type=t.type.toUpperCase()}return Merge(this.params,t)};this.CustParams=function(e){var t="data-autocomplete-id";if(e.hasAttribute(t)){return this.customParams[e.getAttribute(t)]}else{e.setAttribute(t,this.customParams.length);var n=CreateCustParams(e);this.customParams.push(n);return n}};this.Open=function(e,t){var n=t.getElementsByTagName("li");for(var r=n.length-1;r>=0;r--){n[r].addEventListener("click",function(t){var n=t.currentTarget,r="data-autocomplete-value";e.value=n.hasAttribute(r)?n.getAttribute(r):n.innerHTML;e.setAttribute("data-autocomplete-old-value",e.value)})}};this.Merge=function(e,t){var n={};for(var r in e){n[r]=e[r]}for(var r in t){n[r]=t[r]}return n};this.params=e;this.customParams=new Array;this.Initialize();for(var t=this.params.selector.length-1;t>=0;t--){this.BindCollection(this.params.selector[t])}}<commit_msg>minify<commit_after>/* Autocomplete.js v1.3.0 unstable developed by Baptiste Donaux | Under MIT Licence | (c) 2014, Baptiste Donaux */
var AutoComplete=function(e){this.Ajax=function(e,t,n,r,i){if(e){e.abort()}var s=t.method,o=t.url;if(s=="GET"){o+="?"+n}e=XMLHttpRequest();e.open(s,o,true);e.setRequestHeader("Content-type","application/x-www-form-urlencoded");e.setRequestHeader("Content-length",n.length);e.setRequestHeader("Connection","close");e.onreadystatechange=function(){if(e.readyState==4&&e.status==200){var n=e.response;switch(t.type){case"HTML":i.innerHTML=n;break;default:n=JSON.parse(n);var s,o=n.length,u=document.createElement("li"),a=document.createElement("ul");if(Object.prototype.toString.call(n)=="[object Array]"){if(o){for(var f=0;f<o;f++){u.innerHTML=n[f];a.appendChild(u);u=document.createElement("li")}}else{s=true;u.setAttribute("class","locked");u.innerHTML=t.noResult;a.appendChild(u)}}else{var l=Object.getOwnPropertyNames(n);for(propertie in l){u.innerHTML=n[l[propertie]];u.setAttribute("data-autocomplete-value",l[propertie]);a.appendChild(u);u=document.createElement("li")}}if(i.hasChildNodes()){i.childNodes[0].remove()}i.appendChild(a)}if(s!==true){Open(r,i)}}};e.send(n);return e};this.BindCollection=function(e){var t,n=document.querySelectorAll(e);for(var r=n.length-1;r>=0;r--){t=n[r];if(t.nodeName.toUpperCase()=="INPUT"&&t.type.toUpperCase()=="TEXT"){BindOne(t)}}};this.BindOne=function(e){if(e!=null){var t="data-autocomplete-old-value",n=document.createElement("div"),r;n.setAttribute("class","resultsAutocomplete");n.setAttribute("style","top:"+(e.offsetTop+e.offsetHeight)+"px;left:"+e.offsetLeft+"px;width:"+e.clientWidth+"px;");e.parentNode.appendChild(n);e.setAttribute("autocomplete","off");e.addEventListener("focus",function(){var r=e.getAttribute(t);if(!r||e.value!=r){n.setAttribute("class","resultsAutocomplete open")}});e.addEventListener("blur",function(){Close(n)});e.addEventListener("keyup",function(e){var i=e.currentTarget,s=i.value;if(s){var o=CustParams(i),u=o.paramName+"="+s;if(o.url){var a=i.getAttribute(t);if(!a||s!=a){n.setAttribute("class","resultsAutocomplete open")}r=Ajax(r,o,u,i,n)}}})}};this.Close=function(e,t){t?e.setAttribute("class","resultsAutocomplete"):setTimeout(function(){Close(e,true)},150)};this.Initialize=function(){var e={method:"GET",paramName:"q",selector:["input[data-autocomplete]"],type:"JSON",noResult:"No result"};if(this.params===undefined){this.params={}}this.params=Merge(e,this.params);this.params.method=this.params.method.toUpperCase();this.params.type=this.params.type.toUpperCase();if(!this.params.method.match("^GET|POST$")){this.params.method=e.method}if(!this.params.type.match("^JSON|HTML$")){this.params.type=e.type}if(!Array.isArray(this.params.selector)){this.params.selector=e.selector}};this.CreateCustParams=function(e){var t={url:e.getAttribute("data-autocomplete"),method:e.getAttribute("data-autocomplete-method"),paramName:e.getAttribute("data-autocomplete-param-name"),type:e.getAttribute("data-autocomplete-type"),noResult:e.getAttribute("data-autocomplete-no-result")};for(var n in t){if(t.hasOwnProperty(n)&&!t[n]){delete t[n]}}if(t.method){!t.method.match("^GET|POST$")?delete t.method:t.method=t.method.toUpperCase()}if(t.type){!t.type.match("^JSON|HTML$")?delete t.type:t.type=t.type.toUpperCase()}return Merge(this.params,t)};this.CustParams=function(e){var t="data-autocomplete-id";if(e.hasAttribute(t)){return this.customParams[e.getAttribute(t)]}else{e.setAttribute(t,this.customParams.length);var n=CreateCustParams(e);this.customParams.push(n);return n}};this.Open=function(e,t){var n=t.getElementsByTagName("li");for(var r=n.length-1;r>=0;r--){n[r].addEventListener("click",function(t){var n=t.currentTarget,r="data-autocomplete-value";e.value=n.hasAttribute(r)?n.getAttribute(r):n.innerHTML;e.setAttribute("data-autocomplete-old-value",e.value)})}};this.Merge=function(e,t){var n={};for(var r in e){n[r]=e[r]}for(var r in t){n[r]=t[r]}return n};this.params=e;this.customParams=new Array;this.Initialize();for(var t=this.params.selector.length-1;t>=0;t--){this.BindCollection(this.params.selector[t])}}<|endoftext|>


<commit_before>/** @babel */
/** @jsx etch.dom */

import path from 'path'
import electron from 'electron'
import {CompositeDisposable, TextEditor} from 'atom'
import etch from 'etch'

import PackageCard from './package-card'
import ErrorView from './error-view'

const PackageNameRegex = /config\/install\/(package|theme):([a-z0-9-_]+)/i
import hostedGitInfo from 'hosted-git-info'

export default class InstallPanel {
  constructor (settingsView, packageManager) {
    this.settingsView = settingsView
    this.packageManager = packageManager
    this.disposables = new CompositeDisposable()
    this.client = this.packageManager.getClient()
    this.atomIoURL = 'https://atom.io/packages'

    etch.initialize(this)

    this.refs.searchMessage.style.display = 'none'

    this.refs.searchEditor.setPlaceholderText('Search packages')
    this.searchType = 'packages'
    this.disposables.add(
      this.packageManager.on('package-install-failed', ({pack, error}) => {
        this.refs.searchErrors.appendChild(new ErrorView(this.packageManager, error).element)
      })
    )
    this.disposables.add(
      this.packageManager.on('package-installed theme-installed', ({pack}) => {
        const gitUrlInfo =
          (this.currentGitPackageCard && this.currentGitPackageCard.pack && this.currentGitPackageCard.pack.gitUrlInfo) ?
          this.currentGitPackageCard.pack.gitUrlInfo :
          null

        if (gitUrlInfo && gitUrlInfo === pack.gitUrlInfo) {
          this.updateGitPackageCard(pack)
        }
      })
    )

    this.disposables.add(atom.commands.add(this.refs.searchEditor.element, 'core:confirm', () => {
      this.performSearch()
    }))
    this.disposables.add(atom.commands.add(this.element, {
      'core:move-up': () => { this.scrollUp() },
      'core:move-down': () => { this.scrollDown() },
      'core:page-up': () => { this.pageUp() },
      'core:page-down': () => { this.pageDown() },
      'core:move-to-top': () => { this.scrollToTop() },
      'core:move-to-bottom': () => { this.scrollToBottom() }
    }))

    this.loadFeaturedPackages()
  }

  destroy () {
    this.disposables.dispose()
    return etch.destroy(this)
  }

  update () {}

  focus () {
    this.refs.searchEditor.element.focus()
  }

  show () {
    this.element.style.display = ''
  }

  render () {
    return (

Install Packages

              Packages are published to
              atom.io
               and are installed to {path.join(process.env.ATOM_HOME, 'packages')}

                <TextEditor mini ref='searchEditor' />

                <button ref='searchPackagesButton' className='btn btn-default selected' onclick={this.didClickSearchPackagesButton.bind(this)}>Packages</button>
                <button ref='searchThemesButton' className='btn btn-default' onclick={this.didClickSearchThemesButton.bind(this)}>Themes</button>

    )
  }

  setSearchType (searchType) {
    if (searchType === 'theme') {
      this.searchType = 'themes'
      this.refs.searchThemesButton.classList.add('selected')
      this.refs.searchPackagesButton.classList.remove('selected')
      this.refs.searchEditor.setPlaceholderText('Search themes')
      this.refs.publishedToText.textContent = 'Themes are published to '
      this.atomIoURL = 'https://atom.io/themes'
      this.loadFeaturedPackages(true)
    } else if (searchType === 'package') {
      this.searchType = 'packages'
      this.refs.searchPackagesButton.classList.add('selected')
      this.refs.searchThemesButton.classList.remove('selected')
      this.refs.searchEditor.setPlaceholderText('Search packages')
      this.refs.publishedToText.textContent = 'Packages are published to '
      this.atomIoURL = 'https://atom.io/packages'
      this.loadFeaturedPackages()
    }
  }

  beforeShow (options) {
    if (options && options.uri) {
      const query = this.extractQueryFromURI(options.uri)
      if (query != null) {
        const {searchType, packageName} = query
        this.setSearchType(searchType)
        this.refs.searchEditor.setText(packageName)
        this.performSearch()
      }
    }
  }

  extractQueryFromURI (uri) {
    const matches = PackageNameRegex.exec(uri)
    if (matches) {
      const [, searchType, packageName] = Array.from(matches)
      return {searchType, packageName}
    } else {
      return null
    }
  }

  performSearch () {
    const query = this.refs.searchEditor.getText().trim().toLowerCase()
    if (query) {
      this.performSearchForQuery(query)
    }
  }

  performSearchForQuery (query) {
    let gitUrlInfo
    if (gitUrlInfo = hostedGitInfo.fromUrl(query)) {
      const type = gitUrlInfo.default
      if (type === 'sshurl' || type === 'https' || type === 'shortcut') {
        this.showGitInstallPackageCard({name: query, gitUrlInfo})
      }
    } else {
      this.search(query)
    }
  }

  showGitInstallPackageCard (pack) {
    if (this.currentGitPackageCard) {
      this.currentGitPackageCard.destroy()
    }

    this.currentGitPackageCard = this.getPackageCardView(pack)
    this.currentGitPackageCard.displayGitPackageInstallInformation()
    this.replaceCurrentGitPackageCardView()
  }

  updateGitPackageCard (pack) {
    if (this.currentGitPackageCard) {
      this.currentGitPackageCard.destroy()
    }

    this.currentGitPackageCard = this.getPackageCardView(pack)
    this.replaceCurrentGitPackageCardView()
  }

  replaceCurrentGitPackageCardView () {
    this.refs.resultsContainer.innerHTML = ''
    this.addPackageCardView(this.refs.resultsContainer, this.currentGitPackageCard)
  }

  async search (query) {
    this.refs.resultsContainer.innerHTML = ''
    this.refs.searchMessage.textContent = `Searching ${this.searchType} for \u201C${query}\u201D\u2026`
    this.refs.searchMessage.style.display = ''

    const options = {}
    options[this.searchType] = true

    try {
      const packages = (await this.client.search(query, options)) || []
      this.refs.resultsContainer.innerHTML = ''
      this.refs.searchMessage.style.display = 'none'
      if (packages.length === 0) {
        this.showNoResultMessage(query)
      }
      this.highlightExactMatch(this.refs.resultsContainer, query, packages)
      this.addCloseMatches(this.refs.resultsContainer, query, packages)
      this.addPackageViews(this.refs.resultsContainer, packages)
    } catch (error) {
      this.refs.searchMessage.style.display = 'none'
      this.refs.searchErrors.appendChild(new ErrorView(this.packageManager, error).element)
    }
  }

  showNoResultMessage (query) {
    this.refs.searchMessage.textContent = `No ${this.searchType.replace(/s$/, '')} results for \u201C${query}\u201D`
    this.refs.searchMessage.style.display = ''
  }

  highlightExactMatch (container, query, packages) {
    const exactMatch = packages.filter(pkg => pkg.name === query)[0]

    if (exactMatch) {
      this.addPackageCardView(container, this.getPackageCardView(exactMatch))
      packages.splice(packages.indexOf(exactMatch), 1)
    }
  }

  addCloseMatches (container, query, packages) {
    const matches = packages.filter(pkg => pkg.name.indexOf(query) >= 0)

    for (let pack of matches) {
      this.addPackageCardView(container, this.getPackageCardView(pack))
      packages.splice(packages.indexOf(pack), 1)
    }
  }

  addPackageViews (container, packages) {
    for (const pack of packages) {
      this.addPackageCardView(container, this.getPackageCardView(pack))
    }
  }

  addPackageCardView (container, packageCard) {
    const packageRow = document.createElement('div')
    packageRow.classList.add('row')
    packageRow.appendChild(packageCard.element)
    container.appendChild(packageRow)
  }

  getPackageCardView (pack) {
    return new PackageCard(pack, this.settingsView, this.packageManager, {back: 'Install'})
  }

  filterPackages (packages, themes) {
    return packages.filter(({theme}) => themes ? theme : !theme)
  }

  // Load and display the featured packages that are available to install.
  loadFeaturedPackages (loadThemes) {
    if (loadThemes == null) {
      loadThemes = false
    }
    this.refs.featuredContainer.innerHTML = ''

    if (loadThemes) {
      this.refs.installHeading.textContent = 'Install Themes'
      this.refs.featuredHeading.textContent = 'Featured Themes'
      this.refs.loadingMessage.textContent = 'Loading featured themes\u2026'
    } else {
      this.refs.installHeading.textContent = 'Install Packages'
      this.refs.featuredHeading.textContent = 'Featured Packages'
      this.refs.loadingMessage.textContent = 'Loading featured packages\u2026'
    }

    this.refs.loadingMessage.style.display = ''

    const handle = error => {
      this.refs.loadingMessage.style.display = 'none'
      this.refs.featuredErrors.appendChild(new ErrorView(this.packageManager, error).element)
    }

    if (loadThemes) {
      this.client.featuredThemes((error, themes) => {
        if (error) {
          handle(error)
        } else {
          this.refs.loadingMessage.style.display = 'none'
          this.refs.featuredHeading.textContent = 'Featured Themes'
          this.addPackageViews(this.refs.featuredContainer, themes)
        }
      })
    } else {
      this.client.featuredPackages((error, packages) => {
        if (error) {
          handle(error)
        } else {
          this.refs.loadingMessage.style.display = 'none'
          this.refs.featuredHeading.textContent = 'Featured Packages'
          this.addPackageViews(this.refs.featuredContainer, packages)
        }
      })
    }
  }

  didClickOpenAtomIo (event) {
    event.preventDefault()
    electron.shell.openExternal(this.atomIoURL)
  }

  didClickSearchPackagesButton () {
    if (!this.refs.searchPackagesButton.classList.contains('selected')) {
      this.setSearchType('package')
    }

    this.performSearch()
  }

  didClickSearchThemesButton () {
    if (!this.refs.searchThemesButton.classList.contains('selected')) {
      this.setSearchType('theme')
    }

    this.performSearch()
  }

  scrollUp () {
    this.element.scrollTop -= document.body.offsetHeight / 20
  }

  scrollDown () {
    this.element.scrollTop += document.body.offsetHeight / 20
  }

  pageUp () {
    this.element.scrollTop -= this.element.offsetHeight
  }

  pageDown () {
    this.element.scrollTop += this.element.offsetHeight
  }

  scrollToTop () {
    this.element.scrollTop = 0
  }

  scrollToBottom () {
    this.element.scrollTop = this.element.scrollHeight
  }
}
<commit_msg>Fix highlighted results not working on search results that contain uppercase letters<commit_after>/** @babel */
/** @jsx etch.dom */

import path from 'path'
import electron from 'electron'
import {CompositeDisposable, TextEditor} from 'atom'
import etch from 'etch'

import PackageCard from './package-card'
import ErrorView from './error-view'

const PackageNameRegex = /config\/install\/(package|theme):([a-z0-9-_]+)/i
import hostedGitInfo from 'hosted-git-info'

export default class InstallPanel {
  constructor (settingsView, packageManager) {
    this.settingsView = settingsView
    this.packageManager = packageManager
    this.disposables = new CompositeDisposable()
    this.client = this.packageManager.getClient()
    this.atomIoURL = 'https://atom.io/packages'

    etch.initialize(this)

    this.refs.searchMessage.style.display = 'none'

    this.refs.searchEditor.setPlaceholderText('Search packages')
    this.searchType = 'packages'
    this.disposables.add(
      this.packageManager.on('package-install-failed', ({pack, error}) => {
        this.refs.searchErrors.appendChild(new ErrorView(this.packageManager, error).element)
      })
    )
    this.disposables.add(
      this.packageManager.on('package-installed theme-installed', ({pack}) => {
        const gitUrlInfo =
          (this.currentGitPackageCard && this.currentGitPackageCard.pack && this.currentGitPackageCard.pack.gitUrlInfo) ?
          this.currentGitPackageCard.pack.gitUrlInfo :
          null

        if (gitUrlInfo && gitUrlInfo === pack.gitUrlInfo) {
          this.updateGitPackageCard(pack)
        }
      })
    )

    this.disposables.add(atom.commands.add(this.refs.searchEditor.element, 'core:confirm', () => {
      this.performSearch()
    }))
    this.disposables.add(atom.commands.add(this.element, {
      'core:move-up': () => { this.scrollUp() },
      'core:move-down': () => { this.scrollDown() },
      'core:page-up': () => { this.pageUp() },
      'core:page-down': () => { this.pageDown() },
      'core:move-to-top': () => { this.scrollToTop() },
      'core:move-to-bottom': () => { this.scrollToBottom() }
    }))

    this.loadFeaturedPackages()
  }

  destroy () {
    this.disposables.dispose()
    return etch.destroy(this)
  }

  update () {}

  focus () {
    this.refs.searchEditor.element.focus()
  }

  show () {
    this.element.style.display = ''
  }

  render () {
    return (

Install Packages

              Packages are published to
              atom.io
               and are installed to {path.join(process.env.ATOM_HOME, 'packages')}

                <TextEditor mini ref='searchEditor' />

                <button ref='searchPackagesButton' className='btn btn-default selected' onclick={this.didClickSearchPackagesButton.bind(this)}>Packages</button>
                <button ref='searchThemesButton' className='btn btn-default' onclick={this.didClickSearchThemesButton.bind(this)}>Themes</button>

    )
  }

  setSearchType (searchType) {
    if (searchType === 'theme') {
      this.searchType = 'themes'
      this.refs.searchThemesButton.classList.add('selected')
      this.refs.searchPackagesButton.classList.remove('selected')
      this.refs.searchEditor.setPlaceholderText('Search themes')
      this.refs.publishedToText.textContent = 'Themes are published to '
      this.atomIoURL = 'https://atom.io/themes'
      this.loadFeaturedPackages(true)
    } else if (searchType === 'package') {
      this.searchType = 'packages'
      this.refs.searchPackagesButton.classList.add('selected')
      this.refs.searchThemesButton.classList.remove('selected')
      this.refs.searchEditor.setPlaceholderText('Search packages')
      this.refs.publishedToText.textContent = 'Packages are published to '
      this.atomIoURL = 'https://atom.io/packages'
      this.loadFeaturedPackages()
    }
  }

  beforeShow (options) {
    if (options && options.uri) {
      const query = this.extractQueryFromURI(options.uri)
      if (query != null) {
        const {searchType, packageName} = query
        this.setSearchType(searchType)
        this.refs.searchEditor.setText(packageName)
        this.performSearch()
      }
    }
  }

  extractQueryFromURI (uri) {
    const matches = PackageNameRegex.exec(uri)
    if (matches) {
      const [, searchType, packageName] = Array.from(matches)
      return {searchType, packageName}
    } else {
      return null
    }
  }

  performSearch () {
    const query = this.refs.searchEditor.getText().trim().toLowerCase()
    if (query) {
      this.performSearchForQuery(query)
    }
  }

  performSearchForQuery (query) {
    let gitUrlInfo
    if (gitUrlInfo = hostedGitInfo.fromUrl(query)) {
      const type = gitUrlInfo.default
      if (type === 'sshurl' || type === 'https' || type === 'shortcut') {
        this.showGitInstallPackageCard({name: query, gitUrlInfo})
      }
    } else {
      this.search(query)
    }
  }

  showGitInstallPackageCard (pack) {
    if (this.currentGitPackageCard) {
      this.currentGitPackageCard.destroy()
    }

    this.currentGitPackageCard = this.getPackageCardView(pack)
    this.currentGitPackageCard.displayGitPackageInstallInformation()
    this.replaceCurrentGitPackageCardView()
  }

  updateGitPackageCard (pack) {
    if (this.currentGitPackageCard) {
      this.currentGitPackageCard.destroy()
    }

    this.currentGitPackageCard = this.getPackageCardView(pack)
    this.replaceCurrentGitPackageCardView()
  }

  replaceCurrentGitPackageCardView () {
    this.refs.resultsContainer.innerHTML = ''
    this.addPackageCardView(this.refs.resultsContainer, this.currentGitPackageCard)
  }

  async search (query) {
    this.refs.resultsContainer.innerHTML = ''
    this.refs.searchMessage.textContent = `Searching ${this.searchType} for \u201C${query}\u201D\u2026`
    this.refs.searchMessage.style.display = ''

    const options = {}
    options[this.searchType] = true

    try {
      const packages = (await this.client.search(query, options)) || []
      this.refs.resultsContainer.innerHTML = ''
      this.refs.searchMessage.style.display = 'none'
      if (packages.length === 0) {
        this.showNoResultMessage(query)
      }
      this.highlightExactMatch(this.refs.resultsContainer, query, packages)
      this.addCloseMatches(this.refs.resultsContainer, query, packages)
      this.addPackageViews(this.refs.resultsContainer, packages)
    } catch (error) {
      this.refs.searchMessage.style.display = 'none'
      this.refs.searchErrors.appendChild(new ErrorView(this.packageManager, error).element)
    }
  }

  showNoResultMessage (query) {
    this.refs.searchMessage.textContent = `No ${this.searchType.replace(/s$/, '')} results for \u201C${query}\u201D`
    this.refs.searchMessage.style.display = ''
  }

  highlightExactMatch (container, query, packages) {
    const exactMatch = packages.filter(pkg => pkg.name.toLowerCase() === query)[0]

    if (exactMatch) {
      this.addPackageCardView(container, this.getPackageCardView(exactMatch))
      packages.splice(packages.indexOf(exactMatch), 1)
    }
  }

  addCloseMatches (container, query, packages) {
    const matches = packages.filter(pkg => pkg.name.toLowerCase().indexOf(query) >= 0)

    for (let pack of matches) {
      this.addPackageCardView(container, this.getPackageCardView(pack))
      packages.splice(packages.indexOf(pack), 1)
    }
  }

  addPackageViews (container, packages) {
    for (const pack of packages) {
      this.addPackageCardView(container, this.getPackageCardView(pack))
    }
  }

  addPackageCardView (container, packageCard) {
    const packageRow = document.createElement('div')
    packageRow.classList.add('row')
    packageRow.appendChild(packageCard.element)
    container.appendChild(packageRow)
  }

  getPackageCardView (pack) {
    return new PackageCard(pack, this.settingsView, this.packageManager, {back: 'Install'})
  }

  filterPackages (packages, themes) {
    return packages.filter(({theme}) => themes ? theme : !theme)
  }

  // Load and display the featured packages that are available to install.
  loadFeaturedPackages (loadThemes) {
    if (loadThemes == null) {
      loadThemes = false
    }
    this.refs.featuredContainer.innerHTML = ''

    if (loadThemes) {
      this.refs.installHeading.textContent = 'Install Themes'
      this.refs.featuredHeading.textContent = 'Featured Themes'
      this.refs.loadingMessage.textContent = 'Loading featured themes\u2026'
    } else {
      this.refs.installHeading.textContent = 'Install Packages'
      this.refs.featuredHeading.textContent = 'Featured Packages'
      this.refs.loadingMessage.textContent = 'Loading featured packages\u2026'
    }

    this.refs.loadingMessage.style.display = ''

    const handle = error => {
      this.refs.loadingMessage.style.display = 'none'
      this.refs.featuredErrors.appendChild(new ErrorView(this.packageManager, error).element)
    }

    if (loadThemes) {
      this.client.featuredThemes((error, themes) => {
        if (error) {
          handle(error)
        } else {
          this.refs.loadingMessage.style.display = 'none'
          this.refs.featuredHeading.textContent = 'Featured Themes'
          this.addPackageViews(this.refs.featuredContainer, themes)
        }
      })
    } else {
      this.client.featuredPackages((error, packages) => {
        if (error) {
          handle(error)
        } else {
          this.refs.loadingMessage.style.display = 'none'
          this.refs.featuredHeading.textContent = 'Featured Packages'
          this.addPackageViews(this.refs.featuredContainer, packages)
        }
      })
    }
  }

  didClickOpenAtomIo (event) {
    event.preventDefault()
    electron.shell.openExternal(this.atomIoURL)
  }

  didClickSearchPackagesButton () {
    if (!this.refs.searchPackagesButton.classList.contains('selected')) {
      this.setSearchType('package')
    }

    this.performSearch()
  }

  didClickSearchThemesButton () {
    if (!this.refs.searchThemesButton.classList.contains('selected')) {
      this.setSearchType('theme')
    }

    this.performSearch()
  }

  scrollUp () {
    this.element.scrollTop -= document.body.offsetHeight / 20
  }

  scrollDown () {
    this.element.scrollTop += document.body.offsetHeight / 20
  }

  pageUp () {
    this.element.scrollTop -= this.element.offsetHeight
  }

  pageDown () {
    this.element.scrollTop += this.element.offsetHeight
  }

  scrollToTop () {
    this.element.scrollTop = 0
  }

  scrollToBottom () {
    this.element.scrollTop = this.element.scrollHeight
  }
}
<|endoftext|>