<commit_before>(function($) {

var c_aNumberSegments = [0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F]; //http://en.wikipedia.org/wiki/Seven-segment_display
var c_sClassSvg = "sevenSeg-svg";
var c_sClassSegOn = "sevenSeg-segOn";

// Default CSS styles. If you don't specify your own CSS or discrete color options, this is what gets used.
//
$("<style type='text/css'>"
    + "." + c_sClassSvg + "{fill: #320000; overflow: hidden; stroke-width: 0; height: 100%; width: 100%; background-color: Black}"
    + "." + c_sClassSegOn + "{fill: Red}"
    + "</style>")
    .prependTo("head");

$.widget("bw.sevenSegDigit", {

options: {
    /**
    This option controls the display value on the 7seg.  Set this to the numeric digit you
    want displayed.
    */
    value: null,

    /**
    Override the default segment on color (Red).
    Note: You can alternatively define a CSS style for the class.sevenSeg-segOn that specifies a 'fill' color.
    */
    colorOn: null,

    /**
    Override the default segment off color (#320000).
    Note: You can alternatively define a CSS style for the class .sevenSeg-svg that specifies a 'fill' color.
    */
    colorOff: null,

    /**
    Override the default background color of the display (Black).
    Note: You can alternatively define a CSS style for the class .sevenSeg-svg that specifies a 'background-color' color.
    */
    colorBackground: null,

    /**
    This option allows skewing the segments to create a slant effect.
    Note: Setting "transform: skew()" in CSS is problematic for SVG. Would be nice to have, but browser support just
    isn't there yet. So, setting the slant must be done through options.
    */
    slant: 0,

    /**
    This flag controls the appearance of the decimal point 'dot' in the display.
    The default is to display it (true), but you can set to false to omit it.
    */
    decimalPoint: true
},

/**
Widget factory creation handler.
*/
_create: function () {
    this.jqSvgElement = $("<svg/>", {
        class: c_sClassSvg,
        viewBox: "0 0 57 80",
        version: "1.1",
        xmlns: "http://www.w3.org/2000/svg",
        "xmlns:xlink": "http://www.w3.org/1999/xlink",
        focusable: false // Prevent IE11 from creating a tabstop (Issue #8)
    })
    .css({fill: this.options.colorOff, "background-color": this.options.colorBackground})    ;

    $("<defs/>")
        .append($("<polyline/>", {id: "h-seg", points:"11 0, 37 0, 42 5, 37 10, 11 10, 6 5"}))
        .append($("<polyline/>", {id: "v-seg", points:"0 11, 5 6, 10 11, 10 34, 5 39, 0 39"}))
        .appendTo(this.jqSvgElement);

    this.jqSegments = $("<g/>", {class: this.widgetName + "-segGroup"})
        .append($("<use/>", {"xlink:href": "#h-seg", x: "0", y: "0"}))                                  //Segment A
        .append($("<use/>", {"xlink:href": "#v-seg", x: "-48", y: "0", transform: "scale(-1,1)"}))      //Segment B
        .append($("<use/>", {"xlink:href": "#v-seg", x: "-48", y: "-80", transform: "scale(-1,-1)"}))   //Segment C
        .append($("<use/>", {"xlink:href": "#h-seg", x: "0", y: "70"}))                                 //Segment D
        .append($("<use/>", {"xlink:href": "#v-seg", x: "0", y: "-80", transform: "scale(1,-1)"}))      //Segment E
        .append($("<use/>", {"xlink:href": "#v-seg", x: "0", y: "0"}))                                  //Segment F
        .append($("<use/>", {"xlink:href": "#h-seg", x: "0", y: "35"}))                                 //Segment G
        .appendTo(this.jqSvgElement);

    if(this.options.slant) {
        this.jqSegments.attr("transform", "skewX(" + -this.options.slant + ")");
    }

    if(this.options.decimalPoint) {
        $("<circle/>", {cx:"52", cy:"75", r:"5"}).appendTo(this.jqSvgElement);
    }

    this.jqSvgElement.appendTo(this.element);

    // http://stackoverflow.com/a/13654655/390906
    //
    this.element.html(this.element.html());
    this.jqSvgElement = this.element.find("svg");
    this.jqSegments = this.jqSvgElement.find("." + this.widgetName + "-segGroup");

    if(this.options.value) {
        this.displayValue(this.options.value);
    }
},

_destroy: function() {
    this.jqSvgElement.remove();
},

_setOption: function(key, value){
	this.options[key] = value;

	switch(key){
		case "value":
			this.displayValue(value);
			break;
	}
},

/**
This is the method to set the digit displayed.
@param value The numeric digit to display.  Call with null to blank out the display.
@param bDecimalPoint Set to true or false to drive the illumination state of the decimal point
(does not apply if decimal point display is disabled)
*/
displayValue: function(value, bDecimalPoint) {
    var self = this;
    if (value >= c_aNumberSegments.length) return;
    self.options.value = value;
    var segments = self._getSegments(value);
    self.jqSegments.children().each(function(index, element) {
        self._setSvgElementFill($(element), segments & (1 << index));
    });

    self._setSvgElementFill(self.jqSvgElement.find("circle"), bDecimalPoint);
},

/**
Return the bitfield mask for the segments to illuminate for the argumen numeric digit value.
*/
_getSegments: function(value) {
    if(value === "-") return 0x40;
    return c_aNumberSegments[value];
},

_setSvgElementFill: function(jqElement, bOn) {
    // jQuery addClass/removeClass doesn't work with svg <use> elements. So we have to do it the old way.
    //
    jqElement.attr("class", bOn && c_sClassSegOn);

    // Set the fill style if options.colorOn is defined. This overrides CSS definitions.
    //
    jqElement.css("fill", (bOn && this.options.colorOn) || "");
}

});

/**
This widget creates a group comprised of any number of discrete sevenSegDigits.
*/
$.widget("bw.sevenSeg", {

options: {
    /**
    This option controls the display value on the 7seg array.  Set this to the numeric value you
    want displayed.
    */
    value: null,

    /**
    Defines the number of digits that comprise the array.
    */
    digits: 1,

    /**
    Set this to true to allow sevenSeg to respond to the mousewheel event, which
    will allow you to change the display value by spinning the mousewheel up or down.
    (The default step is +/- 1, but you can set that in the step option).
    */
    allowInput: false,

    /**
    This setting controls the +/- delta value whenever the sevenSeg is incremented up or down (via mousewheel).
    The allowInput option must be true for this setting to be of use.
    */
    step: 1,

    /**
    This controls the number of decimal places displayed.  The default -1 results in no rounding and displays the value
    as-is.  A value of 0 or more defines the number of fixed decimal places that the numeric value will be rounded to.

    If you intend to set display values that are the result of floating point operations, including the
    use of allowInput=true and a fractional step size, then you most definitely want to set this to a specific value to
    avoid overflowing the display from floating point inaccuracies.
    */
    decimalPlaces: -1
},

/**
Widget factory creation handler. This will create N number of sevenSegDigit widgets, one for each digit.
*/
_create: function () {
    this.aJqDigits = [];
    var sDigitWidth = this.options.digits && (100 / this.options.digits + "%");

    for(var iDigit = 0; iDigit < this.options.digits; ++iDigit) {
        this.aJqDigits[iDigit] = $("<div/>", {style: "display: inline-block; height: 100%;"})
            .css("width", sDigitWidth)
            .sevenSegDigit(this.options)
            .appendTo(this.element);
    }

    this.aJqDigits.reverse();
    this._displayValue(this.options.value);
    this._bindMouseWheel();
},

_destroy: function() {
    $.each(this.aJqDigits, function(index, jqDigit) {
        jqDigit.sevenSegDigit("destroy");
        jqDigit.remove();
    });
},

/**
Setup event handler for mousewheel spins, if options.allowInput is set.
This will inc/dec the display value in response to spinning the wheel up or down.
*/
_bindMouseWheel: function () {
    var self = this;

    // Chrome and IE use the "mousewheel" event while FF uses "wheel".
    //
    var sEventName = "onwheel" in document ? "wheel" : "mousewheel";

    self._off(self.element, sEventName);
    if (!self.options.allowInput) return;

    var eventHandler = {};
    eventHandler[sEventName] = function (eventInfo) {
        var step = self.options.step;

        // Chrome and IE specify wheelDelta while FF uses deltaY (with reverse polarity).
        //
        var delta = eventInfo.originalEvent.wheelDelta || -eventInfo.originalEvent.deltaY;
        if (delta < 0) step = -step;

        self.option("value", parseFloat(self.options.value, 10) + step);
        eventInfo.preventDefault();
    };

    self._on(eventHandler);
},

_setOption: function(key, value){
	this.options[key] = value;

	switch(key){
		case "value":
			this._displayValue(value);
			break;

        // TODO BW : Add other options.
	}
},

/**
Set the value of the digits to display.  You simply call this with a number and the respective
digits will be set.  Whatever digits that fit will be displayed, any additional will just be omitted.
@param value The numeric value to display.  Call with null to blank out the display.
*/
_displayValue: function(value) {
    var self = this;
    var sValue = self._createValueString(value);
    var iDecimalIdx = sValue.indexOf('.');
    var iDigitIdx = sValue.length - 1;

    $.each(self.aJqDigits, function(index, jqDigit) {
        var bDecimal = iDecimalIdx >= 0 && iDigitIdx === iDecimalIdx;
        if(bDecimal) {
            --iDigitIdx;
        }

        var sDigitValue = sValue[iDigitIdx];
        jqDigit.sevenSegDigit("displayValue", sDigitValue, bDecimal);

        --iDigitIdx;
    });

    self._trigger("change", null, value);
},

/**
Given a value that can be a string, numeric, or null, form and return a string to use for driving the display.
If the value is null, then an empty string is returned.  Otherwise, the value is rounded to options.decimalPlaces
and returned in string form.
*/
_createValueString: function (value) {
    if (!value) return "";
    if (this.options.decimalPlaces < 0) return value.toString();

    var fValue = parseFloat(value, 10);
    return fValue.toFixed(this.options.decimalPlaces);
}

});

// Plugin the Knockout binding handler for sevenSeg if KO is defined.
//
if(ko && ko.bindingHandlers) {
	ko.bindingHandlers.sevenSeg = {
	    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
	        var bindingValue = valueAccessor();
	        $(element).sevenSeg(ko.toJS(bindingValue));

	        // Setup event handler to mutate value observable whenever sevenSeg's value changes.
            //
	        if (ko.isWriteableObservable(bindingValue.value)) {
	            $(element).on("sevensegchange", function (event, value) {
	                bindingValue.value(value);
	            });
	        }
	    },

	    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
			$(element).sevenSeg(ko.toJS(valueAccessor()));
		}
	};
}

})(jQuery);
<commit_msg>Fixed initialization error (due to knockout dependency)<commit_after>(function(global, $) {

var c_aNumberSegments = [0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F]; //http://en.wikipedia.org/wiki/Seven-segment_display
var c_sClassSvg = "sevenSeg-svg";
var c_sClassSegOn = "sevenSeg-segOn";

// Default CSS styles. If you don't specify your own CSS or discrete color options, this is what gets used.
//
$("<style type='text/css'>"
    + "." + c_sClassSvg + "{fill: #320000; overflow: hidden; stroke-width: 0; height: 100%; width: 100%; background-color: Black}"
    + "." + c_sClassSegOn + "{fill: Red}"
    + "</style>")
    .prependTo("head");

$.widget("bw.sevenSegDigit", {

options: {
    /**
    This option controls the display value on the 7seg.  Set this to the numeric digit you
    want displayed.
    */
    value: null,

    /**
    Override the default segment on color (Red).
    Note: You can alternatively define a CSS style for the class.sevenSeg-segOn that specifies a 'fill' color.
    */
    colorOn: null,

    /**
    Override the default segment off color (#320000).
    Note: You can alternatively define a CSS style for the class .sevenSeg-svg that specifies a 'fill' color.
    */
    colorOff: null,

    /**
    Override the default background color of the display (Black).
    Note: You can alternatively define a CSS style for the class .sevenSeg-svg that specifies a 'background-color' color.
    */
    colorBackground: null,

    /**
    This option allows skewing the segments to create a slant effect.
    Note: Setting "transform: skew()" in CSS is problematic for SVG. Would be nice to have, but browser support just
    isn't there yet. So, setting the slant must be done through options.
    */
    slant: 0,

    /**
    This flag controls the appearance of the decimal point 'dot' in the display.
    The default is to display it (true), but you can set to false to omit it.
    */
    decimalPoint: true
},

/**
Widget factory creation handler.
*/
_create: function () {
    this.jqSvgElement = $("<svg/>", {
        class: c_sClassSvg,
        viewBox: "0 0 57 80",
        version: "1.1",
        xmlns: "http://www.w3.org/2000/svg",
        "xmlns:xlink": "http://www.w3.org/1999/xlink",
        focusable: false // Prevent IE11 from creating a tabstop (Issue #8)
    })
    .css({fill: this.options.colorOff, "background-color": this.options.colorBackground})    ;

    $("<defs/>")
        .append($("<polyline/>", {id: "h-seg", points:"11 0, 37 0, 42 5, 37 10, 11 10, 6 5"}))
        .append($("<polyline/>", {id: "v-seg", points:"0 11, 5 6, 10 11, 10 34, 5 39, 0 39"}))
        .appendTo(this.jqSvgElement);

    this.jqSegments = $("<g/>", {class: this.widgetName + "-segGroup"})
        .append($("<use/>", {"xlink:href": "#h-seg", x: "0", y: "0"}))                                  //Segment A
        .append($("<use/>", {"xlink:href": "#v-seg", x: "-48", y: "0", transform: "scale(-1,1)"}))      //Segment B
        .append($("<use/>", {"xlink:href": "#v-seg", x: "-48", y: "-80", transform: "scale(-1,-1)"}))   //Segment C
        .append($("<use/>", {"xlink:href": "#h-seg", x: "0", y: "70"}))                                 //Segment D
        .append($("<use/>", {"xlink:href": "#v-seg", x: "0", y: "-80", transform: "scale(1,-1)"}))      //Segment E
        .append($("<use/>", {"xlink:href": "#v-seg", x: "0", y: "0"}))                                  //Segment F
        .append($("<use/>", {"xlink:href": "#h-seg", x: "0", y: "35"}))                                 //Segment G
        .appendTo(this.jqSvgElement);

    if(this.options.slant) {
        this.jqSegments.attr("transform", "skewX(" + -this.options.slant + ")");
    }

    if(this.options.decimalPoint) {
        $("<circle/>", {cx:"52", cy:"75", r:"5"}).appendTo(this.jqSvgElement);
    }

    this.jqSvgElement.appendTo(this.element);

    // http://stackoverflow.com/a/13654655/390906
    //
    this.element.html(this.element.html());
    this.jqSvgElement = this.element.find("svg");
    this.jqSegments = this.jqSvgElement.find("." + this.widgetName + "-segGroup");

    if(this.options.value) {
        this.displayValue(this.options.value);
    }
},

_destroy: function() {
    this.jqSvgElement.remove();
},

_setOption: function(key, value){
	this.options[key] = value;

	switch(key){
		case "value":
			this.displayValue(value);
			break;
	}
},

/**
This is the method to set the digit displayed.
@param value The numeric digit to display.  Call with null to blank out the display.
@param bDecimalPoint Set to true or false to drive the illumination state of the decimal point
(does not apply if decimal point display is disabled)
*/
displayValue: function(value, bDecimalPoint) {
    var self = this;
    if (value >= c_aNumberSegments.length) return;
    self.options.value = value;
    var segments = self._getSegments(value);
    self.jqSegments.children().each(function(index, element) {
        self._setSvgElementFill($(element), segments & (1 << index));
    });

    self._setSvgElementFill(self.jqSvgElement.find("circle"), bDecimalPoint);
},

/**
Return the bitfield mask for the segments to illuminate for the argumen numeric digit value.
*/
_getSegments: function(value) {
    if(value === "-") return 0x40;
    return c_aNumberSegments[value];
},

_setSvgElementFill: function(jqElement, bOn) {
    // jQuery addClass/removeClass doesn't work with svg <use> elements. So we have to do it the old way.
    //
    jqElement.attr("class", bOn && c_sClassSegOn);

    // Set the fill style if options.colorOn is defined. This overrides CSS definitions.
    //
    jqElement.css("fill", (bOn && this.options.colorOn) || "");
}

});

/**
This widget creates a group comprised of any number of discrete sevenSegDigits.
*/
$.widget("bw.sevenSeg", {

options: {
    /**
    This option controls the display value on the 7seg array.  Set this to the numeric value you
    want displayed.
    */
    value: null,

    /**
    Defines the number of digits that comprise the array.
    */
    digits: 1,

    /**
    Set this to true to allow sevenSeg to respond to the mousewheel event, which
    will allow you to change the display value by spinning the mousewheel up or down.
    (The default step is +/- 1, but you can set that in the step option).
    */
    allowInput: false,

    /**
    This setting controls the +/- delta value whenever the sevenSeg is incremented up or down (via mousewheel).
    The allowInput option must be true for this setting to be of use.
    */
    step: 1,

    /**
    This controls the number of decimal places displayed.  The default -1 results in no rounding and displays the value
    as-is.  A value of 0 or more defines the number of fixed decimal places that the numeric value will be rounded to.

    If you intend to set display values that are the result of floating point operations, including the
    use of allowInput=true and a fractional step size, then you most definitely want to set this to a specific value to
    avoid overflowing the display from floating point inaccuracies.
    */
    decimalPlaces: -1
},

/**
Widget factory creation handler. This will create N number of sevenSegDigit widgets, one for each digit.
*/
_create: function () {
    this.aJqDigits = [];
    var sDigitWidth = this.options.digits && (100 / this.options.digits + "%");

    for(var iDigit = 0; iDigit < this.options.digits; ++iDigit) {
        this.aJqDigits[iDigit] = $("<div/>", {style: "display: inline-block; height: 100%;"})
            .css("width", sDigitWidth)
            .sevenSegDigit(this.options)
            .appendTo(this.element);
    }

    this.aJqDigits.reverse();
    this._displayValue(this.options.value);
    this._bindMouseWheel();
},

_destroy: function() {
    $.each(this.aJqDigits, function(index, jqDigit) {
        jqDigit.sevenSegDigit("destroy");
        jqDigit.remove();
    });
},

/**
Setup event handler for mousewheel spins, if options.allowInput is set.
This will inc/dec the display value in response to spinning the wheel up or down.
*/
_bindMouseWheel: function () {
    var self = this;

    // Chrome and IE use the "mousewheel" event while FF uses "wheel".
    //
    var sEventName = "onwheel" in document ? "wheel" : "mousewheel";

    self._off(self.element, sEventName);
    if (!self.options.allowInput) return;

    var eventHandler = {};
    eventHandler[sEventName] = function (eventInfo) {
        var step = self.options.step;

        // Chrome and IE specify wheelDelta while FF uses deltaY (with reverse polarity).
        //
        var delta = eventInfo.originalEvent.wheelDelta || -eventInfo.originalEvent.deltaY;
        if (delta < 0) step = -step;

        self.option("value", parseFloat(self.options.value, 10) + step);
        eventInfo.preventDefault();
    };

    self._on(eventHandler);
},

_setOption: function(key, value){
	this.options[key] = value;

	switch(key){
		case "value":
			this._displayValue(value);
			break;

        // TODO BW : Add other options.
	}
},

/**
Set the value of the digits to display.  You simply call this with a number and the respective
digits will be set.  Whatever digits that fit will be displayed, any additional will just be omitted.
@param value The numeric value to display.  Call with null to blank out the display.
*/
_displayValue: function(value) {
    var self = this;
    var sValue = self._createValueString(value);
    var iDecimalIdx = sValue.indexOf('.');
    var iDigitIdx = sValue.length - 1;

    $.each(self.aJqDigits, function(index, jqDigit) {
        var bDecimal = iDecimalIdx >= 0 && iDigitIdx === iDecimalIdx;
        if(bDecimal) {
            --iDigitIdx;
        }

        var sDigitValue = sValue[iDigitIdx];
        jqDigit.sevenSegDigit("displayValue", sDigitValue, bDecimal);

        --iDigitIdx;
    });

    self._trigger("change", null, value);
},

/**
Given a value that can be a string, numeric, or null, form and return a string to use for driving the display.
If the value is null, then an empty string is returned.  Otherwise, the value is rounded to options.decimalPlaces
and returned in string form.
*/
_createValueString: function (value) {
    if (!value) return "";
    if (this.options.decimalPlaces < 0) return value.toString();

    var fValue = parseFloat(value, 10);
    return fValue.toFixed(this.options.decimalPlaces);
}

});

// Plugin the Knockout binding handler for sevenSeg if KO is defined.
//
if(global.ko && ko.bindingHandlers) {
	ko.bindingHandlers.sevenSeg = {
	    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
	        var bindingValue = valueAccessor();
	        $(element).sevenSeg(ko.toJS(bindingValue));

	        // Setup event handler to mutate value observable whenever sevenSeg's value changes.
            //
	        if (ko.isWriteableObservable(bindingValue.value)) {
	            $(element).on("sevensegchange", function (event, value) {
	                bindingValue.value(value);
	            });
	        }
	    },

	    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
			$(element).sevenSeg(ko.toJS(valueAccessor()));
		}
	};
}

})(this, jQuery);
<|endoftext|>


<commit_before>(function () {
    var raim = $.connection.raimHub;
    var connected = false;

    var gameArena;

    var _playerId;

    raim.client.signedIn = function (id) {
        connected = true;
        _playerId = id;
        gameArena.setPlayer(id);
    };

    raim.client.setupArena = function (arenaData) { gameArena.setupArena(arenaData); };

    raim.client.registered = function (player) { gameArena.addNewPlayer(player); }
    raim.client.signedOff = function (player) { gameArena.removePlayer(player); }
    raim.client.otherPlayers = function (players) {
        for (var i = 0; i < players.length; i++) {
            gameArena.addNewPlayer(players[i]);
        }
    };

    raim.client.playerMoved = function (gameState) { gameArena.playerMoved(gameState); }

    function signOff() {
        console.log("unloading");
        raim.server.signOff(_playerId);
    }

    var playerName = document.getElementById("playerName");
    var playButton = document.getElementById("playButton");

    playerName.addEventListener("keyup", function () {
        if (event.keyCode == 13) playButton.click();
    });
    playerName.value = localStorage.getItem("playerName");

    playButton.addEventListener("click", function () {
        $.connection.hub.start().done(function () {

            document.getElementById("registration").style.display = "none";
            var arenaElement = document.getElementById("arena").style.display = "block";

            gameArena = new arena({
                playerMoving: function (e) {
                    if (!connected) return;

                    raim.server.playerMoving(e);
                },
                signOut: function () {
                    if (!connected)
                        return;

                    gameArena.stop();

                    $.connection.hub.stop();
                    connected = false;
                    document.getElementById("registration").style.display = "block";

                    var arenaElement = document.getElementById("arena");
                    arenaElement.style.display = "none";

                    while (arenaElement.firstChild) {
                        arenaElement.removeChild(arenaElement.firstChild);
                    }

                    var playersList = document.getElementById("playersList");
                    while (playersList.firstChild) {
                        playersList.removeChild(playersList.firstChild);
                    }
                }
            });

            var name = playerName.value || "random player";
            localStorage.setItem("playerName", name);

            raim.server.register(name);

            window.addEventListener("beforeunload", signOff);
        });
    });
})();<commit_msg>stop connection when unloading page<commit_after>(function () {
    var raim = $.connection.raimHub;
    var connected = false;

    var gameArena;

    var _playerId;

    raim.client.signedIn = function (id) {
        connected = true;
        _playerId = id;
        gameArena.setPlayer(id);
    };

    raim.client.setupArena = function (arenaData) { gameArena.setupArena(arenaData); };

    raim.client.registered = function (player) { gameArena.addNewPlayer(player); }
    raim.client.signedOff = function (player) { gameArena.removePlayer(player); }
    raim.client.otherPlayers = function (players) {
        for (var i = 0; i < players.length; i++) {
            gameArena.addNewPlayer(players[i]);
        }
    };

    raim.client.playerMoved = function (gameState) { gameArena.playerMoved(gameState); }

    function signOff() {
        raim.server.signOff(_playerId);
        $.connection.hub.stop();
    }

    var playerName = document.getElementById("playerName");
    var playButton = document.getElementById("playButton");

    playerName.addEventListener("keyup", function () {
        if (event.keyCode == 13) playButton.click();
    });
    playerName.value = localStorage.getItem("playerName");

    playButton.addEventListener("click", function () {
        $.connection.hub.start().done(function () {

            document.getElementById("registration").style.display = "none";
            var arenaElement = document.getElementById("arena").style.display = "block";

            gameArena = new arena({
                playerMoving: function (e) {
                    if (!connected) return;

                    raim.server.playerMoving(e);
                },
                signOut: function () {
                    if (!connected)
                        return;

                    gameArena.stop();

                    $.connection.hub.stop();
                    connected = false;
                    document.getElementById("registration").style.display = "block";

                    var arenaElement = document.getElementById("arena");
                    arenaElement.style.display = "none";

                    while (arenaElement.firstChild) {
                        arenaElement.removeChild(arenaElement.firstChild);
                    }

                    var playersList = document.getElementById("playersList");
                    while (playersList.firstChild) {
                        playersList.removeChild(playersList.firstChild);
                    }
                }
            });

            var name = playerName.value || "random player";
            localStorage.setItem("playerName", name);

            raim.server.register(name);

            window.addEventListener("beforeunload", signOff);
        });
    });
})();<|endoftext|>


<commit_before>var pg = require('pg').native
, connectionString = process.env.DATABASE_URL
, client
, query;

client = new pg.Client(connectionString);
client.connect();
query = client.query('CREATE TABLE tasman_table (userid text, imgName text, imagedescription text, imageurl text)');

var newTable = 'CREATE TABLE gps (address text, content text, icon text);';
	client.query(newTable); //create table

/*
CREATE TABLE tasman_table (
	user_id serial PRIMARY KEY,
	name text not null,
	imgname text not null,
	img bytea not null,
)
*/

query.on('end', function(result) {
	// console.log(JSON.stringify(result))
	client.end();
});
<commit_msg>changes<commit_after>var pg = require('pg').native
, connectionString = process.env.DATABASE_URL
, client
, query;

client = new pg.Client(connectionString);
client.connect();
// query = client.query('CREATE TABLE tasman_table (userid text, imgName text, imagedescription text, imageurl text)');

client.query('CREATE TABLE tasman_table (userid text, imgName text, imagedescription text, imageurl text)');

var newTable = 'CREATE TABLE gps (address text, content text, icon text);';
	query = client.query(newTable); //create table

/*
CREATE TABLE tasman_table (
	user_id serial PRIMARY KEY,
	name text not null,
	imgname text not null,
	img bytea not null,
)
*/

query.on('end', function(result) {
	// console.log(JSON.stringify(result))
	client.end();
});
<|endoftext|>


<commit_before>var attributes = {};
var objectclasses = {};

var re_main = /(?:[^\(]*\( *)(.+)(?: \))/;
var re_tokenize = /[\w\.-:]+|'(?:\\'|[^'])+'/g;
var re_quotedstring = /(?:')([^'\\]*(?:\\.[^'\\]*)*)/;
var is_oid = /[0-9\.]+/;
var is_keyword = /(NAME|DESC|X-ORDERED|EQUALITY|OBSOLETE|SUP|ABSTRACT|STRUCTURAL|AUXILIARY|MUST|MAY|SINGLE-VALUE|NO-USER-MODIFICATION|SYNTAX|ORDERING|SUBSTR|COLLECTIVE)/;

function parse(result, entry) {
    var x;
    var keyword;

    try {
        var items = entry.match(re_main)[1].match(re_tokenize);
        items.forEach(function(item) {
            if ((x = item.match(is_keyword)) && x[0]) {
                keyword = x[0].toLowerCase().replace(/-/, '');
                result[keyword] = true;
            } else if ((x = item.match(is_oid)) && !keyword) {
                result.oid = item;
            } else {
                // we're a value.. let's clean it up.
                if (item[0] == '\'') {
                    item = item.match(re_quotedstring)[1];
                } else if (item[0] == '(') {
                    item = item.split(/ /);
                }

                switch(typeof result[keyword]) {
                case 'boolean':
                    result[keyword] = item;
                    break;
                case 'string':
                    result[keyword] = [ result[keyword] ];
                    // nobreak - fall through
                case 'object':
                    result[keyword].push(item);
                    break;
                case 'undefined':
                    break;
                default:
                    result[keyword] = item;
                    break;
                }
            }
        });

    } catch (e) {
        console.log(e);
    }
    if (result.name && typeof result.name != 'object') {
        result.name = [ result.name ];
    }
    if (result.may && typeof result.may != 'object') {
        result.may = [ result.may ];
    }
    if (result.must && typeof result.must != 'object') {
        result.must = [ result.must ];
    }

    return;
}

function ObjectClass(str) {
    var must = {};
    var may = {};

    parse(this, str);

    for (var i in this.must) {
        var attrname = this.must[i];
        if (attributes[attrname]) {
            must[attrname] = attributes[attrname];
        }
    }
    for (var i in this.may) {
        var attrname = this.may[i];
        if (attributes[attrname]) {
            may[attrname] = attributes[attrname];
        }
    }

    this.muststr = this.must; // used for looping - so we know what name this oc uses for a given attr
    this.maystr = this.may;
    this.must = must;
    this.may = may;

    return this;
}

function Attribute(str) {
    parse(this, str);
    return this;
}

module.exports = function(ldap, opt) {
    // dummy for init_attr;
    var init_attr = function() {
        return;
    }

    // dummy for init_obj
    // which is cheaper: calling a dummy func, or  "if (func) func();" ?
    var init_obj = function() {
        return;
    }

    function getAllAttributes() {
        return attributes;
    }

    function getAllObjectClasses() {
        return objectclasses;
    }

    function getAttributesForRec(data) {
        var res = [];

        if (!data || !data.objectClass) {
            return undefined;
        }
        data.objectClass.forEach(function(oc) {
            var obj = getObjectClass(oc);
            if (obj) {
                if (obj.must) {
                    res = res.concat(obj.must);
                }
                if (obj.may) {
                    res = res.concat(obj.may);
                }
            }
        });
        return res;
    }

    function getUniqueAttributes(rec) {
        var res = {};

        if (!rec) return undefined;

        for (var i in rec.objectClass) {
            var oc = objectclasses[rec.objectClass[i]];
            if (oc.muststr) {
                oc.muststr.forEach(function(attr) {
                    res[attr] = attributes[attr];
                });
            }
            if (oc.maystr) {
                oc.maystr.forEach(function(attr) {
                    res[attr] = attributes[attr];
                });
            }
        }
        return res;
    }

    function getObjectClass(name) {
        return objectclasses[name];
    }

    function getAttribute(name) {
        return attributes[name];
    }

    if (!opt) opt = {};

    if (typeof opt.init_attr == 'function') {
        init_attr = opt.init_attr;
    }
    if (typeof opt.init_obj == 'function') {
        init_obj = opt.init_obj;
    }

    ldap.search({
        base: 'cn=subSchema',
        filter: '(objectClass=subschema)',
        attrs: 'attributeTypes objectClasses',
        scope: ldap.BASE
    }, function(err, data) {
        if (err) {
            throw err;
        }
        data.forEach(function(schemaentry) {
            schemaentry.attributeTypes.forEach(function (attr) {
                var a = new Attribute(attr);
                a.name.forEach(function(n) {
                    attributes[n] = a;
                });
                init_attr(a);
            });
        });

        // now all the attributes have been collected.
        data.forEach(function(schemaentry) {
           schemaentry.objectClasses.forEach(function (oc) {
                var a = new ObjectClass(oc);
                a.name.forEach(function(n) {
                    objectclasses[n] = a;
                });
               init_obj(a);
            });
        });
        // call the callback
        if (typeof opt.ready == 'function') {
            opt.ready();
        };
    });

    this.getObjectClass = getObjectClass;
    this.getAttribute = getAttribute;
    this.getAttributesForRec = getAttributesForRec;
    this.getUniqueAttributes = getUniqueAttributes;
    this.getAllObjectClasses = getAllObjectClasses;
    this.getAllAttributes = getAllAttributes;
}
<commit_msg>Added some extra keywords for schema parsing.<commit_after>var attributes = {};
var objectclasses = {};

var re_main = /(?:[^\(]*\( *)(.+)(?: \))/;
var re_tokenize = /[\w\.\-:\{\}]+|'(?:\\'|[^'])+'/g;
var re_quotedstring = /(?:')([^'\\]*(?:\\.[^'\\]*)*)/;
var is_oid = /[0-9\.]+/;
var is_keyword = /(NAME|DESC|X\-ORDERED|USAGE|EQUALITY|OBSOLETE|SUP|ABSTRACT|STRUCTURAL|AUXILIARY|MUST|MAY|SINGLE\-VALUE|NO\-USER\-MODIFICATION|SYNTAX|ORDERING|SUBSTR|COLLECTIVE|X\-ORDERED\-VALUES)/;

function parseSchema(entry) {
    var self = this;
    var x;
    var keyword;
    try {
        var items = entry.match(re_main)[1].match(re_tokenize);
        items.forEach(function(item) {
            if ((x = item.match(is_keyword)) && x[0]) {
                keyword = x[0].toLowerCase().replace(/-/, '');
                self[keyword] = true;
            } else if ((x = item.match(is_oid)) && !keyword) {
                self.oid = item;
            } else {
                // we're a value.. let's clean it up.
                if (item[0] == '\'') {
                    item = item.match(re_quotedstring)[1];
                } else if (item[0] == '(') {
                    item = item.split(/ /);
                }

                switch(typeof self[keyword]) {
                case 'boolean':
                    self[keyword] = item;
                    break;
                case 'string':
                    self[keyword] = [ self[keyword] ];
                    // nobreak - fall through
                case 'object':
                    self[keyword].push(item);
                    break;
                case 'undefined':
                    break;
                default:
                    self[keyword] = item;
                    break;
                }
            }
        });

    } catch (e) {
        console.log(e);
    }

    return;
}

function ObjectClass(str) {
    this.attributes = {};
    this.parse(str);

    if (!this.must) {
        this.must = [];
    } else if (typeof this.must != 'object') {
        this.must = [ this.must ];
    }
    if (!this.may) {
        this.may = [];
    } else if (typeof this.may != 'object') {
        this.may = [ this.may ];
    }
    if (!this.name) {
        this.name = [];
    } else if (typeof this.name != 'object') {
        this.name = [ this.name ];
    }

    for (var i in this.must) {
        var attrname = this.must[i];
        if (attributes[attrname]) {
            this.attributes[attrname] = attributes[attrname];
        }
    }
    for (var i in this.may) {
        var attrname = this.may[i];
        if (attributes[attrname]) {
            this.attributes[attrname] = attributes[attrname];
        }
    }
    return this;
}
ObjectClass.prototype.parse = parseSchema;

function Attribute(str) {
    this.parse(str);
    if (!this.name) {
        this.name = [];
    } else if (typeof this.name != 'object') {
        this.name = [ this.name ];
    }
    return this;
}
Attribute.prototype.parse = parseSchema;

module.exports = function(ldap, opt) {
    // dummy for init_attr;
    var init_attr = function() {
        return;
    }

    // dummy for init_obj
    // which is cheaper: calling a dummy func, or  "if (func) func();" ?
    var init_obj = function() {
        return;
    }

    function getAllAttributes() {
        return attributes;
    }

    function getAllObjectClasses() {
        return objectclasses;
    }

    function getAttributesForRec(data) {
        var res = [];

        if (!data || !data.objectClass) {
            return undefined;
        }
        data.objectClass.forEach(function(oc) {
            var obj = getObjectClass(oc);
            if (obj) {
                if (obj.must) {
                    res = res.concat(obj.must);
                }
                if (obj.may) {
                    res = res.concat(obj.may);
                }
            }
        });
        return res;
    }

    function getUniqueAttributes(rec) {
        var res = {};

        if (!rec) return undefined;

        for (var i in rec.objectClass) {
            var oc = objectclasses[rec.objectClass[i]];
            if (oc.muststr) {
                oc.muststr.forEach(function(attr) {
                    res[attr] = attributes[attr];
                });
            }
            if (oc.maystr) {
                oc.maystr.forEach(function(attr) {
                    res[attr] = attributes[attr];
                });
            }
        }
        return res;
    }

    function getObjectClass(name) {
        return objectclasses[name];
    }

    function getAttribute(name) {
        return attributes[name];
    }

    if (!opt) opt = {};

    if (typeof opt.init_attr == 'function') {
        init_attr = opt.init_attr;
    }
    if (typeof opt.init_obj == 'function') {
        init_obj = opt.init_obj;
    }

    ldap.search({
        base: 'cn=subSchema',
        filter: '(objectClass=subschema)',
        attrs: 'attributeTypes objectClasses',
        scope: ldap.BASE
    }, function(err, data) {
        if (err) {
            throw err;
        }
        data.forEach(function(schemaentry) {
            schemaentry.attributeTypes.forEach(function (attr) {
                var a = new Attribute(attr);
                a.name.forEach(function(n) {
                    attributes[n] = a;
                });
                init_attr(a);
            });
        });

        // now all the attributes have been collected.
        data.forEach(function(schemaentry) {
           schemaentry.objectClasses.forEach(function (oc) {
                var a = new ObjectClass(oc);
                a.name.forEach(function(n) {
                    objectclasses[n] = a;
                });
               init_obj(a);
            });
        });
        // call the callback
        if (typeof opt.ready == 'function') {
            opt.ready();
        };
    });

    this.getObjectClass = getObjectClass;
    this.getAttribute = getAttribute;
    this.getAttributesForRec = getAttributesForRec;
    this.getUniqueAttributes = getUniqueAttributes;
    this.getAllObjectClasses = getAllObjectClasses;
    this.getAllAttributes = getAllAttributes;
}
<|endoftext|>


<commit_before>!function(){function n(n,r){for(var t={},e=t,o=0,u=n.length-1;u>o;o++)e=e[n[o]]={};return e[n[o]]=r,t}function r(){function r(n){return n instanceof Date?n.getTime():n instanceof Array?n.map(r):n}function t(n,t,e){var o=r(e);return{k:t,v:f[n]?f[n](o):o,e:i[n]}}var e=this.test=function(n,t){for(var e=n.exprs,o=0,u=e.length;u>o;o++){var i=e[o];if(!i.e(i.v,r(t),t))return!1}return!0},o=this.parse=function(r,f){r||(r={$eq:r});var a=[];if(r&&r.constructor===Object)for(var s in r){var c;if(i[s])c=s;else{if(36===s.charCodeAt(0))throw new Error("Unknown operator "+s+".");c="$trav"}var v=r[s],$=v;if(u[c]){if(~s.indexOf(".")){var l=s.split(".");s=l.shift(),$=v=n(l,v)}if(v instanceof Array){$=[];for(var p=v.length;p--;)$.push(o(v[p]))}else $=o(v,s)}a.push(t(c,s,$))}else a.push(t("$eq",f,r));var d={exprs:a,k:f,test:function(n){return e(d,n)}};return d},u=this.traversable={$and:!0,$or:!0,$nor:!0,$trav:!0,$not:!0},i=this.testers={$eq:function(n,r){return n.test(r)},$ne:function(n,r){return!n.test(r)},$lt:function(n,r){return n>r},$gt:function(n,r){return r>n},$lte:function(n,r){return n>=r},$gte:function(n,r){return r>=n},$exists:function(n,r){return n===(null!=r)},$in:function(n,r){if(!(r instanceof Array))return~n.indexOf(r);for(var t=r.length;t--;)if(~n.indexOf(r[t]))return!0;return!1},$not:function(n,r){if(!n.test)throw new Error("$not test should include an expression, not a value. Use $ne instead.");return!n.test(r)},$type:function(n,r,t){return null!=t?t instanceof n||t.constructor==n:!1},$nin:function(n,r){return!i.$in(n,r)},$mod:function(n,r){return r%n[0]==n[1]},$all:function(n,r){r||(r=[]);for(var t=n.length;t--;){var e=n[t],o=~r.indexOf(e);if(!o)return!1}return!0},$size:function(n,r){return r?n===r.length:!1},$or:function(n,r){for(var t=n.length,o=t;t--;)if(e(n[t],r))return!0;return 0===o},$nor:function(n,r){for(var t=n.length;t--;)if(e(n[t],r))return!1;return!0},$and:function(n,r){for(var t=n.length;t--;)if(!e(n[t],r))return!1;return!0},$trav:function(n,r){if(r instanceof Array){for(var t=r.length;t--;){var o=r[t];if(o[n.k]&&e(n,o[n.k]))return!0}return!1}return e(n,r?r[n.k]:void 0)},$regex:function(n,r){var t=new RegExp(n);return t.test(r)},$where:function(n,r){return n.call(r)}},f={$eq:function(n){var r;return n instanceof RegExp?n:(r=n instanceof Function?n:function(r){return r instanceof Array?~r.indexOf(n):n===r},{test:r})},$ne:function(n){return f.$eq(n)},$where:function(n){return"string"==typeof n?new Function("return "+n):n}}}function t(n,r,t){function u(n){return f.test(i(n))}"object"!=typeof r&&(t=r,r=void 0);var i=o(t),f=e.parse(n);return r?r.filter(u):(u.query=n,u)}var e=new r,o=function(n){if(!n)return function(n){return n};if("function"==typeof n)return n;throw new Error("Unknown sift selector "+n)};t.use=function(n){n.operators&&t.useOperators(n.operators),"function"==typeof n&&n(t)},t.useOperators=function(n){for(var r in n)t.useOperator(r,n[r])},t.useOperator=function(n,r){var t={};t="object"==typeof r?r:{test:r};var o="$"+n;e.testers[o]=t.test,(t.traversable||t.traverse)&&(e.traversable[o]=!0)},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=t:"undefined"!=typeof window&&(window.sift=t)}();<commit_msg>make min<commit_after>!function(){"use strict";function n(n,r){for(var t={},e=t,o=0,u=n.length-1;u>o;o++)e=e[n[o]]={};return e[n[o]]=r,t}function r(){function r(n){return n instanceof Date?n.getTime():n instanceof Array?n.map(r):n}function t(n,t,e){var o=r(e);return{k:t,v:f[n]?f[n](o):o,e:i[n]}}var e=this.test=function(n,t){for(var e=n.exprs,o=0,u=e.length;u>o;o++){var i=e[o];if(!i.e(i.v,r(t),t))return!1}return!0},o=this.parse=function(r,f){r||(r={$eq:r});var s=[];if(r&&r.constructor===Object)for(var a in r){var c;if(i[a])c=a;else{if(36===a.charCodeAt(0))throw new Error("Unknown operator "+a+".");c="$trav"}var v=r[a],$=v;if(u[c]){if(~a.indexOf(".")){var l=a.split(".");a=l.shift(),$=v=n(l,v)}if(v instanceof Array){$=[];for(var p=v.length;p--;)$.push(o(v[p]))}else $=o(v,a)}s.push(t(c,a,$))}else s.push(t("$eq",f,r));var d={exprs:s,k:f,test:function(n){return e(d,n)}};return d},u=this.traversable={$and:!0,$or:!0,$nor:!0,$trav:!0,$not:!0},i=this.testers={$eq:function(n,r){return n.test(r)},$ne:function(n,r){return!n.test(r)},$lt:function(n,r){return n>r},$gt:function(n,r){return r>n},$lte:function(n,r){return n>=r},$gte:function(n,r){return r>=n},$exists:function(n,r){return n===(null!=r)},$in:function(n,r){if(!(r instanceof Array))return~n.indexOf(r);for(var t=r.length;t--;)if(~n.indexOf(r[t]))return!0;return!1},$not:function(n,r){if(!n.test)throw new Error("$not test should include an expression, not a value. Use $ne instead.");return!n.test(r)},$type:function(n,r,t){return null!=t?t instanceof n||t.constructor==n:!1},$nin:function(n,r){return!i.$in(n,r)},$mod:function(n,r){return r%n[0]==n[1]},$all:function(n,r){r||(r=[]);for(var t=n.length;t--;){var e=n[t],o=~r.indexOf(e);if(!o)return!1}return!0},$size:function(n,r){return r?n===r.length:!1},$or:function(n,r){for(var t=n.length,o=t;t--;)if(e(n[t],r))return!0;return 0===o},$nor:function(n,r){for(var t=n.length;t--;)if(e(n[t],r))return!1;return!0},$and:function(n,r){for(var t=n.length;t--;)if(!e(n[t],r))return!1;return!0},$trav:function(n,r){if(r instanceof Array){for(var t=r.length;t--;){var o=r[t];if(o[n.k]&&e(n,o[n.k]))return!0}return!1}return e(n,r?r[n.k]:void 0)},$regex:function(n,r){var t=new RegExp(n);return t.test(r)},$where:function(n,r){return n.call(r)}},f={$eq:function(n){var r;return n instanceof RegExp?n:(r=n instanceof Function?n:function(r){return r instanceof Array?~r.indexOf(n):n===r},{test:r})},$ne:function(n){return f.$eq(n)},$where:function(n){return"string"==typeof n?new Function("return "+n):n}}}function t(n,r,t){function u(n){return f.test(i(n))}"object"!=typeof r&&(t=r,r=void 0);var i=o(t),f=e.parse(n);return r?r.filter(u):(u.query=n,u)}var e=new r,o=function(n){if(!n)return function(n){return n};if("function"==typeof n)return n;throw new Error("Unknown sift selector "+n)};t.use=function(n){n.operators&&t.useOperators(n.operators),"function"==typeof n&&n(t)},t.useOperators=function(n){for(var r in n)t.useOperator(r,n[r])},t.useOperator=function(n,r){var t={};t="object"==typeof r?r:{test:r};var o="$"+n;e.testers[o]=t.test,(t.traversable||t.traverse)&&(e.traversable[o]=!0)},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=t:"undefined"!=typeof window&&(window.sift=t)}();<|endoftext|>


<commit_before>

var parse = require("./parser").parse;
var _ = require("underscore");

function interpreter(expr){
    var parsedData = parse(expr);
    var env = {
        '+': (x,y) => x + y,

    }

    return _inter(parsedData, env);
}

function lookup(symbol, env){
    if(_.has(env, symbol)){
        return env[symbol]
    }
    throw new Error('no ' + symbol + "in env");
}

function _inter(expr, env){
    if(_.isArray(expr)){
        if(expr.length === 1){
            return _inter(expr[0])
        }

        if(_.isString(expr[0])){
            if(expr[0] == '+'){
                return _inter(expr[1]) + _inter(expr[2]);
            }
        }
    }
    if(_.isNumber(expr) || _.isBoolean(expr)){
        return expr;
    }

    if(_.isString(expr)){
        return lookup(expr, env)
    }

}

console.log(interpreter("(+ 1 2)")) // ==> 3
console.log(interpreter("(+ 1 (+ 1 2))")) // ==> 4

<commit_msg>implement basic function<commit_after>

var parse = require("./parser").parse;
var _ = require("underscore");

function interpreter(expr){
    var parsedData = parse(expr);
    var env = {
    }

    return _inter(parsedData, env);
}

function lookup(symbol, env){
    if(_.has(env, symbol)){
        return env[symbol]
    }
    // console.log(env);
    throw new Error('no ' + symbol + " in env");
}

function _inter(expr, env){
    // console.log(expr);
    // console.log(env);
    if(_.isArray(expr)){
        if(expr.length === 1){
            return _inter(expr[0], env)
        }

        if(_.isString(expr[0])){
            if(expr[0] == '+'){
                return _inter(expr[1], env) + _inter(expr[2], env);
            }

            if(expr[0] == 'lambda'){
                return function(x){
                    env[expr[1][0]] = x;
                    return _inter(expr[2], env);
                }
            }
        }

        return _inter(expr[0], env)(_inter(expr[1], env))

    }
    if(_.isNumber(expr) || _.isBoolean(expr)){
        return expr;
    }

    if(_.isString(expr)){
        return lookup(expr, env)
    }

}

console.log(interpreter("(+ 1 2)")) // ==> 3
console.log(interpreter("(+ 1 (+ 1 2))")) // ==> 4
console.log(interpreter("(lambda (x) x)")) // ==> [Function]
console.log(interpreter("((lambda (x) (+ x 2)) 1)")) // ==> 3

<|endoftext|>


<commit_before>var utils = require('../utils');
var layout = require('./layout');
var menu = require('./menu');
var widgets = require('./_commonWidgets');
var xhr = require('../xhr');
var i18n = require('../i18n');
var socket = require('../socket');
var session = require('../session');
var loginModal = require('./loginModal');
var gamesMenu = require('./gamesMenu');
var uniq = require('lodash-node/modern/arrays/uniq');

var seeks = {};

function seekUserId(seek) {
  return seek.username.toLowerCase();
}

function fixSeeks(ss) {
  var userId = session.getUserId();
  if (userId) ss.sort(function(a, b) {
    if (seekUserId(a) === userId) return -1;
    if (seekUserId(b) === userId) return 1;
  });
  return uniq(ss, function(s) {
    return s.username + s.mode + s.variant.key + s.days;
  });
}

seeks.controller = function() {

  var lobbySocket;
  var pool = [];

  window.analytics.trackView('Seeks');

  xhr.lobby(true).then(function(data) {
    lobbySocket = socket.connectLobby(data.lobby.version, reload, {
      redirect: function(data) {
        m.route('/play' + data.url);
      },
      reload_seeks: reload,
      resync: function() {
        xhr.lobby().then(function(data) {
          if (lobbySocket) lobbySocket.setVersion(data.lobby.version);
        });
      }
    });
  });

  var reload = function(foreground) {
    xhr.seeks(foreground).then(function(d) {
      pool = fixSeeks(d);
      m.redraw();
    });
  };

  return {
    pool: function() {
      return pool;
    },
    cancel: function(seekId) {
      lobbySocket.send('cancelSeek', seekId);
    },
    join: function(seekId) {
      lobbySocket.send('joinSeek', seekId);
    },
    onunload: function() {
      if (lobbySocket) {
        lobbySocket.destroy();
        lobbySocket = null;
      }
    }
  };
};

function renderSeek(ctrl, seek) {
  var action = seek.username.toLowerCase() === session.getUserId() ? 'cancel' : 'join';
  return m('div', {
    key: seek.id,
    'data-id': seek.id,
    class: 'seek ' + action,
    config: utils.ontouchend(utils.partialƒ(ctrl[action], seek.id))
  }, [
    m('div.icon', {
      'data-icon': seek.perf.icon
    }),
    m('div.body', [
      m('div.player', seek.username + ' (' + seek.rating + ')'),
      m('div.variant', seek.variant.name),
      m('div', [
        seek.days ? i18n(seek.days === 1 ? 'oneDay' : 'nbDays', seek.days) : '∞',
        ', ',
        i18n(seek.mode === 1 ? 'rated' : 'casual')
      ])
    ])
  ]);
}

seeks.view = function(ctrl) {

  var header = utils.partialƒ(widgets.header, i18n('correspondence'));
  var body = function() {
    return session.isConnected() ? m('div.seeks', [
      ctrl.pool().map(utils.partialƒ(renderSeek, ctrl)),
      m('button.fat', {
        config: utils.ontouchend(gamesMenu.openNewGameCorrespondence)
      }, i18n('createAGame'))
    ]) : m('div.disconnected',
      m('button.fat', {
        config: utils.ontouchend(loginModal.open)
      }, i18n('logIn'))
    )
  };

  return layout.free(header, body, widgets.empty, menu.view, widgets.empty);
};

module.exports = seeks;
<commit_msg>correspondence seeks scroller<commit_after>var utils = require('../utils');
var layout = require('./layout');
var menu = require('./menu');
var widgets = require('./_commonWidgets');
var xhr = require('../xhr');
var i18n = require('../i18n');
var socket = require('../socket');
var session = require('../session');
var loginModal = require('./loginModal');
var gamesMenu = require('./gamesMenu');
var uniq = require('lodash-node/modern/arrays/uniq');
var iScroll = require('iscroll');

var seeks = {};

function seekUserId(seek) {
  return seek.username.toLowerCase();
}

function fixSeeks(ss) {
  var userId = session.getUserId();
  if (userId) ss.sort(function(a, b) {
    if (seekUserId(a) === userId) return -1;
    if (seekUserId(b) === userId) return 1;
  });
  return uniq(ss, function(s) {
    return s.username + s.mode + s.variant.key + s.days;
  });
}

seeks.controller = function() {

  var lobbySocket;
  var pool = [];

  window.analytics.trackView('Seeks');

  xhr.lobby(true).then(function(data) {
    lobbySocket = socket.connectLobby(data.lobby.version, reload, {
      redirect: function(data) {
        m.route('/play' + data.url);
      },
      reload_seeks: reload,
      resync: function() {
        xhr.lobby().then(function(data) {
          if (lobbySocket) lobbySocket.setVersion(data.lobby.version);
        });
      }
    });
  });

  var reload = function(foreground) {
    xhr.seeks(foreground).then(function(d) {
      pool = fixSeeks(d);
      m.redraw();
    });
  };

  return {
    pool: function() {
      return pool;
    },
    cancel: function(seekId) {
      lobbySocket.send('cancelSeek', seekId);
    },
    join: function(seekId) {
      lobbySocket.send('joinSeek', seekId);
    },
    onunload: function() {
      if (lobbySocket) {
        lobbySocket.destroy();
        lobbySocket = null;
      }
    }
  };
};

function renderSeek(ctrl, seek) {
  var action = seek.username.toLowerCase() === session.getUserId() ? 'cancel' : 'join';
  return m('div', {
    key: seek.id,
    'data-id': seek.id,
    class: 'seek ' + action,
    config: utils.ontouchend(utils.partialƒ(ctrl[action], seek.id))
  }, [
    m('div.icon', {
      'data-icon': seek.perf.icon
    }),
    m('div.body', [
      m('div.player', seek.username + ' (' + seek.rating + ')'),
      m('div.variant', seek.variant.name),
      m('div', [
        seek.days ? i18n(seek.days === 1 ? 'oneDay' : 'nbDays', seek.days) : '∞',
        ', ',
        i18n(seek.mode === 1 ? 'rated' : 'casual')
      ])
    ])
  ]);
}

seeks.view = function(ctrl) {

  var scroller;
  var header = utils.partialƒ(widgets.header, i18n('correspondence'));
  var body = function() {
    return session.isConnected() ? m('div.seeks', {
      config: function(el, isUpdate, context) {
        if (!scroller || !isUpdate) {
          scroller = new iScroll(el);
          context.onunload = function() {
            if (scroller) {
              scroller.destroy();
              scroller = null;
            }
          };
        }
        scroller.refresh();
      }
    }, [
      ctrl.pool().map(utils.partialƒ(renderSeek, ctrl)),
      m('button.fat', {
        config: utils.ontouchend(gamesMenu.openNewGameCorrespondence)
      }, i18n('createAGame'))
    ]) : m('div.disconnected',
      m('button.fat', {
        config: utils.ontouchend(loginModal.open)
      }, i18n('logIn'))
    )
  };

  return layout.free(header, body, widgets.empty, menu.view, widgets.empty);
};

module.exports = seeks;
<|endoftext|>


<commit_before>import React from "react"
import { shallow, mount } from "enzyme"
import sinon from "sinon"
import "../../setupTests"
import { InfoPageView } from "./InfoPageView"
import { Container } from "styles"
import { Editor } from "draft-js"

describe("InfoPage/InfoPageView", () => {
  let props
  let mountedInfoPageView
  const infoPageView = () => {
    if (!mountedInfoPageView) {
      mountedInfoPageView = shallow(<InfoPageView {...props} />)
    }
    return mountedInfoPageView
  }

  beforeEach(() => {
    props = {
      page: undefined,
      match: undefined,
      editPage: undefined,
      fetchUserInfo: undefined,
      fetchedUserData: undefined,
      loggedInUser: undefined,
      isAuthenticated: undefined,
    }
    mountedInfoPageView = undefined
  })

  describe("initial render", () => {
    beforeEach(() => {
      props = {
        page: {
          data: {
            attributes: {
              content: "page content",
              updated_at: "999",
            },
          },
        },
        match: {
          params: {
            name: "order",
          },
        },
        fetchUserInfo: () => {},
      }
    })

    it("always renders a Container", () => {
      expect(infoPageView().find(Container).length).toBeGreaterThan(0)
    })
    it("always renders an Editor", () => {
      expect(infoPageView().find(Editor).length).toBeGreaterThan(0)
    })
    it("Editor is readOnly", () => {
      const editor = infoPageView().find(Editor)
      expect(editor)
        .props()
        .readOnly.toBe(true)
    })
  })

  describe("user is authenticated with no other permissions", () => {
    beforeEach(() => {
      props = {
        page: {
          data: {
            attributes: {
              content: "page content",
              updated_at: "999",
            },
          },
        },
        match: {
          params: {
            name: "order",
          },
        },
        fetchUserInfo: () => {},
        isAuthenticated: true,
      }
    })
    it("calls componentDidMount", () => {
      sinon.spy(InfoPageView.prototype, "componentDidMount")
      infoPageView()
      expect(InfoPageView.prototype.componentDidMount.calledOnce).toEqual(true)
    })
  })

  describe("user is authenticated with editing privileges and valid JWT", () => {
    // add tests here
  })

  describe("user is authenticated with editing privileges but JWT is invalid", () => {
    // add tests here
  })
})
<commit_msg>fix broken InfoPageView tests<commit_after>import React from "react"
import { shallow, mount } from "enzyme"
import sinon from "sinon"
import "../../setupTests"
import { InfoPageView } from "./InfoPageView"
import { Container } from "styles"
import { Editor } from "draft-js"

describe("InfoPage/InfoPageView", () => {
  let props
  let mountedInfoPageView
  const infoPageView = () => {
    if (!mountedInfoPageView) {
      mountedInfoPageView = shallow(<InfoPageView {...props} />)
    }
    return mountedInfoPageView
  }

  beforeEach(() => {
    props = {
      page: undefined,
      match: undefined,
      editPage: undefined,
      fetchUserInfo: undefined,
      fetchedUserData: undefined,
      loggedInUser: undefined,
      isAuthenticated: undefined,
    }
    mountedInfoPageView = undefined
  })

  const content = JSON.stringify({
    entityMap: {},
    blocks: [
      {
        key: "abc",
        text: "123",
        type: "unstyled",
        depth: 0,
      },
    ],
  })

  describe("initial render", () => {
    beforeEach(() => {
      props = {
        page: {
          data: {
            attributes: {
              content: content,
              updated_at: "999",
            },
          },
        },
        match: {
          params: {
            name: "order",
          },
        },
        fetchUserInfo: () => {},
      }
    })

    it("always renders a Container", () => {
      expect(infoPageView().find(Container).length).toBeGreaterThan(0)
    })
    it("always renders an Editor", () => {
      expect(infoPageView().find(Editor).length).toBeGreaterThan(0)
    })
    it("Editor is readOnly", () => {
      const editor = infoPageView().find(Editor)
      expect(editor.props().readOnly).toBe(true)
    })
  })

  describe("user is authenticated with no other permissions", () => {
    beforeEach(() => {
      props = {
        page: {
          data: {
            attributes: {
              content: content,
              updated_at: "999",
            },
          },
        },
        match: {
          params: {
            name: "order",
          },
        },
        fetchUserInfo: () => {},
        isAuthenticated: true,
      }
    })
    it("calls componentDidMount", () => {
      sinon.spy(InfoPageView.prototype, "componentDidMount")
      infoPageView()
      expect(InfoPageView.prototype.componentDidMount.calledOnce).toEqual(true)
    })
  })

  describe("user is authenticated with editing privileges and valid JWT", () => {
    // add tests here
  })

  describe("user is authenticated with editing privileges but JWT is invalid", () => {
    // add tests here
  })
})
<|endoftext|>


<commit_before>define("ace/theme/terminal",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-terminal-theme",t.cssText=".ace-terminal-theme .ace_gutter {background: #1a0005;color: steelblue}.ace-terminal-theme .ace_print-margin {width: 1px;background: #1a1a1a}.ace-terminal-theme {background-color: black;color: #DEDEDE}.ace-terminal-theme .ace_cursor {color: #9F9F9F}.ace-terminal-theme .ace_marker-layer .ace_selection {background: #424242}.ace-terminal-theme.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px black;}.ace-terminal-theme .ace_marker-layer .ace_step {background: rgb(0, 0, 0)}.ace-terminal-theme .ace_marker-layer .ace_bracket {background: #090;}.ace-terminal-theme .ace_marker-layer .ace_bracket-start {background: #090;}.ace-terminal-theme .ace_marker-layer .ace_bracket-unmatched {margin: -1px 0 0 -1px;border: 1px solid #900}.ace-terminal-theme .ace_marker-layer .ace_active-line {background: #2A2A2A}.ace-terminal-theme .ace_gutter-active-line {background-color: #2A112A}.ace-terminal-theme .ace_marker-layer .ace_selected-word {border: 1px solid #424242}.ace-terminal-theme .ace_invisible {color: #343434}.ace-terminal-theme .ace_keyword,.ace-terminal-theme .ace_meta,.ace-terminal-theme .ace_storage,.ace-terminal-theme .ace_storage.ace_type,.ace-terminal-theme .ace_support.ace_type {color: tomato}.ace-terminal-theme .ace_keyword.ace_operator {color: deeppink}.ace-terminal-theme .ace_constant.ace_character,.ace-terminal-theme .ace_constant.ace_language,.ace-terminal-theme .ace_constant.ace_numeric,.ace-terminal-theme .ace_keyword.ace_other.ace_unit,.ace-terminal-theme .ace_support.ace_constant,.ace-terminal-theme .ace_variable.ace_parameter {color: #E78C45}.ace-terminal-theme .ace_constant.ace_other {color: gold}.ace-terminal-theme .ace_invalid {color: yellow;background-color: red}.ace-terminal-theme .ace_invalid.ace_deprecated {color: #CED2CF;background-color: #B798BF}.ace-terminal-theme .ace_fold {background-color: #7AA6DA;border-color: #DEDEDE}.ace-terminal-theme .ace_entity.ace_name.ace_function,.ace-terminal-theme .ace_support.ace_function,.ace-terminal-theme .ace_variable {color: #7AA6DA}.ace-terminal-theme .ace_support.ace_class,.ace-terminal-theme .ace_support.ace_type {color: #E7C547}.ace-terminal-theme .ace_heading,.ace-terminal-theme .ace_string {color: #B9CA4A}.ace-terminal-theme .ace_entity.ace_name.ace_tag,.ace-terminal-theme .ace_entity.ace_other.ace_attribute-name,.ace-terminal-theme .ace_meta.ace_tag,.ace-terminal-theme .ace_string.ace_regexp,.ace-terminal-theme .ace_variable {color: #D54E53}.ace-terminal-theme .ace_comment {color: orangered}.ace-terminal-theme .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLBWV/8PAAK4AYnhiq+xAAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})<commit_msg>Update tmp/bower_components/ace-builds/src-min/theme-terminal.js<commit_after><|endoftext|>


<commit_before>(function () {
    'use strict';

    angular
        .module('app.layout')
        .controller('NavbarController', Navbar);

    Navbar.$inject = ['$scope', '$state', 'search', '$http', '__env'];
    function Navbar($scope, $state, search, $http, __env) {
      $scope.warcraftLfgUrl = __env.warcraftLfgUrl;
      $scope.warcraftProgressUrl = __env.warcraftProgressUrl;
      $scope.warcraftParserUrl = __env.warcraftParserUrl;
      $scope.apiUrl = __env.apiUrl;
      if (__env.html5) {
          $scope.hashbang = '';
          $scope.hashbangAbs = '';
      } else {
          $scope.hashbang = '#';
          $scope.hashbangAbs = '#/';
      }

      $scope.getLocation = function(val) {
          return $http.get(__env.apiProgressUrl+'/api/v1/search/'+val, {
              params: {
                  number: 5
              }
          }).then(function (response) {
              return response.data.map(function(guild) {
                  return guild;
              });
          });
      };

      $scope.onSelect = function(item, model, label, event) {
        if (event && event.type && event.type == "keydown") {
          $state.go('guild-read', {region: item.region, realm: item.realm, name: item.name});
        }
      }

      $scope.goSearch = function() {
        $state.go('search', {term: $scope.asyncSelected});
      };

      $scope.ngModelOptionsSelected = function(value) {
        if (arguments.length) {
          _selected = value;
        } else {
          return _selected;
        }
      };

      $scope.modelOptions = {
        debounce: {
          default: 500,
          blur: 250
        },
        getterSetter: true
      };
    }
})();<commit_msg>Remove credentials from search API<commit_after>(function () {
    'use strict';

    angular
        .module('app.layout')
        .controller('NavbarController', Navbar);

    Navbar.$inject = ['$scope', '$state', 'search', '$http', '__env'];
    function Navbar($scope, $state, search, $http, __env) {
      $scope.warcraftLfgUrl = __env.warcraftLfgUrl;
      $scope.warcraftProgressUrl = __env.warcraftProgressUrl;
      $scope.warcraftParserUrl = __env.warcraftParserUrl;
      $scope.apiUrl = __env.apiUrl;
      if (__env.html5) {
          $scope.hashbang = '';
          $scope.hashbangAbs = '';
      } else {
          $scope.hashbang = '#';
          $scope.hashbangAbs = '#/';
      }

      $scope.getLocation = function(val) {
          return $http.get(__env.apiProgressUrl+'/api/v1/search/'+val, {
              params: {
                  number: 5
              },
              withCredentials: false,
          }).then(function (response) {
              return response.data.map(function(guild) {
                  return guild;
              });
          });
      };

      $scope.onSelect = function(item, model, label, event) {
        if (event && event.type && event.type == "keydown") {
          $state.go('guild-read', {region: item.region, realm: item.realm, name: item.name});
        }
      }

      $scope.goSearch = function() {
        $state.go('search', {term: $scope.asyncSelected});
      };

      $scope.ngModelOptionsSelected = function(value) {
        if (arguments.length) {
          _selected = value;
        } else {
          return _selected;
        }
      };

      $scope.modelOptions = {
        debounce: {
          default: 500,
          blur: 250
        },
        getterSetter: true
      };
    }
})();<|endoftext|>


<commit_before>'use strict';

function scrape(html) {
  var arr = []
    , rows
    ;

  if (/Sorry, no records found/.test(html)) {
    return null;
  }

  // there's tons of malformed html, let's level the playing field
  html = html.replace(/[\s\S]+(
)[\s\S]+/g, '$1');
  html = html.replace(/<TH[\s\S]+?
/g, '
');
  rows = html.split(/
/ig);
  rows.shift(); // TABLE open + header
  rows.pop(); // TABLE close

  rows.forEach(function (row) {
    var cols = row.split(//ig)
      , linkHrefRe = /<A.*?HREF='([^']*)'.*/
      , linkTitleRe = /]*>([^<]+)(<\/A>)?/
      , area
      , prefix
      , city
      , state
      , st
      , company
      , type
      , carrier
      , carrierLink
      ;

    cols.shift();
    // 972[ ]360[  ]DALLAS[  ]Texas[ ]AT&T LOCAL[  ]CLEC[  ]More
    area = cols[0].replace(linkTitleRe, '$1');
    prefix = cols[1].replace(linkTitleRe, '$1');
    city = cols[2].replace(linkTitleRe, '$1');
    st = cols[2].replace(/.*state=(\w+).*/, '$1');
    state = cols[3].replace(linkTitleRe, '$1');
    company = cols[4].replace(linkTitleRe, '$1');
    carrierLink = cols[4].replace(linkHrefRe, '$1');
    if (!/^http/.test(carrierLink)) {
      carrierLink = '';
    } else {
      carrier = carrierLink.replace(/.*fonefinder.net\/(.*).php/, '$1');
      if (carrierLink === carrier) {
        carrier = '';
      }
    }
    type = cols[5] || '';

    if (/fonefinder/.test(carrierLink)) {
      carrierLink = '';
    }
    arr.push([area, prefix, city, state, st, company, type, carrierLink, carrier]);
  });

  return arr;
}

module.exports.scrape = scrape;
<commit_msg>keep fonefinder links, but remove incomplete ones<commit_after>'use strict';

function scrape(html) {
  var arr = []
    , rows
    ;

  if (/Sorry, no records found/.test(html)) {
    return null;
  }

  // there's tons of malformed html, let's level the playing field
  html = html.replace(/[\s\S]+(
)[\s\S]+/g, '$1');
  html = html.replace(/<TH[\s\S]+?
/g, '
');
  rows = html.split(/
/ig);
  rows.shift(); // TABLE open + header
  rows.pop(); // TABLE close

  rows.forEach(function (row) {
    var cols = row.split(//ig)
      , linkHrefRe = /<A.*?HREF='([^']*)'.*/
      , linkTitleRe = /]*>([^<]+)(<\/A>)?/
      , area
      , prefix
      , city
      , state
      , st
      , company
      , type
      , carrier
      , carrierLink
      ;

    cols.shift();
    // 972[ ]360[  ]DALLAS[  ]Texas[ ]AT&T LOCAL[  ]CLEC[  ]More
    area = cols[0].replace(linkTitleRe, '$1');
    prefix = cols[1].replace(linkTitleRe, '$1');
    city = cols[2].replace(linkTitleRe, '$1');
    st = cols[2].replace(/.*state=(\w+).*/, '$1');
    state = cols[3].replace(linkTitleRe, '$1');
    company = cols[4].replace(linkTitleRe, '$1');
    carrierLink = cols[4].replace(linkHrefRe, '$1');
    if (!/^http/.test(carrierLink)) {
      carrierLink = '';
    } else {
      // the link is incomplete
      if ("http://fonefinder.net" === carrierLink) {
        carrierLink = '';
      }

      carrier = carrierLink.replace(/.*fonefinder.net\/(.*).php/, '$1');
      // there is no link
      if (carrierLink === carrier) {
        carrier = '';
      }
    }
    type = cols[5] || '';
    arr.push([area, prefix, city, state, st, company, type, carrierLink, carrier]);
  });

  return arr;
}

module.exports.scrape = scrape;
<|endoftext|>


<commit_before>'use strict';

var db           = require('magic-db')
  , express      = require('express')
  , stylus       = require('stylus')
  , bodyParser   = require('body-parser')
  , cookieParser = require('cookie-parser')
  , compression  = require('compression')
  , favicon      = require('serve-favicon')
  , fs           = require('fs')
  , morgan       = require('morgan')
  , errorHandler = require('magic-errorHandler')
  , headers      = require('magic-headers')
  , log          = require('magic-log')
  , auth         = require('magic-auth')
  , path         = require('path')
  , router       = require('magic-router')
  , sslRedirect  = require('magic-ssl')
;

module.exports = function(M, S, dir) {
  var css         = ( S.get('css') || stylus )
    , env         = S.get('env') || 'production'
    , dbConf      = S.get('db') || false
    , faviconPath = path.join(dir, 'public', 'favicon.ico')
    , dirs        = S.get('dirs') || {
        public: path.join(dir, 'public')
      , views : path.join(dir, 'views')
    }
  ;

  if ( ! S.get('allowHttp') && S.get('env') === 'production' ) {
   // S.use(sslRedirect);
  }

  //set expiry headers
  S.use(headers);

  //fs.existsSync only gets called once
  if ( ! S.get('faviconExistanceCheck') ) {
    S.set('faviconExistanceCheck', true);
    S.set('faviconExists', fs.existsSync(faviconPath));
  }

  if ( S.get('faviconExists') ) {
    S.use( favicon(faviconPath) );
  }

  S.set('views', dirs.views);
  S.set('view engine', S.get('view engine') || 'jade');

  S.use(compression({ threshold: 128 }));

  S.use( css.middleware(dirs.public, {maxAge: '1d'}) );
  S.use( express.static(dirs.public, {maxAge: '1d'}) );

  if ( S.get('db') ) {
    let dbConf = S.get('db')
      , schema = db(dbConf);
    ;

    S.set('schema', schema);
  }

  //logging
  S.use(morgan('combined'));

  //if host sets bodyparser to true, init it
  if ( S.get('bodyParser') ) {
    S.use(bodyParser.json());
    S.use(bodyParser.urlencoded({ extended: false }));
  }

  //if host sets cookieparser to true, init it:
  if ( S.get('cookieParser') ) {
    S.use(cookieParser());
  }

  if ( S.get('useAuth') ) {
    S.use(function (req, res, next) {
       auth.routes(S, req, res, next);
    });
  }

  //load host specific routes
  if ( S.get('routes') ) {
    let routes = S.get('routes');

    if ( typeof routes === 'array' || typeof routes === 'object' ) {
      for (var route in routes ) {
        S.use(route);
      }
    } else if ( typeof routes === 'function' ) {
      S.use( routes );
    }
  }

  S.use(router);
  S.use(errorHandler);

  return S;
}
<commit_msg>moved errorhandling into two different functions<commit_after>'use strict';
var db           = require('magic-db')
  , express      = require('express')
  , stylus       = require('stylus')
  , bodyParser   = require('body-parser')
  , cookieParser = require('cookie-parser')
  , compression  = require('compression')
  , favicon      = require('serve-favicon')
  , fs           = require('fs')
  , morgan       = require('morgan')
  , errorHandler = require('magic-errorHandler')
  , headers      = require('magic-headers')
  , log          = require('magic-log')
  , auth         = require('magic-auth')
  , path         = require('path')
  , router       = require('magic-router')
  , sslRedirect  = require('magic-ssl')
;

module.exports = function(M, S, dir) {
  var css         = ( S.get('css') || stylus )
    , env         = S.get('env') || 'production'
    , dbConf      = S.get('db') || false
    , faviconPath = path.join(dir, 'public', 'favicon.ico')
    , dirs        = S.get('dirs') || {
        public: path.join(dir, 'public')
      , views : path.join(dir, 'views')
    }
  ;

  if ( ! S.get('allowHttp') && S.get('env') === 'production' ) {
   // S.use(sslRedirect);
  }

  //set expiry headers
  S.use(headers);

  //fs.existsSync only gets called once
  if ( ! S.get('faviconExistanceCheck') ) {
    S.set('faviconExistanceCheck', true);
    S.set('faviconExists', fs.existsSync(faviconPath));
  }

  if ( S.get('faviconExists') ) {
    S.use( favicon(faviconPath) );
  }

  S.set('views', dirs.views);
  S.set('view engine', S.get('view engine') || 'jade');

  S.use(compression({ threshold: 128 }));

  S.use( css.middleware(dirs.public, {maxAge: '1d'}) );
  S.use( express.static(dirs.public, {maxAge: '1d'}) );

  if ( S.get('db') ) {
    let dbConf = S.get('db')
      , schema = db(dbConf);
    ;

    S.set('schema', schema);
  }

  //logging
  S.use(morgan('combined'));

  //if host sets bodyparser to true, init it
  if ( S.get('bodyParser') ) {
    S.use(bodyParser.json());
    S.use(bodyParser.urlencoded({ extended: false }));
  }

  //if host sets cookieparser to true, init it:
  if ( S.get('cookieParser') ) {
    S.use(cookieParser());
  }

  if ( S.get('useAuth') ) {
    S.use(function (req, res, next) {
       auth.routes(S, req, res, next);
    });
  }

  //load host specific routes
  if ( S.get('routes') ) {
    let routes = S.get('routes');

    if ( typeof routes === 'array' || typeof routes === 'object' ) {
      for (let route in routes ) {
        S.use(route);
      }
    } else if ( typeof routes === 'function' ) {
      S.use( routes );
    }
  }

  S.use(router);
  S.use(errorHandler.handle404);
  S.use(errorHandler.handle500);

  return S;
}
<|endoftext|>