<commit_before>var respondToKeys = true;

var DETAILS_PADDING_PX = 60,
    IMG_BORDER_PX = 5 * 2,
    EXTRA_SPACE_PX = 20;

if(window.location.search == "?reset") {
    localStorage.clear();
}

var subReddits = [];

function getSubreddits() {
    var storedSubreddits = localStorage.storedSubreddits,
        reddits,
        hash;
    if(storedSubreddits) {
        reddits = JSON.parse(storedSubreddits);
        reddit.log("Using storedSubreddits: ", storedSubreddits);
        if(reddits.length)
            return(reddits);
    }

    hash = window.location.hash;
    if(undefined===hash){
        return([]);
    }
    hash = hash.slice(1);
    if(hash.length===0) {
        return([]);
    }
    reddits = hash.split("+");
    return(reddits);
}

function getCurrentImage() { return($(gallery.masterPages[gallery.currentMasterPage]).find("#gallery-img")); }

function resetImageSize(img) {
    img.width(img.data('orig-width'));
    img.height(img.data('orig-height'));
    var origTop = img.data('orig-top');
    if (null !== origTop) {
        img.offset({top: origTop});
        img.data('orig-top', null);
    }
}

function resetSlides() {
    slides = [];
    function resetClassName() { this.className=''; }
    for (i = 0; i < 3; i++) {
        var masterPage = $(gallery.masterPages[i]);
        if(masterPage.children().length === 0) {
            el = $($('#gallery-page').html());
            el.find("#htmlSpan").hide();
            el.find("#gallery-img").hide();

            el.find("#gallery-img").load(resetClassName);
            masterPage.append(el);
        } else {
            masterPage.find("#htmlSpan").hide();
            masterPage.find("#gallery-img").hide();
            masterPage.find("#details").html("");
        }
    }
    $("#info-popup").show();
}

var gallery,
el,
span,
i,
page,
slides = [],
advanceOnReddit = false;

$(document).ready(function() {
    document.addEventListener('touchmove', function(e) {
        e.preventDefault();
    }, false);

    gallery = new SwipeView('#wrapper', {numberOfPages: slides.length,loop: false});

    resetSlides();

    var onlineMode = window.location.search != "?test";
    picFetcher = new reddit.PicFetcher({onlineMode: onlineMode,
                                        imgFn: addImg,
                                        htmlFn: addHtml,
                                        statusFn: updateStatus,
                                        show_over_18: localStorage.show_over_18==="on",
                                        show_videos: localStorage.show_videos==="on"
                                        });

    function resetSettings() {
        localStorage.clear();
        showSettings();
    }

    function updateStatus(consecutiveDiscarded, nsfwDiscarded, errorFetching, endOfReddit) {
        var statusHTML = "";
        if(errorFetching) {
            statusHTML += "
" + errorFetching + " errors connecting to reddit.  Reload page or check settings to see if all reddits are correct.
";
            if(errorFetching===2) { statusHTML += "
Possible settings problem.  Will reset after two more errors
"; }
            if(errorFetching===4) { resetSettings(); }
        }
        if(consecutiveDiscarded > 10) {
            statusHTML += "
" + consecutiveDiscarded + " unshown items.  Maybe you have seen all new posts on this subreddit.  Come back later or change settings.
";
        }
        if(nsfwDiscarded > 10) {
            statusHTML += "
" + nsfwDiscarded + " NSFW items skipped. Turn on in settings to view
";
        }

        if(endOfReddit) {
            statusHTML += "
You have reached the end of reddit!  There are no new items to display.  Try a new set of subreddits or refresh later.
";
        }

        $("#loading-status").html(statusHTML);
    }

    function start() {
        subReddits = getSubreddits();
        if(subReddits.length) {
            picFetcher.setSubreddits(subReddits, localStorage["hnct-params"]);
        } else {
            showSettings();
        }
    }
    var startDelay = onlineMode ? 0 : 100;
    setTimeout(start, startDelay);

    var detailsTemplate = $('#details-template').html();
    function setDetails(details, item) {
        item.localTimeAgo = moment.unix(item.created_utc).fromNow();
        details.html(_.template(detailsTemplate, item, {variable:"item"}));
    }

    function offsetImg(img) {
        if(img.height()>$(window).height()-DETAILS_PADDING_PX - EXTRA_SPACE_PX - IMG_BORDER_PX) {
            img.offset({top:DETAILS_PADDING_PX});
        } else {
            var remainingSpace = $(window).height() - DETAILS_PADDING_PX;
            img.offset({top:DETAILS_PADDING_PX + (remainingSpace - img.height() - IMG_BORDER_PX) / 2});
        }
    }

    function putSlideAt(upcoming, i) {
        var slide = slides[upcoming] ? slides[upcoming] : {width: 250,height: 250,item:{url: ""}};
        picFetcher.userSawItem(slide.item);
        var page = $(gallery.masterPages[i]),
            htmlSpan = page.find("#htmlSpan"),
            img = page.find("#gallery-img"),
            details = page.find("#details");

        if (slide.html) {
            img.hide();

            htmlSpan.show();
            htmlSpan.html(slide.html);
        } else {
            htmlSpan.hide();
            htmlSpan.html("");

            img.show();
            img.attr('src', slide.url)
            .attr('className', 'loading')
            .width(slide.width)
            .height(slide.height)
            .data('orig-width', slide.width)
            .data('orig-height', slide.height)
            .data('orig-top', null) // Need to set a null so that it can be persisted.  Can't data set undefined although it's the beginning state
            ;

            offsetImg(img);
        }
        setDetails(details, slide.item);
    }

    gallery.onFlip(function() {
        var el,
        slideIdx,
        i;
        for (i = 0; i < 3; i++) {
            slideIdx = gallery.masterPages[i].dataset.upcomingPageIndex;
            if (slideIdx != gallery.masterPages[i].dataset.pageIndex) {
                putSlideAt(slideIdx, i);
            }
        }
    });

    gallery.onMoveOut(function() {
        gallery.masterPages[gallery.currentMasterPage].className = gallery.masterPages[gallery.currentMasterPage].className.replace(/(^|\s)swipeview-active(\s|$)/, '');
    });

    gallery.onMoveIn(function() {
        var className = gallery.masterPages[gallery.currentMasterPage].className;
        if( !(/(^|\s)swipeview-active(\s|$)/.test(className)) ) {
            gallery.masterPages[gallery.currentMasterPage].className = !className ? 'swipeview-active' : className + ' swipeview-active';
        }
    });

    function advanceImg() {
        resetImageSize(getCurrentImage());
        picFetcher.advance();

        if(!gallery.next()){
            advanceOnReddit = true;
            $("#info-popup").show();
        }
    }

    function retreatImg() {
        resetImageSize(getCurrentImage());
        picFetcher.retreat();
        gallery.prev();
    }

    $(document).keydown(function(event) {
        if (!respondToKeys)
            return;
        if(0===slides.length)
            return;

        var img = getCurrentImage();

        var jCode = 74, kCode = 75, lCode = 76, aCode = 65, sCode = 83, dCode = 68, spaceCode = 32,
        leftCode = 37, upCode = 38, rightCode = 39, downCode = 40;
        switch (event.which) {
            case jCode:
            case aCode:
            case rightCode:
                advanceImg();
                break;

            case kCode:
            case sCode:
            case leftCode:
                retreatImg();
                break;

            case upCode:
                if (null === img.data('orig-top')) {
                    img.data('orig-top', img.offset().top);
                }

                if(img.offset().top === img.data('orig-top')) {
                    retreatImg();
                } else {
                    img.offset({top: Math.min( (img.offset().top + $(window).height()/2),
                                                img.data('orig-top')
                    )});
                }
                break;

            case spaceCode:
            case downCode:
                if (null === img.data('orig-top')) {
                    img.data('orig-top', img.offset().top);
                }

                var imgBottom = img.offset().top + img.height(),
                bottomOffScreen = $(window).height() < imgBottom;
                if (bottomOffScreen) {
                    img.offset({top: img.offset().top - $(window).height()/2});
                } else {
                    advanceImg();
                }
                break;

            case dCode:
            case lCode:
                var zoomed = img.width() != img.data('orig-width');
                if (zoomed) {
                    img.width(img.data('orig-width'));
                    img.height(img.data('orig-height'));
                } else {
                    if (null !== img.data('orig-top')) {
                        img.offset({top: img.data('orig-top')});
                    }
                    var zoomedSize = fitToWindow(img, true);

                    img.width(zoomedSize.width);
                    img.height(zoomedSize.height);
                }
                offsetImg(img);
                break;
        }
    });

    function addSlide(slide) {
        $("#info-popup").hide();

        var newPageI = gallery.options.numberOfPages,
            forceRefresh = slides.length <= 2 ? true : false;

        gallery.updatePageCount(newPageI + 1);
        slides.push(slide);

        if(forceRefresh) {
            putSlideAt(slides.length-1, (slides.length)%3);
        }

        if(advanceOnReddit) {
            advanceOnReddit = false;
            advanceImg();
        }
    }

    function fitToWindow(img, forceShrink) {
        img = $(img);
        var maxWidth = $(window).width() - 30;
        var scaledWidth = Math.min(maxWidth, img.width());
        var scaledHeight = img.height() * (scaledWidth / img.width());

        // Shrink things if doing so slightly will make them fit completely on the page
        var acceptableShrink = 0.5;
        var maxHeight = $(window).height() - DETAILS_PADDING_PX - IMG_BORDER_PX - EXTRA_SPACE_PX;
        if(forceShrink || (maxHeight < scaledHeight && maxHeight / scaledHeight > acceptableShrink)) {
            var newWidth = scaledWidth * (maxHeight / scaledHeight);
            if(newWidth<maxWidth) {
                scaledWidth = newWidth;
                scaledHeight = maxHeight;
            }
        }

        return({width:scaledWidth, height:scaledHeight});
    }

    function addHtml(item, html) {
        addSlide({html: html, item: item});
    }

    function addImg(item, img)
    {
        var fittedSize = fitToWindow(img);
        addSlide({url: item.url, width: fittedSize.width, height: fittedSize.height, item: item});
    }

    $('#subredditsTypeahead')
    .typeahead({source:typeaheadSource,
        menu: '

',
        matcher: function (item) {
            return 0===item.toLowerCase().indexOf(this.query.toLowerCase());
        }
    })
    .change(function(event){
        var val = $(this).val();

        if(val.length > 2)  {
            var bgh = $("#buttonsGoHere");
            if(0===bgh.find(".subreddit-" + val).length)
            {
                var allButton = bgh.find(".subreddit-All");
                allButton.remove();

                bgh.append(subredditButton(val));
                $(this).val("");
            }
        }
        event.preventDefault();
        event.stopPropagation();
    }
    );

    $("#modalForm") // prevent the auto-submitting of the form on enter
    .submit(function(e) {
        e.preventDefault();
        e.stopPropagation();
    });

// end document ready
});

// Settings Modal Related

function typeaheadSource(query, cbFn) {
    var bgh = $("#buttonsGoHere");
    var completions = [];
    var alreadySelected = [];
    for (var i = bgh.children().length - 1; i >= 0; i--) {
        var child = $(bgh.children()[i]);
        alreadySelected.push(child.data("subreddit"));
    }

    var filtered = SFWReddits.filter(function(sub){return( -1 == alreadySelected.indexOf(sub));});
    cbFn(filtered);
}

function subredditButton(subreddit) {
    var button = $("<button />")
    .addClass("btn")
    .addClass("btn-mini")
    .addClass("subreddit-" + subreddit)
    .data("subreddit", subreddit)
    .html(subreddit + " - X")
    .click(function(e) { if(e.clientX!==0 && e.clientY!==0) { $(this).remove(); } }); // get spurious clicks at 0,0 when submitting without typeahead

    return(button);
}

function getButtonData(params) {
    for(var paramName in params) {
        var group = $("#" + paramName);
        var active = group.find(".active");
        params[paramName] = active.data("ifset");
    }
    return params;
}

function allButtonClicked() {
    $.each($("#buttonsGoHere").children(), function(){$(this).remove();});

    $("#buttonsGoHere").append(subredditButton("All"));
}

function setButtonData(params) {
    for(var group in params) {
        var val = params[group];
        group = $("#" + group);
        var toActivate = group.find("[data-ifset='" + val + "']");
        if(toActivate.length) {
            toActivate.addClass("active");
        } else {
        }
    }
}

var defaultParams = {
    "hnct-params": "hot",
    "nsfw-params":  "off"
};

function getParams() {
    var params = defaultParams;
    for(var param in defaultParams) {
        if(localStorage[param]) {
            params[param] = localStorage[param];
        }
    }
    return(params);
}

function showSettings() {
    var params = getParams();
    setButtonData(params);

    var subReddits = getSubreddits();
    var bgh = $("#buttonsGoHere");
    for (var i = bgh.children().length - 1; i >= 0; i--) {
        $(bgh.children()[i]).remove();
    }
    for (i = subReddits.length - 1; i >= 0; i--) {
        bgh.append(subredditButton(subReddits[i]));
    }
    $("#settingsModal").modal( {backdrop: "static", keyboard: false });
}

function getModalSubreddits() {
    var subReddits = [];

    var bgh = $("#buttonsGoHere");
    for (var i = bgh.children().length - 1; i >= 0; i--) {
        var child = $(bgh.children()[i]);
        subReddits.push(child.data("subreddit"));
    }
    return(subReddits);
}

function saveSettings() {

    $.each($("#formErrors").children(), function(){$(this).remove();});

    var settings = getButtonData(defaultParams);
    for(var key in settings) {
        localStorage[key] = settings[key];
    }

    picFetcher.setShow_Videos(settings["video-params"]==="on");
    picFetcher.setShow_over_18(settings["nsfw-params"]==="on");

    subReddits = getModalSubreddits();

    if(!subReddits.length) {
        $("#formErrors")
        .append($('
Please pick at least one Subreddit
'));

        return;
    }

    picFetcher.setSubreddits(subReddits, settings["hnct-params"]);
    localStorage.storedSubreddits = JSON.stringify(subReddits);

    $("#settingsModal").modal("hide");
    respondToKeys = true;
    resetSlides();

    /*
    if($.support.fullscreen){
        console.debug("FULLSCREEN!");
        $('#wrapper').fullScreen();
    } else {
        console.debug("NOT FULLSCREEN!");
    }
    */
}
<commit_msg>Remove automatic reset since it could fire on legit no Internet situations<commit_after>var respondToKeys = true;

var DETAILS_PADDING_PX = 60,
    IMG_BORDER_PX = 5 * 2,
    EXTRA_SPACE_PX = 20;

if(window.location.search == "?reset") {
    localStorage.clear();
}

var subReddits = [];

function getSubreddits() {
    var storedSubreddits = localStorage.storedSubreddits,
        reddits,
        hash;
    if(storedSubreddits) {
        reddits = JSON.parse(storedSubreddits);
        reddit.log("Using storedSubreddits: ", storedSubreddits);
        if(reddits.length)
            return(reddits);
    }

    hash = window.location.hash;
    if(undefined===hash){
        return([]);
    }
    hash = hash.slice(1);
    if(hash.length===0) {
        return([]);
    }
    reddits = hash.split("+");
    return(reddits);
}

function getCurrentImage() { return($(gallery.masterPages[gallery.currentMasterPage]).find("#gallery-img")); }

function resetImageSize(img) {
    img.width(img.data('orig-width'));
    img.height(img.data('orig-height'));
    var origTop = img.data('orig-top');
    if (null !== origTop) {
        img.offset({top: origTop});
        img.data('orig-top', null);
    }
}

function resetSlides() {
    slides = [];
    function resetClassName() { this.className=''; }
    for (i = 0; i < 3; i++) {
        var masterPage = $(gallery.masterPages[i]);
        if(masterPage.children().length === 0) {
            el = $($('#gallery-page').html());
            el.find("#htmlSpan").hide();
            el.find("#gallery-img").hide();

            el.find("#gallery-img").load(resetClassName);
            masterPage.append(el);
        } else {
            masterPage.find("#htmlSpan").hide();
            masterPage.find("#gallery-img").hide();
            masterPage.find("#details").html("");
        }
    }
    $("#info-popup").show();
}

var gallery,
el,
span,
i,
page,
slides = [],
advanceOnReddit = false;

$(document).ready(function() {
    document.addEventListener('touchmove', function(e) {
        e.preventDefault();
    }, false);

    gallery = new SwipeView('#wrapper', {numberOfPages: slides.length,loop: false});

    resetSlides();

    var onlineMode = window.location.search != "?test";
    picFetcher = new reddit.PicFetcher({onlineMode: onlineMode,
                                        imgFn: addImg,
                                        htmlFn: addHtml,
                                        statusFn: updateStatus,
                                        show_over_18: localStorage.show_over_18==="on",
                                        show_videos: localStorage.show_videos==="on"
                                        });

    function resetSettings() {
        localStorage.clear();
        showSettings();
    }

    function updateStatus(consecutiveDiscarded, nsfwDiscarded, errorFetching, endOfReddit) {
        var statusHTML = "";
        if(errorFetching) {
            statusHTML += "
" + errorFetching + " errors connecting to reddit.  Reload page or check settings to see if all reddits are correct.
";
            if(errorFetching===2) { statusHTML += "
>More errors... perhaps reddit or your internet is down.  If not then try changing your settings by clicking the link below.
"; }
        }
        if(consecutiveDiscarded > 10) {
            statusHTML += "
" + consecutiveDiscarded + " unshown items.  Maybe you have seen all new posts on this subreddit.  Come back later or change settings.
";
        }
        if(nsfwDiscarded > 10) {
            statusHTML += "
" + nsfwDiscarded + " NSFW items skipped. Turn on in settings to view
";
        }

        if(endOfReddit) {
            statusHTML += "
You have reached the end of reddit!  There are no new items to display.  Try a new set of subreddits or refresh later.
";
        }

        $("#loading-status").html(statusHTML);
    }

    function start() {
        subReddits = getSubreddits();
        if(subReddits.length) {
            picFetcher.setSubreddits(subReddits, localStorage["hnct-params"]);
        } else {
            showSettings();
        }
    }
    var startDelay = onlineMode ? 0 : 100;
    setTimeout(start, startDelay);

    var detailsTemplate = $('#details-template').html();
    function setDetails(details, item) {
        item.localTimeAgo = moment.unix(item.created_utc).fromNow();
        details.html(_.template(detailsTemplate, item, {variable:"item"}));
    }

    function offsetImg(img) {
        if(img.height()>$(window).height()-DETAILS_PADDING_PX - EXTRA_SPACE_PX - IMG_BORDER_PX) {
            img.offset({top:DETAILS_PADDING_PX});
        } else {
            var remainingSpace = $(window).height() - DETAILS_PADDING_PX;
            img.offset({top:DETAILS_PADDING_PX + (remainingSpace - img.height() - IMG_BORDER_PX) / 2});
        }
    }

    function putSlideAt(upcoming, i) {
        var slide = slides[upcoming] ? slides[upcoming] : {width: 250,height: 250,item:{url: ""}};
        picFetcher.userSawItem(slide.item);
        var page = $(gallery.masterPages[i]),
            htmlSpan = page.find("#htmlSpan"),
            img = page.find("#gallery-img"),
            details = page.find("#details");

        if (slide.html) {
            img.hide();

            htmlSpan.show();
            htmlSpan.html(slide.html);
        } else {
            htmlSpan.hide();
            htmlSpan.html("");

            img.show();
            img.attr('src', slide.url)
            .attr('className', 'loading')
            .width(slide.width)
            .height(slide.height)
            .data('orig-width', slide.width)
            .data('orig-height', slide.height)
            .data('orig-top', null) // Need to set a null so that it can be persisted.  Can't data set undefined although it's the beginning state
            ;

            offsetImg(img);
        }
        setDetails(details, slide.item);
    }

    gallery.onFlip(function() {
        var el,
        slideIdx,
        i;
        for (i = 0; i < 3; i++) {
            slideIdx = gallery.masterPages[i].dataset.upcomingPageIndex;
            if (slideIdx != gallery.masterPages[i].dataset.pageIndex) {
                putSlideAt(slideIdx, i);
            }
        }
    });

    gallery.onMoveOut(function() {
        gallery.masterPages[gallery.currentMasterPage].className = gallery.masterPages[gallery.currentMasterPage].className.replace(/(^|\s)swipeview-active(\s|$)/, '');
    });

    gallery.onMoveIn(function() {
        var className = gallery.masterPages[gallery.currentMasterPage].className;
        if( !(/(^|\s)swipeview-active(\s|$)/.test(className)) ) {
            gallery.masterPages[gallery.currentMasterPage].className = !className ? 'swipeview-active' : className + ' swipeview-active';
        }
    });

    function advanceImg() {
        resetImageSize(getCurrentImage());
        picFetcher.advance();

        if(!gallery.next()){
            advanceOnReddit = true;
            $("#info-popup").show();
        }
    }

    function retreatImg() {
        resetImageSize(getCurrentImage());
        picFetcher.retreat();
        gallery.prev();
    }

    $(document).keydown(function(event) {
        if (!respondToKeys)
            return;
        if(0===slides.length)
            return;

        var img = getCurrentImage();

        var jCode = 74, kCode = 75, lCode = 76, aCode = 65, sCode = 83, dCode = 68, spaceCode = 32,
        leftCode = 37, upCode = 38, rightCode = 39, downCode = 40;
        switch (event.which) {
            case jCode:
            case aCode:
            case rightCode:
                advanceImg();
                break;

            case kCode:
            case sCode:
            case leftCode:
                retreatImg();
                break;

            case upCode:
                if (null === img.data('orig-top')) {
                    img.data('orig-top', img.offset().top);
                }

                if(img.offset().top === img.data('orig-top')) {
                    retreatImg();
                } else {
                    img.offset({top: Math.min( (img.offset().top + $(window).height()/2),
                                                img.data('orig-top')
                    )});
                }
                break;

            case spaceCode:
            case downCode:
                if (null === img.data('orig-top')) {
                    img.data('orig-top', img.offset().top);
                }

                var imgBottom = img.offset().top + img.height(),
                bottomOffScreen = $(window).height() < imgBottom;
                if (bottomOffScreen) {
                    img.offset({top: img.offset().top - $(window).height()/2});
                } else {
                    advanceImg();
                }
                break;

            case dCode:
            case lCode:
                var zoomed = img.width() != img.data('orig-width');
                if (zoomed) {
                    img.width(img.data('orig-width'));
                    img.height(img.data('orig-height'));
                } else {
                    if (null !== img.data('orig-top')) {
                        img.offset({top: img.data('orig-top')});
                    }
                    var zoomedSize = fitToWindow(img, true);

                    img.width(zoomedSize.width);
                    img.height(zoomedSize.height);
                }
                offsetImg(img);
                break;
        }
    });

    function addSlide(slide) {
        $("#info-popup").hide();

        var newPageI = gallery.options.numberOfPages,
            forceRefresh = slides.length <= 2 ? true : false;

        gallery.updatePageCount(newPageI + 1);
        slides.push(slide);

        if(forceRefresh) {
            putSlideAt(slides.length-1, (slides.length)%3);
        }

        if(advanceOnReddit) {
            advanceOnReddit = false;
            advanceImg();
        }
    }

    function fitToWindow(img, forceShrink) {
        img = $(img);
        var maxWidth = $(window).width() - 30;
        var scaledWidth = Math.min(maxWidth, img.width());
        var scaledHeight = img.height() * (scaledWidth / img.width());

        // Shrink things if doing so slightly will make them fit completely on the page
        var acceptableShrink = 0.5;
        var maxHeight = $(window).height() - DETAILS_PADDING_PX - IMG_BORDER_PX - EXTRA_SPACE_PX;
        if(forceShrink || (maxHeight < scaledHeight && maxHeight / scaledHeight > acceptableShrink)) {
            var newWidth = scaledWidth * (maxHeight / scaledHeight);
            if(newWidth<maxWidth) {
                scaledWidth = newWidth;
                scaledHeight = maxHeight;
            }
        }

        return({width:scaledWidth, height:scaledHeight});
    }

    function addHtml(item, html) {
        addSlide({html: html, item: item});
    }

    function addImg(item, img)
    {
        var fittedSize = fitToWindow(img);
        addSlide({url: item.url, width: fittedSize.width, height: fittedSize.height, item: item});
    }

    $('#subredditsTypeahead')
    .typeahead({source:typeaheadSource,
        menu: '

',
        matcher: function (item) {
            return 0===item.toLowerCase().indexOf(this.query.toLowerCase());
        }
    })
    .change(function(event){
        var val = $(this).val();

        if(val.length > 2)  {
            var bgh = $("#buttonsGoHere");
            if(0===bgh.find(".subreddit-" + val).length)
            {
                var allButton = bgh.find(".subreddit-All");
                allButton.remove();

                bgh.append(subredditButton(val));
                $(this).val("");
            }
        }
        event.preventDefault();
        event.stopPropagation();
    }
    );

    $("#modalForm") // prevent the auto-submitting of the form on enter
    .submit(function(e) {
        e.preventDefault();
        e.stopPropagation();
    });

// end document ready
});

// Settings Modal Related

function typeaheadSource(query, cbFn) {
    var bgh = $("#buttonsGoHere");
    var completions = [];
    var alreadySelected = [];
    for (var i = bgh.children().length - 1; i >= 0; i--) {
        var child = $(bgh.children()[i]);
        alreadySelected.push(child.data("subreddit"));
    }

    var filtered = SFWReddits.filter(function(sub){return( -1 == alreadySelected.indexOf(sub));});
    cbFn(filtered);
}

function subredditButton(subreddit) {
    var button = $("<button />")
    .addClass("btn")
    .addClass("btn-mini")
    .addClass("subreddit-" + subreddit)
    .data("subreddit", subreddit)
    .html(subreddit + " - X")
    .click(function(e) { if(e.clientX!==0 && e.clientY!==0) { $(this).remove(); } }); // get spurious clicks at 0,0 when submitting without typeahead

    return(button);
}

function getButtonData(params) {
    for(var paramName in params) {
        var group = $("#" + paramName);
        var active = group.find(".active");
        params[paramName] = active.data("ifset");
    }
    return params;
}

function allButtonClicked() {
    $.each($("#buttonsGoHere").children(), function(){$(this).remove();});

    $("#buttonsGoHere").append(subredditButton("All"));
}

function setButtonData(params) {
    for(var group in params) {
        var val = params[group];
        group = $("#" + group);
        var toActivate = group.find("[data-ifset='" + val + "']");
        if(toActivate.length) {
            toActivate.addClass("active");
        } else {
        }
    }
}

var defaultParams = {
    "hnct-params": "hot",
    "nsfw-params":  "off"
};

function getParams() {
    var params = defaultParams;
    for(var param in defaultParams) {
        if(localStorage[param]) {
            params[param] = localStorage[param];
        }
    }
    return(params);
}

function showSettings() {
    var params = getParams();
    setButtonData(params);

    var subReddits = getSubreddits();
    var bgh = $("#buttonsGoHere");
    for (var i = bgh.children().length - 1; i >= 0; i--) {
        $(bgh.children()[i]).remove();
    }
    for (i = subReddits.length - 1; i >= 0; i--) {
        bgh.append(subredditButton(subReddits[i]));
    }
    $("#settingsModal").modal( {backdrop: "static", keyboard: false });
}

function getModalSubreddits() {
    var subReddits = [];

    var bgh = $("#buttonsGoHere");
    for (var i = bgh.children().length - 1; i >= 0; i--) {
        var child = $(bgh.children()[i]);
        subReddits.push(child.data("subreddit"));
    }
    return(subReddits);
}

function saveSettings() {

    $.each($("#formErrors").children(), function(){$(this).remove();});

    var settings = getButtonData(defaultParams);
    for(var key in settings) {
        localStorage[key] = settings[key];
    }

    picFetcher.setShow_Videos(settings["video-params"]==="on");
    picFetcher.setShow_over_18(settings["nsfw-params"]==="on");

    subReddits = getModalSubreddits();

    if(!subReddits.length) {
        $("#formErrors")
        .append($('
Please pick at least one Subreddit
'));

        return;
    }

    picFetcher.setSubreddits(subReddits, settings["hnct-params"]);
    localStorage.storedSubreddits = JSON.stringify(subReddits);

    $("#settingsModal").modal("hide");
    respondToKeys = true;
    resetSlides();

    /*
    if($.support.fullscreen){
        console.debug("FULLSCREEN!");
        $('#wrapper').fullScreen();
    } else {
        console.debug("NOT FULLSCREEN!");
    }
    */
}
<|endoftext|>


<commit_before>module.exports = {
  config: {
    // default font size in pixels for all tabs
    fontSize: 14,

    // font family with optional fallbacks
    fontFamily: 'Hack, Menlo, "DejaVu Sans Mono", "Lucida Console", monospace',

    // terminal cursor background color (hex)
    cursorColor: '#F81CE5',

    // color of the text
    foregroundColor: '#fff',

    // terminal background color
    backgroundColor: '#000',

    // border color (window, tabs)
    borderColor: '#333',

    // custom css to embed in the main window
    css: '',

    // custom css to embed in the terminal window
    termCSS: '',

    // custom padding (css format, i.e.: `top right bottom left`)
    padding: '12px 14px',

    // some color overrides. see http://bit.ly/29k1iU2 for
    // the full list
    colors: [
      '#000000',
      '#ff0000',
      '#33ff00',
      '#ffff00',
      '#0066ff',
      '#cc00ff',
      '#00ffff',
      '#d0d0d0',
      '#808080',
      '#ff0000',
      '#33ff00',
      '#ffff00',
      '#0066ff',
      '#cc00ff',
      '#00ffff',
      '#ffffff'
    ]
  },

  // a list of plugins to fetch and install from npm
  // format: [@org/]project[#version]
  // examples:
  //   `hyperpower`
  //   `@company/project`
  //   `project#1.0.1`
  plugins: [
    'hyperterm-snazzy',
    'hypercwd',
  ],

  // in development, you can create a directory under
  // `~/.hyperterm_plugins/local/` and include it here
  // to load it and avoid it being `npm install`ed
  localPlugins: []
};
<commit_msg>hyperterm: add hypertitle and hyperterm-themed-scrollbar<commit_after>module.exports = {
  config: {
    // default font size in pixels for all tabs
    fontSize: 14,

    // font family with optional fallbacks
    fontFamily: 'Hack, Menlo, "DejaVu Sans Mono", "Lucida Console", monospace',

    // terminal cursor background color (hex)
    cursorColor: '#F81CE5',

    // color of the text
    foregroundColor: '#fff',

    // terminal background color
    backgroundColor: '#000',

    // border color (window, tabs)
    borderColor: '#333',

    // custom css to embed in the main window
    css: '',

    // custom css to embed in the terminal window
    termCSS: '',

    // custom padding (css format, i.e.: `top right bottom left`)
    padding: '12px 14px',

    // some color overrides. see http://bit.ly/29k1iU2 for
    // the full list
    colors: [
      '#000000',
      '#ff0000',
      '#33ff00',
      '#ffff00',
      '#0066ff',
      '#cc00ff',
      '#00ffff',
      '#d0d0d0',
      '#808080',
      '#ff0000',
      '#33ff00',
      '#ffff00',
      '#0066ff',
      '#cc00ff',
      '#00ffff',
      '#ffffff'
    ]
  },

  // a list of plugins to fetch and install from npm
  // format: [@org/]project[#version]
  // examples:
  //   `hyperpower`
  //   `@company/project`
  //   `project#1.0.1`
  plugins: [
    'hyperterm-snazzy',
    'hypercwd',
    'hypertitle',
    'hyperterm-themed-scrollbar',
  ],

  // in development, you can create a directory under
  // `~/.hyperterm_plugins/local/` and include it here
  // to load it and avoid it being `npm install`ed
  localPlugins: []
};
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

//  Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
//  and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl

var Class = require('../utils/Class');

/**
 * @typedef {object} Vector2Like
 *
 * @property {number} x - The x component.
 * @property {number} y - The y component.
 */

/**
 * @classdesc
 * A representation of a vector in 2D space.
 *
 * A two-component vector.
 *
 * @class Vector2
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {number|Vector2Like} [x] - The x component, or an object with `x` and `y` properties.
 * @param {number} [y] - The y component.
 */
var Vector2 = new Class({

    initialize:

    function Vector2 (x, y)
    {
        /**
         * The x component of this Vector.
         *
         * @name Phaser.Math.Vector2#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = 0;

        /**
         * The y component of this Vector.
         *
         * @name Phaser.Math.Vector2#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = 0;

        if (typeof x === 'object')
        {
            this.x = x.x || 0;
            this.y = x.y || 0;
        }
        else
        {
            if (y === undefined) { y = x; }

            this.x = x || 0;
            this.y = y || 0;
        }
    },

    /**
     * Make a clone of this Vector2.
     *
     * @method Phaser.Math.Vector2#clone
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} A clone of this Vector2.
     */
    clone: function ()
    {
        return new Vector2(this.x, this.y);
    },

    /**
     * Copy the components of a given Vector into this Vector.
     *
     * @method Phaser.Math.Vector2#copy
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to copy the components from.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    copy: function (src)
    {
        this.x = src.x || 0;
        this.y = src.y || 0;

        return this;
    },

    /**
     * Set the component values of this Vector from a given Vector2Like object.
     *
     * @method Phaser.Math.Vector2#setFromObject
     * @since 3.0.0
     *
     * @param {Vector2Like} obj - The object containing the component values to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setFromObject: function (obj)
    {
        this.x = obj.x || 0;
        this.y = obj.y || 0;

        return this;
    },

    /**
     * Set the `x` and `y` components of the this Vector to the given `x` and `y` values.
     *
     * @method Phaser.Math.Vector2#set
     * @since 3.0.0
     *
     * @param {number} x - The x value to set for this Vector.
     * @param {number} [y=x] - The y value to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    set: function (x, y)
    {
        if (y === undefined) { y = x; }

        this.x = x;
        this.y = y;

        return this;
    },

    /**
     * This method is an alias for `Vector2.set`.
     *
     * @method Phaser.Math.Vector2#setTo
     * @since 3.4.0
     *
     * @param {number} x - The x value to set for this Vector.
     * @param {number} [y=x] - The y value to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setTo: function (x, y)
    {
        return this.set(x, y);
    },

    /**
     * Sets the `x` and `y` values of this object from a given polar coordinate.
     *
     * @method Phaser.Math.Vector2#setToPolar
     * @since 3.0.0
     *
     * @param {number} azimuth - The angular coordinate, in radians.
     * @param {number} [radius=1] - The radial coordinate (length).
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setToPolar: function (azimuth, radius)
    {
        if (radius == null) { radius = 1; }

        this.x = Math.cos(azimuth) * radius;
        this.y = Math.sin(azimuth) * radius;

        return this;
    },

    /**
     * Check whether this Vector is equal to a given Vector.
     *
     * Performs a strict equality check against each Vector's components.
     *
     * @method Phaser.Math.Vector2#equals
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} v - The vector to compare with this Vector.
     *
     * @return {boolean} Whether the given Vector is equal to this Vector.
     */
    equals: function (v)
    {
        return ((this.x === v.x) && (this.y === v.y));
    },

    /**
     * Calculate the angle between this Vector and the positive x-axis, in radians.
     *
     * @method Phaser.Math.Vector2#angle
     * @since 3.0.0
     *
     * @return {number} The angle between this Vector, and the positive x-axis, given in radians.
     */
    angle: function ()
    {
        // computes the angle in radians with respect to the positive x-axis

        var angle = Math.atan2(this.y, this.x);

        if (angle < 0)
        {
            angle += 2 * Math.PI;
        }

        return angle;
    },

    /**
     * Add a given Vector to this Vector. Addition is component-wise.
     *
     * @method Phaser.Math.Vector2#add
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to add to this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    add: function (src)
    {
        this.x += src.x;
        this.y += src.y;

        return this;
    },

    /**
     * Subtract the given Vector from this Vector. Subtraction is component-wise.
     *
     * @method Phaser.Math.Vector2#subtract
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to subtract from this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    subtract: function (src)
    {
        this.x -= src.x;
        this.y -= src.y;

        return this;
    },

    /**
     * Perform a component-wise multiplication between this Vector and the given Vector.
     *
     * Multiplies this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector2#multiply
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to multiply this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    multiply: function (src)
    {
        this.x *= src.x;
        this.y *= src.y;

        return this;
    },

    /**
     * Scale this Vector by the given value.
     *
     * @method Phaser.Math.Vector2#scale
     * @since 3.0.0
     *
     * @param {number} value - The value to scale this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    scale: function (value)
    {
        if (isFinite(value))
        {
            this.x *= value;
            this.y *= value;
        }
        else
        {
            this.x = 0;
            this.y = 0;
        }

        return this;
    },

    /**
     * Perform a component-wise division between this Vector and the given Vector.
     *
     * Divides this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector2#divide
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to divide this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    divide: function (src)
    {
        this.x /= src.x;
        this.y /= src.y;

        return this;
    },

    /**
     * Negate the `x` and `y` components of this Vector.
     *
     * @method Phaser.Math.Vector2#negate
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    negate: function ()
    {
        this.x = -this.x;
        this.y = -this.y;

        return this;
    },

    /**
     * Calculate the distance between this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#distance
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector.
     */
    distance: function (src)
    {
        var dx = src.x - this.x;
        var dy = src.y - this.y;

        return Math.sqrt(dx * dx + dy * dy);
    },

    /**
     * Calculate the distance between this Vector and the given Vector, squared.
     *
     * @method Phaser.Math.Vector2#distanceSq
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector, squared.
     */
    distanceSq: function (src)
    {
        var dx = src.x - this.x;
        var dy = src.y - this.y;

        return dx * dx + dy * dy;
    },

    /**
     * Calculate the length (or magnitude) of this Vector.
     *
     * @method Phaser.Math.Vector2#length
     * @since 3.0.0
     *
     * @return {number} The length of this Vector.
     */
    length: function ()
    {
        var x = this.x;
        var y = this.y;

        return Math.sqrt(x * x + y * y);
    },

    /**
     * Calculate the length of this Vector squared.
     *
     * @method Phaser.Math.Vector2#lengthSq
     * @since 3.0.0
     *
     * @return {number} The length of this Vector, squared.
     */
    lengthSq: function ()
    {
        var x = this.x;
        var y = this.y;

        return x * x + y * y;
    },

    /**
     * Normalize this Vector.
     *
     * Makes the vector a unit length vector (magnitude of 1) in the same direction.
     *
     * @method Phaser.Math.Vector2#normalize
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    normalize: function ()
    {
        var x = this.x;
        var y = this.y;
        var len = x * x + y * y;

        if (len > 0)
        {
            len = 1 / Math.sqrt(len);

            this.x = x * len;
            this.y = y * len;
        }

        return this;
    },

    /**
     * Right-hand normalize (make unit length) this Vector.
     *
     * @method Phaser.Math.Vector2#normalizeRightHand
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    normalizeRightHand: function ()
    {
        var x = this.x;

        this.x = this.y * -1;
        this.y = x;

        return this;
    },

    /**
     * Calculate the dot product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#dot
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector2 to dot product with this Vector2.
     *
     * @return {number} The dot product of this Vector and the given Vector.
     */
    dot: function (src)
    {
        return this.x * src.x + this.y * src.y;
    },

    /**
     * Calculate the cross product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#cross
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector2 to cross with this Vector2.
     *
     * @return {number} The cross product of this Vector and the given Vector.
     */
    cross: function (src)
    {
        return this.x * src.y - this.y * src.x;
    },

    /**
     * Linearly interpolate between this Vector and the given Vector.
     *
     * Interpolates this Vector towards the given Vector.
     *
     * @method Phaser.Math.Vector2#lerp
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector2 to interpolate towards.
     * @param {number} [t=0] - The interpolation percentage, between 0 and 1.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    lerp: function (src, t)
    {
        if (t === undefined) { t = 0; }

        var ax = this.x;
        var ay = this.y;

        this.x = ax + t * (src.x - ax);
        this.y = ay + t * (src.y - ay);

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector2#transformMat3
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    transformMat3: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var m = mat.val;

        this.x = m[0] * x + m[3] * y + m[6];
        this.y = m[1] * x + m[4] * y + m[7];

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector2#transformMat4
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    transformMat4: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var m = mat.val;

        this.x = m[0] * x + m[4] * y + m[12];
        this.y = m[1] * x + m[5] * y + m[13];

        return this;
    },

    /**
     * Make this Vector the zero vector (0, 0).
     *
     * @method Phaser.Math.Vector2#reset
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    reset: function ()
    {
        this.x = 0;
        this.y = 0;

        return this;
    }

});

/**
 * A static zero Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.ZERO
 * @type {Vector2}
 * @since 3.1.0
 */
Vector2.ZERO = new Vector2();

module.exports = Vector2;
<commit_msg>JSDoc update<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

//  Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
//  and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl

var Class = require('../utils/Class');

/**
 * @typedef {object} Vector2Like
 *
 * @property {number} x - The x component.
 * @property {number} y - The y component.
 */

/**
 * @classdesc
 * A representation of a vector in 2D space.
 *
 * A two-component vector.
 *
 * @class Vector2
 * @memberof Phaser.Math
 * @constructor
 * @since 3.0.0
 *
 * @param {number|Vector2Like} [x] - The x component, or an object with `x` and `y` properties.
 * @param {number} [y] - The y component.
 */
var Vector2 = new Class({

    initialize:

    function Vector2 (x, y)
    {
        /**
         * The x component of this Vector.
         *
         * @name Phaser.Math.Vector2#x
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.x = 0;

        /**
         * The y component of this Vector.
         *
         * @name Phaser.Math.Vector2#y
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.y = 0;

        if (typeof x === 'object')
        {
            this.x = x.x || 0;
            this.y = x.y || 0;
        }
        else
        {
            if (y === undefined) { y = x; }

            this.x = x || 0;
            this.y = y || 0;
        }
    },

    /**
     * Make a clone of this Vector2.
     *
     * @method Phaser.Math.Vector2#clone
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} A clone of this Vector2.
     */
    clone: function ()
    {
        return new Vector2(this.x, this.y);
    },

    /**
     * Copy the components of a given Vector into this Vector.
     *
     * @method Phaser.Math.Vector2#copy
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to copy the components from.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    copy: function (src)
    {
        this.x = src.x || 0;
        this.y = src.y || 0;

        return this;
    },

    /**
     * Set the component values of this Vector from a given Vector2Like object.
     *
     * @method Phaser.Math.Vector2#setFromObject
     * @since 3.0.0
     *
     * @param {Vector2Like} obj - The object containing the component values to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setFromObject: function (obj)
    {
        this.x = obj.x || 0;
        this.y = obj.y || 0;

        return this;
    },

    /**
     * Set the `x` and `y` components of the this Vector to the given `x` and `y` values.
     *
     * @method Phaser.Math.Vector2#set
     * @since 3.0.0
     *
     * @param {number} x - The x value to set for this Vector.
     * @param {number} [y=x] - The y value to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    set: function (x, y)
    {
        if (y === undefined) { y = x; }

        this.x = x;
        this.y = y;

        return this;
    },

    /**
     * This method is an alias for `Vector2.set`.
     *
     * @method Phaser.Math.Vector2#setTo
     * @since 3.4.0
     *
     * @param {number} x - The x value to set for this Vector.
     * @param {number} [y=x] - The y value to set for this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setTo: function (x, y)
    {
        return this.set(x, y);
    },

    /**
     * Sets the `x` and `y` values of this object from a given polar coordinate.
     *
     * @method Phaser.Math.Vector2#setToPolar
     * @since 3.0.0
     *
     * @param {number} azimuth - The angular coordinate, in radians.
     * @param {number} [radius=1] - The radial coordinate (length).
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    setToPolar: function (azimuth, radius)
    {
        if (radius == null) { radius = 1; }

        this.x = Math.cos(azimuth) * radius;
        this.y = Math.sin(azimuth) * radius;

        return this;
    },

    /**
     * Check whether this Vector is equal to a given Vector.
     *
     * Performs a strict equality check against each Vector's components.
     *
     * @method Phaser.Math.Vector2#equals
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} v - The vector to compare with this Vector.
     *
     * @return {boolean} Whether the given Vector is equal to this Vector.
     */
    equals: function (v)
    {
        return ((this.x === v.x) && (this.y === v.y));
    },

    /**
     * Calculate the angle between this Vector and the positive x-axis, in radians.
     *
     * @method Phaser.Math.Vector2#angle
     * @since 3.0.0
     *
     * @return {number} The angle between this Vector, and the positive x-axis, given in radians.
     */
    angle: function ()
    {
        // computes the angle in radians with respect to the positive x-axis

        var angle = Math.atan2(this.y, this.x);

        if (angle < 0)
        {
            angle += 2 * Math.PI;
        }

        return angle;
    },

    /**
     * Add a given Vector to this Vector. Addition is component-wise.
     *
     * @method Phaser.Math.Vector2#add
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to add to this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    add: function (src)
    {
        this.x += src.x;
        this.y += src.y;

        return this;
    },

    /**
     * Subtract the given Vector from this Vector. Subtraction is component-wise.
     *
     * @method Phaser.Math.Vector2#subtract
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to subtract from this Vector.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    subtract: function (src)
    {
        this.x -= src.x;
        this.y -= src.y;

        return this;
    },

    /**
     * Perform a component-wise multiplication between this Vector and the given Vector.
     *
     * Multiplies this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector2#multiply
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to multiply this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    multiply: function (src)
    {
        this.x *= src.x;
        this.y *= src.y;

        return this;
    },

    /**
     * Scale this Vector by the given value.
     *
     * @method Phaser.Math.Vector2#scale
     * @since 3.0.0
     *
     * @param {number} value - The value to scale this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    scale: function (value)
    {
        if (isFinite(value))
        {
            this.x *= value;
            this.y *= value;
        }
        else
        {
            this.x = 0;
            this.y = 0;
        }

        return this;
    },

    /**
     * Perform a component-wise division between this Vector and the given Vector.
     *
     * Divides this Vector by the given Vector.
     *
     * @method Phaser.Math.Vector2#divide
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to divide this Vector by.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    divide: function (src)
    {
        this.x /= src.x;
        this.y /= src.y;

        return this;
    },

    /**
     * Negate the `x` and `y` components of this Vector.
     *
     * @method Phaser.Math.Vector2#negate
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    negate: function ()
    {
        this.x = -this.x;
        this.y = -this.y;

        return this;
    },

    /**
     * Calculate the distance between this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#distance
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector.
     */
    distance: function (src)
    {
        var dx = src.x - this.x;
        var dy = src.y - this.y;

        return Math.sqrt(dx * dx + dy * dy);
    },

    /**
     * Calculate the distance between this Vector and the given Vector, squared.
     *
     * @method Phaser.Math.Vector2#distanceSq
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
     *
     * @return {number} The distance from this Vector to the given Vector, squared.
     */
    distanceSq: function (src)
    {
        var dx = src.x - this.x;
        var dy = src.y - this.y;

        return dx * dx + dy * dy;
    },

    /**
     * Calculate the length (or magnitude) of this Vector.
     *
     * @method Phaser.Math.Vector2#length
     * @since 3.0.0
     *
     * @return {number} The length of this Vector.
     */
    length: function ()
    {
        var x = this.x;
        var y = this.y;

        return Math.sqrt(x * x + y * y);
    },

    /**
     * Calculate the length of this Vector squared.
     *
     * @method Phaser.Math.Vector2#lengthSq
     * @since 3.0.0
     *
     * @return {number} The length of this Vector, squared.
     */
    lengthSq: function ()
    {
        var x = this.x;
        var y = this.y;

        return x * x + y * y;
    },

    /**
     * Normalize this Vector.
     *
     * Makes the vector a unit length vector (magnitude of 1) in the same direction.
     *
     * @method Phaser.Math.Vector2#normalize
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    normalize: function ()
    {
        var x = this.x;
        var y = this.y;
        var len = x * x + y * y;

        if (len > 0)
        {
            len = 1 / Math.sqrt(len);

            this.x = x * len;
            this.y = y * len;
        }

        return this;
    },

    /**
     * Right-hand normalize (make unit length) this Vector.
     *
     * @method Phaser.Math.Vector2#normalizeRightHand
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    normalizeRightHand: function ()
    {
        var x = this.x;

        this.x = this.y * -1;
        this.y = x;

        return this;
    },

    /**
     * Calculate the dot product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#dot
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector2 to dot product with this Vector2.
     *
     * @return {number} The dot product of this Vector and the given Vector.
     */
    dot: function (src)
    {
        return this.x * src.x + this.y * src.y;
    },

    /**
     * Calculate the cross product of this Vector and the given Vector.
     *
     * @method Phaser.Math.Vector2#cross
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector2 to cross with this Vector2.
     *
     * @return {number} The cross product of this Vector and the given Vector.
     */
    cross: function (src)
    {
        return this.x * src.y - this.y * src.x;
    },

    /**
     * Linearly interpolate between this Vector and the given Vector.
     *
     * Interpolates this Vector towards the given Vector.
     *
     * @method Phaser.Math.Vector2#lerp
     * @since 3.0.0
     *
     * @param {Phaser.Math.Vector2} src - The Vector2 to interpolate towards.
     * @param {number} [t=0] - The interpolation percentage, between 0 and 1.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    lerp: function (src, t)
    {
        if (t === undefined) { t = 0; }

        var ax = this.x;
        var ay = this.y;

        this.x = ax + t * (src.x - ax);
        this.y = ay + t * (src.y - ay);

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector2#transformMat3
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    transformMat3: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var m = mat.val;

        this.x = m[0] * x + m[3] * y + m[6];
        this.y = m[1] * x + m[4] * y + m[7];

        return this;
    },

    /**
     * Transform this Vector with the given Matrix.
     *
     * @method Phaser.Math.Vector2#transformMat4
     * @since 3.0.0
     *
     * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with.
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    transformMat4: function (mat)
    {
        var x = this.x;
        var y = this.y;
        var m = mat.val;

        this.x = m[0] * x + m[4] * y + m[12];
        this.y = m[1] * x + m[5] * y + m[13];

        return this;
    },

    /**
     * Make this Vector the zero vector (0, 0).
     *
     * @method Phaser.Math.Vector2#reset
     * @since 3.0.0
     *
     * @return {Phaser.Math.Vector2} This Vector2.
     */
    reset: function ()
    {
        this.x = 0;
        this.y = 0;

        return this;
    }

});

/**
 * A static zero Vector2 for use by reference.
 *
 * This constant is meant for comparison operations and should not be modified directly.
 *
 * @constant
 * @name Phaser.Math.Vector2.ZERO
 * @type {Phaser.Math.Vector2}
 * @since 3.1.0
 */
Vector2.ZERO = new Vector2();

module.exports = Vector2;
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import SearchInput from 'components/Texts/SearchInput'
import { connect } from 'react-redux'
import {
  clearUserSearch,
  fetchUsers,
  fetchMoreUsers,
  searchUsers
} from 'redux/actions/UserActions'
import ProfilePanel from '../ProfilePanel'
import LoadMoreButton from 'components/LoadMoreButton'
import Loading from 'components/Loading'
import { addEvent, removeEvent } from 'helpers/listenerHelpers'
import { queryStringForArray } from 'helpers/apiHelpers'
import { stringIsEmpty } from 'helpers/stringHelpers'
import { Color } from 'constants/css'

class People extends Component {
  static propTypes = {
    chatMode: PropTypes.bool,
    clearUserSearch: PropTypes.func.isRequired,
    fetchMoreUsers: PropTypes.func.isRequired,
    fetchUsers: PropTypes.func.isRequired,
    loadMoreButton: PropTypes.bool,
    profiles: PropTypes.array.isRequired,
    searchedProfiles: PropTypes.array.isRequired,
    searchUsers: PropTypes.func.isRequired,
    userId: PropTypes.number
  }

  scrollHeight = 0

  timer = null

  state = {
    searchText: '',
    loading: false,
    loaded: false,
    searching: false
  }

  componentDidMount() {
    const { fetchUsers } = this.props
    addEvent(document.getElementById('react-view'), 'scroll', this.onScroll)
    return fetchUsers().then(() => this.setState({ loaded: true }))
  }

  componentWillUnmount() {
    const { clearUserSearch } = this.props
    clearUserSearch()
    removeEvent(document.getElementById('react-view'), 'scroll', this.onScroll)
  }

  render() {
    const { userId, loadMoreButton, profiles, searchedProfiles } = this.props
    const { loading, loaded, searching, searchText } = this.state
    return (

 {
          this.Container = ref
        }}
      >
        <SearchInput
          addonColor={Color.orange}
          placeholder="Search for users"
          onChange={this.onPeopleSearch}
          value={searchText}
        />

          {!loaded && <Loading text="Loading Users..." />}
          {loaded &&
            !searching &&
            profiles.map(profile => (
              <ProfilePanel
                expandable
                key={profile.id}
                userId={userId}
                profile={profile}
              />
            ))}
          {searching &&
            searchedProfiles.map(profile => (
              <ProfilePanel
                expandable
                key={profile.id}
                userId={userId}
                profile={profile}
              />
            ))}

        {!searching &&
          loaded &&
          loadMoreButton && (
            <LoadMoreButton onClick={this.loadMoreProfiles} loading={loading} />
          )}

    )
  }

  loadMoreProfiles = () => {
    const { fetchMoreUsers, profiles } = this.props
    const { loading } = this.state
    if (!loading) {
      this.setState({ loading: true })
      return fetchMoreUsers(
        queryStringForArray(profiles, 'id', 'shownUsers')
      ).then(() => this.setState({ loading: false }))
    }
  }

  onPeopleSearch = text => {
    const { searchUsers, clearUserSearch } = this.props
    clearTimeout(this.timer)
    this.setState({ searchText: text, searching: !stringIsEmpty(text) })
    if (stringIsEmpty(text)) {
      return clearUserSearch()
    }
    this.timer = setTimeout(() => searchUsers(text), 300)
  }

  onScroll = () => {
    const { chatMode, profiles } = this.props
    if (document.getElementById('react-view').scrollHeight > this.scrollHeight) {
      this.scrollHeight = document.getElementById('react-view').scrollHeight
    }
    if (!chatMode && profiles.length > 0 && this.scrollHeight !== 0) {
      this.setState({ scrollPosition: document.getElementById('react-view').scrollTop }, () => {
        if (
          this.state.scrollPosition >=
          this.Container.offsetHeight - window.innerHeight - 500
        ) {
          this.loadMoreProfiles()
        }
      })
    }
  }
}

export default connect(
  state => ({
    chatMode: state.ChatReducer.chatMode,
    loadMoreButton: state.UserReducer.loadMoreButton,
    profiles: state.UserReducer.profiles,
    searchedProfiles: state.UserReducer.searchedProfiles,
    userId: state.UserReducer.userId
  }),
  {
    clearUserSearch,
    fetchUsers,
    fetchMoreUsers,
    searchUsers
  }
)(People)
<commit_msg>people section margin bottom added<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import SearchInput from 'components/Texts/SearchInput'
import { connect } from 'react-redux'
import {
  clearUserSearch,
  fetchUsers,
  fetchMoreUsers,
  searchUsers
} from 'redux/actions/UserActions'
import ProfilePanel from '../ProfilePanel'
import LoadMoreButton from 'components/LoadMoreButton'
import Loading from 'components/Loading'
import { addEvent, removeEvent } from 'helpers/listenerHelpers'
import { queryStringForArray } from 'helpers/apiHelpers'
import { stringIsEmpty } from 'helpers/stringHelpers'
import { Color } from 'constants/css'

class People extends Component {
  static propTypes = {
    chatMode: PropTypes.bool,
    clearUserSearch: PropTypes.func.isRequired,
    fetchMoreUsers: PropTypes.func.isRequired,
    fetchUsers: PropTypes.func.isRequired,
    loadMoreButton: PropTypes.bool,
    profiles: PropTypes.array.isRequired,
    searchedProfiles: PropTypes.array.isRequired,
    searchUsers: PropTypes.func.isRequired,
    userId: PropTypes.number
  }

  scrollHeight = 0

  timer = null

  state = {
    searchText: '',
    loading: false,
    loaded: false,
    searching: false
  }

  componentDidMount() {
    const { fetchUsers } = this.props
    addEvent(document.getElementById('react-view'), 'scroll', this.onScroll)
    return fetchUsers().then(() => this.setState({ loaded: true }))
  }

  componentWillUnmount() {
    const { clearUserSearch } = this.props
    clearUserSearch()
    removeEvent(document.getElementById('react-view'), 'scroll', this.onScroll)
  }

  render() {
    const { userId, loadMoreButton, profiles, searchedProfiles } = this.props
    const { loading, loaded, searching, searchText } = this.state
    return (

 {
          this.Container = ref
        }}
        style={{ marginBottom: '1rem' }}
      >
        <SearchInput
          addonColor={Color.orange}
          placeholder="Search for users"
          onChange={this.onPeopleSearch}
          value={searchText}
        />

          {!loaded && <Loading text="Loading Users..." />}
          {loaded &&
            !searching &&
            profiles.map(profile => (
              <ProfilePanel
                expandable
                key={profile.id}
                userId={userId}
                profile={profile}
              />
            ))}
          {searching &&
            searchedProfiles.map(profile => (
              <ProfilePanel
                expandable
                key={profile.id}
                userId={userId}
                profile={profile}
              />
            ))}

        {!searching &&
          loaded &&
          loadMoreButton && (
            <LoadMoreButton onClick={this.loadMoreProfiles} loading={loading} />
          )}

    )
  }

  loadMoreProfiles = () => {
    const { fetchMoreUsers, profiles } = this.props
    const { loading } = this.state
    if (!loading) {
      this.setState({ loading: true })
      return fetchMoreUsers(
        queryStringForArray(profiles, 'id', 'shownUsers')
      ).then(() => this.setState({ loading: false }))
    }
  }

  onPeopleSearch = text => {
    const { searchUsers, clearUserSearch } = this.props
    clearTimeout(this.timer)
    this.setState({ searchText: text, searching: !stringIsEmpty(text) })
    if (stringIsEmpty(text)) {
      return clearUserSearch()
    }
    this.timer = setTimeout(() => searchUsers(text), 300)
  }

  onScroll = () => {
    const { chatMode, profiles } = this.props
    if (
      document.getElementById('react-view').scrollHeight > this.scrollHeight
    ) {
      this.scrollHeight = document.getElementById('react-view').scrollHeight
    }
    if (!chatMode && profiles.length > 0 && this.scrollHeight !== 0) {
      this.setState(
        { scrollPosition: document.getElementById('react-view').scrollTop },
        () => {
          if (
            this.state.scrollPosition >=
            this.Container.offsetHeight - window.innerHeight - 500
          ) {
            this.loadMoreProfiles()
          }
        }
      )
    }
  }
}

export default connect(
  state => ({
    chatMode: state.ChatReducer.chatMode,
    loadMoreButton: state.UserReducer.loadMoreButton,
    profiles: state.UserReducer.profiles,
    searchedProfiles: state.UserReducer.searchedProfiles,
    userId: state.UserReducer.userId
  }),
  {
    clearUserSearch,
    fetchUsers,
    fetchMoreUsers,
    searchUsers
  }
)(People)
<|endoftext|>


<commit_before>'use strict';

var helpers = require('../helpers');
var util = require('util');

module.exports = {
    name: 'duplicateProperty',
    nodeTypes: ['block'],
    message: 'Duplicate property: "%s".',

    lint: function duplicatePropertyLinter (config, node) {
        var properties = [];
        var results = [];
        var self = this;

        node.forEach('declaration', function (declaration) {
            var property = declaration.first('property');

            property = helpers.ensureObject(property.first('ident'));

            if (properties.indexOf(property.content) !== -1) {
                results.push({
                    message: util.format(self.message, property.content),
                    column: property.start.column,
                    line: property.start.line
                });
            }

            if (config.exclude.indexOf(property.content) === -1) {
                properties.push(property.content);
            }
        });

        if (results.length) {
            return results;
        }
    }
};
<commit_msg>Fix duplicateProperty crashing on local variables<commit_after>'use strict';

var helpers = require('../helpers');
var util = require('util');

module.exports = {
    name: 'duplicateProperty',
    nodeTypes: ['block'],
    message: 'Duplicate property: "%s".',

    lint: function duplicatePropertyLinter (config, node) {
        var properties = [];
        var results = [];
        var self = this;

        node.forEach('declaration', function (declaration) {
            var property = declaration.first('property');

            property = helpers.ensureObject(property.first('ident'));

            if (property.content && (properties.indexOf(property.content) !== -1)) {
                results.push({
                    message: util.format(self.message, property.content),
                    column: property.start.column,
                    line: property.start.line
                });
            }

            if (config.exclude.indexOf(property.content) === -1) {
                properties.push(property.content);
            }
        });

        if (results.length) {
            return results;
        }
    }
};
<|endoftext|>


<commit_before>!function(a,b){"use strict";"function"==typeof define&&define.amd?define("ajax",b):"object"==typeof exports?exports=module.exports=b():a.ajax=b()}(this,function(){"use strict";function a(a){var d=["get","post","put","delete"];return a=a||{},a.baseUrl=a.baseUrl||"",a.method&&a.url?c(a.method,a.baseUrl+a.url,b(a.data),a):d.reduce(function(d,e){return d[e]=function(d,f){return c(e,a.baseUrl+d,b(f),a)},d},{})}function b(a){return a||null}function c(a,b,c,e){var g=["then","catch","always"],i=g.reduce(function(a,b){return a[b]=function(c){return a[b]=c,a},a},{}),j=new XMLHttpRequest;return j.open(a,b,!0),d(j,e.headers),j.addEventListener("readystatechange",f(i,j),!1),j.send(h(c)),i.abort=function(){return j.abort()},i}function d(a,b){b=b||{},e(b)||(b["Content-Type"]="application/x-www-form-urlencoded"),Object.keys(b).forEach(function(c){b[c]&&a.setRequestHeader(c,b[c])})}function e(a){return Object.keys(a).some(function(a){return"content-type"===a.toLowerCase()})}function f(a,b){return function c(){b.readyState===b.DONE&&(b.removeEventListener("readystatechange",c,!1),a.always.apply(a,g(b)),b.status>=200&&b.status<300?a.then.apply(a,g(b)):a.catch.apply(a,g(b)))}}function g(a){var b;try{b=JSON.parse(a.responseText)}catch(c){b=a.responseText}return[b,a]}function h(a){return i(a)?j(a):a}function i(a){return"[object Object]"===Object.prototype.toString.call(a)}function j(a){return Object.keys(a).reduce(function(b,c){var d=b?b+"&":"";return d+k(c)+"="+k(a[c])},"")}function k(a){return encodeURIComponent(a)}return a});var StreamLabSocket=function(){function a(a){this.appId=a.appId,this.channelName=a.channelName,this.event=a.event,this.channelSecret=a.channelSecret,this.user_id=a.user_id,this.user_secret=a.user_secret,this.id=this.appId,this.secret=this.channelSecret,this.channel=this.channelName,this.events=this.event,this.userId=this.user_id,this.userSecret=this.user_secret,this.init()}return a.prototype.userId=null,a.prototype.userSecret=null,a.prototype.ssl=!0,a.prototype.events=null,a.prototype.secret=null,a.prototype.id="",a.prototype.socket=null,a.prototype.channel=null,a.prototype.timeOut=1e4,a.prototype.url="://api.streamlab.io/apps/",a.prototype.init=function(){this.openNewSocket()},a.prototype.openNewSocket=function(){try{return this.socket=new WebSocket(this.buildUrl()),this.errorConnection(),this.openConnection(),this.resumeConnection(this)}catch(a){return console.log("Stream Lab Have error on open socket check your connection or check your prams .."),!1}},a.prototype.buildUrl=function(){return this.sslAppend()+this.url+this.id+"/channels/"+this.channel+"/messages?events="+this.checkIfEventExists()+this.checkIfChannelPrivate()+this.checkIfUserSubscribe()},a.prototype.sslAppend=function(){return this.ssl===!0?"wss":"ws"},a.prototype.checkIfEventExists=function(){return void 0===this.events?"*":this.events},a.prototype.checkIfChannelPrivate=function(){return void 0===this.secret?"":"&channel_secret="+this.secret},a.prototype.checkIfUserSubscribe=function(){return null!=this.userId&&null!=this.userSecret?"&user_id="+this.userId+"&user_secret="+this.userSecret:""},a.prototype.errorConnection=function(){return this.socket.onerror=function(a){return console.log("StreamLab Connection error ...")}},a.prototype.openConnection=function(){return this.socket.onopen=function(){return console.log("StreamLab Connected Now ...")}},a.prototype.resumeConnection=function(a){return this.socket.onclose=function(){setTimeout(function(){console.log("Stream lab Connection is lost reconnect in "+a.timeOut/1e3+" second .."),a.init()},a.timeOut)}},a.prototype.sendMessage=function(a,b,c){ajax().post(a,b).then(function(a){return c(a)})},a}(),StreamLabHtml=function(){function a(){}return a.prototype.data=null,a.prototype.msgTemplate=[],a.prototype.onlineTemplate=[],a.prototype.channelTemplate=[],a.prototype.onlineNow=0,a.prototype.setData=function(a){return this.data=JSON.parse(a.data),this.onlineNow=this.getOnline()},a.prototype.getSource=function(){return null!=this.data?this.data.data.source:"StreamLabHtml lib cannot find any data"},a.prototype.getOnline=function(){return"channels"===this.getSource()&&this.data.data.data.online},a.prototype.getMessage=function(){return"messages"===this.getSource()&&this.data.data.data.data},a.prototype.getById=function(a){return document.getElementById(a)},a.prototype.getVal=function(a){return this.getById(a).value},a.prototype.setVal=function(a,b){return this.getById(a).value=b},a.prototype.html=function(a,b){return this.getById(a).innerHTML=b},a.prototype.append=function(a,b){var c;return c=this.getById(a),c.innerHTML=c.innerHTML+b},a.prototype.setOnlineAndMessages=function(a,b){return this.setMessages(b),this.setOnline(a)},a.prototype.setMessages=function(a){var b;if(b=this.getMessage(),b!==!1)return 0===this.msgTemplate.length?this.append(a,b+"
"):this.extractTemplate(a,this.msgTemplate,b)},a.prototype.extractTemplate=function(a,b,c,d){d=void 0===d?"":d;var e;e="";for(var f=0;f<=b.length;f++)e+=0==f?"<"+b[f]:1==f?" id='"+b[f]+"'":2==f?"  class='"+b[f]+"'":d+">"+c+"</"+b[0]+">";return this.append(a,e)},a.prototype.setOnline=function(a){var b;b=this.getOnline(),b!==!1&&this.html(a,b)},a.prototype.showOnlineUsers=function(a,b,c){try{var d="",e=b.data;e=void 0===e.length?[e]:e;for(var f=0;f<e.length;f++)if(this.userInList(e[f].id)){d="";for(var g=0==e[f].online?"offline":"Online",h=0;h<c.length;h++)void 0!==e[f].data[c[h]]&&(d+=c[h]+" : "+e[f].data[c[h]],d+="
");d+=' status : '+g+"",this.onlineTemplate.length>0?this.extractTemplate(a,this.onlineTemplate,d,'data-id="'+e[f].id+'"'):(d+="
",this.extractTemplate(a,["span","",""],d,'data-id="'+e[f].id+'"'))}}catch(a){console.log("There are error on user info")}},a.prototype.addEventListener=function(a,b,c){return this.getById(a).addEventListener(b,function(a){a.preventDefault(),c()})},a.prototype.hide=function(a){return this.setAttr(a,"style","display:none")},a.prototype.show=function(a){return this.removeAttr(a,"style")},a.prototype.setAttr=function(a,b,c){return this.getById(a).setAttribute(b,c)},a.prototype.getAttr=function(a,b){return this.getById(a).getAttribute(b)},a.prototype.removeAttr=function(a,b){return this.getById(a).removeAttribute(b)},a.prototype.updateUserList=function(a,b){"user.online"==this.getSource()&&(this.updateList("online"),void 0===a?"":a(this.data.data.data.userID)),"user.offline"==this.getSource()&&(this.updateList("offline"),void 0===b?"":b(this.data.data.data.userID))},a.prototype.updateList=function(a){var b=document.querySelectorAll('[data-status="'+this.data.data.data.userID+'"]');void 0!==b[0]&&(b[0].innerHTML="status : "+a)},a.prototype.userInList=function(a){var b=document.querySelectorAll('[data-id="'+a+'"]');return void 0===b[0]},a.prototype.updateChannelOnline=function(a){if("channels"==this.getSource())return void 0===a?this.updateNumber(this.data.data.data.id):a},a.prototype.updateNumber=function(a){var b=document.querySelectorAll('[data-channel-online="'+a+'"]');void 0!==b[0]&&(b[0].innerHTML=this.getOnline())},a.prototype.getAllChannel=function(a,b,c){c=void 0===c?"streamLab/app/getAllChannels":c;var d=this;ajax().get(c).then(function(c){b=void 0===b?d.extractChannel(a,c):b(c)})},a.prototype.extractChannel=function(a,b){for(var c=b.data,d="",e=0;e<c.length;e++)this.channelTemplate.length>0?this.extractTemplate(a,this.channelTemplate,"name : "+c[e].name+"
 online : "+c[e].online+"","data-channel='"+c[e].id+"'"):(d="",d+="name : "+c[e].name+"
 online : "+c[e].online+"
",this.append(a,d))},a}(),StreamLabUser=function(){function a(){}return a.prototype.deleteUser=function(a,b,c){this.checkDeleteUser(a,b,c)},a.prototype.userExist=function(a,b,c){this.checkDeleteUser(a,b,c)},a.prototype.createUser=function(a,b,c){this.createUpdateUser(a,b,c)},a.prototype.updateUser=function(a,b,c){this.createUpdateUser(a,b,c)},a.prototype.getAllUser=function(a,b,c,d,e){c=void 0===c?"":"?limit="+c,d=void 0===d?"":"&offset="+d,e=void 0===e?"":"&channel="+e,ajax().get(a+c+d+e).then(function(a){return b(a)})},a.prototype.createUpdateUser=function(a,b,c){ajax().post(a,b).then(function(a){return c(a)})},a.prototype.checkDeleteUser=function(a,b,c){return void 0===b?"You Must Select id ..":(b="integer"==typeof b?b:parseInt(b),void ajax().get(a+"?id="+b).then(function(a){return c(a)}))},a.prototype.json=function(a){try{return JSON.parse(a)}catch(b){return a}},a}(),StreamLabNotification=function(){function a(){this.init()}return a.prototype.browserNotification=!0,a.prototype.icon="/StreamLab/fb-pro.png",a.prototype.time=500,a.prototype.init=function(){if(this.browserNotification)return this.notificationsPermission(this)},a.prototype.makeNotification=function(a,b){if(this.browserNotification){var c=this.notificationOption(b);return this.appendNotification(a,c)}},a.prototype.appendNotification=function(a,b){try{return new Notification(a,b)}catch(a){console.log(a)}},a.prototype.notificationOption=function(a){return{body:a,icon:this.icon,timeout:this.time}},a.prototype.notificationsPermission=function(a){Notification.requestPermission().then(function(b){if("denied"===b)return a.browserNotification=!1})},a}();
<commit_msg>Update StreamLab.js<commit_after>!function(a,b){"use strict";"function"==typeof define&&define.amd?define("ajax",b):"object"==typeof exports?exports=module.exports=b():a.ajax=b()}(this,function(){"use strict";function a(a){var d=["get","post","put","delete"];return a=a||{},a.baseUrl=a.baseUrl||"",a.method&&a.url?c(a.method,a.baseUrl+a.url,b(a.data),a):d.reduce(function(d,e){return d[e]=function(d,f){return c(e,a.baseUrl+d,b(f),a)},d},{})}function b(a){return a||null}function c(a,b,c,e){var g=["then","catch","always"],i=g.reduce(function(a,b){return a[b]=function(c){return a[b]=c,a},a},{}),j=new XMLHttpRequest;return j.open(a,b,!0),d(j,e.headers),j.addEventListener("readystatechange",f(i,j),!1),j.send(h(c)),i.abort=function(){return j.abort()},i}function d(a,b){b=b||{},e(b)||(b["Content-Type"]="application/x-www-form-urlencoded"),Object.keys(b).forEach(function(c){b[c]&&a.setRequestHeader(c,b[c])})}function e(a){return Object.keys(a).some(function(a){return"content-type"===a.toLowerCase()})}function f(a,b){return function c(){b.readyState===b.DONE&&(b.removeEventListener("readystatechange",c,!1),a.always.apply(a,g(b)),b.status>=200&&b.status<300?a.then.apply(a,g(b)):a.catch.apply(a,g(b)))}}function g(a){var b;try{b=JSON.parse(a.responseText)}catch(c){b=a.responseText}return[b,a]}function h(a){return i(a)?j(a):a}function i(a){return"[object Object]"===Object.prototype.toString.call(a)}function j(a){return Object.keys(a).reduce(function(b,c){var d=b?b+"&":"";return d+k(c)+"="+k(a[c])},"")}function k(a){return encodeURIComponent(a)}return a});var StreamLabSocket=function(){function a(a){this.appId=a.appId,this.channelName=a.channelName,this.event=a.event,this.channelSecret=a.channelSecret,this.user_id=a.user_id,this.user_secret=a.user_secret,this.id=this.appId,this.secret=this.channelSecret,this.channel=this.channelName,this.events=this.event,this.userId=this.user_id,this.userSecret=this.user_secret,this.init()}return a.prototype.userId=null,a.prototype.userSecret=null,a.prototype.ssl=!0,a.prototype.events=null,a.prototype.secret=null,a.prototype.id="",a.prototype.socket=null,a.prototype.channel=null,a.prototype.timeOut=1e4,a.prototype.url="://api.streamlab.io/apps/",a.prototype.init=function(){this.openNewSocket()},a.prototype.openNewSocket=function(){try{return this.socket=new WebSocket(this.buildUrl()),this.errorConnection(),this.openConnection(),this.resumeConnection(this)}catch(a){return console.log("Stream Lab Have error on open socket check your connection or check your prams .."),!1}},a.prototype.buildUrl=function(){return this.sslAppend()+this.url+this.id+"/channels/"+this.channel+"/messages?events="+this.checkIfEventExists()+this.checkIfChannelPrivate()+this.checkIfUserSubscribe()},a.prototype.sslAppend=function(){return this.ssl===!0?"wss":"ws"},a.prototype.checkIfEventExists=function(){return void 0===this.events?"*":this.events},a.prototype.checkIfChannelPrivate=function(){return void 0===this.secret?"":"&channel_secret="+this.secret},a.prototype.checkIfUserSubscribe=function(){return null!=this.userId&&null!=this.userSecret?"&user_id="+this.userId+"&user_secret="+this.userSecret:""},a.prototype.errorConnection=function(){return this.socket.onerror=function(a){return console.log("StreamLab Connection error ...")}},a.prototype.openConnection=function(){return this.socket.onopen=function(){return console.log("StreamLab Connected Now ...")}},a.prototype.resumeConnection=function(a){return this.socket.onclose=function(){setTimeout(function(){console.log("Stream lab Connection is lost reconnect in "+a.timeOut/1e3+" second .."),a.init()},a.timeOut)}},a.prototype.sendMessage=function(a,b,c){ajax().post(a,b).then(function(a){return c(a)})},a}(),StreamLabHtml=function(){function a(){}return a.prototype.data=null,a.prototype.msgTemplate=[],a.prototype.onlineTemplate=[],a.prototype.channelTemplate=[],a.prototype.onlineNow=0,a.prototype.setData=function(a){return this.data=JSON.parse(a.data),this.onlineNow=this.getOnline()},a.prototype.getSource=function(){return null!=this.data?this.data.data.source:"StreamLabHtml lib cannot find any data"},a.prototype.getOnline=function(){return"channels"===this.getSource()&&this.data.data.data.online},a.prototype.getMessage=function(){return"messages"===this.getSource()&&this.data.data.data.data},a.prototype.getById=function(a){return document.getElementById(a)},a.prototype.getVal=function(a){return this.getById(a).value},a.prototype.setVal=function(a,b){return this.getById(a).value=b},a.prototype.html=function(a,b){return this.getById(a).innerHTML=b},a.prototype.append=function(a,b){var c;return c=this.getById(a),c.innerHTML=c.innerHTML+b},a.prototype.setOnlineAndMessages=function(a,b){return this.setMessages(b),this.setOnline(a)},a.prototype.setMessages=function(a){var b;if(b=this.getMessage(),b!==!1)return 0===this.msgTemplate.length?this.append(a,b+"
"):this.extractTemplate(a,this.msgTemplate,b)},a.prototype.extractTemplate=function(a,b,c,d){d=void 0===d?"":d;var e;e="";for(var f=0;f<=b.length;f++)e+=0==f?"<"+b[f]:1==f?" id='"+b[f]+"'":2==f?"  class='"+b[f]+"'":d+">"+c+"</"+b[0]+">";return this.append(a,e)},a.prototype.setOnline=function(a){var b;b=this.getOnline(),b!==!1&&this.html(a,b)},a.prototype.showOnlineUsers=function(a,b,c){try{var d="",e=b.data;e=void 0===e.length?[e]:e;for(var f=0;f<e.length;f++)if(this.userInList(e[f].id)){d="";for(var g=0==e[f].online?"offline":"Online",h=0;h<c.length;h++)void 0!==e[f].data[c[h]]&&(d+=c[h]+" : "+e[f].data[c[h]],d+="
");d+=' status : '+g+"",this.onlineTemplate.length>0?this.extractTemplate(a,this.onlineTemplate,d,'data-id="'+e[f].id+'"'):(d+="
",this.extractTemplate(a,["span","",""],d,'data-id="'+e[f].id+'"'))}}catch(a){console.log("There are error on user info")}},a.prototype.addEventListener=function(a,b,c){return this.getById(a).addEventListener(b,function(a){a.preventDefault(),c()})},a.prototype.hide=function(a){return this.setAttr(a,"style","display:none")},a.prototype.show=function(a){return this.removeAttr(a,"style")},a.prototype.setAttr=function(a,b,c){return this.getById(a).setAttribute(b,c)},a.prototype.getAttr=function(a,b){return this.getById(a).getAttribute(b)},a.prototype.removeAttr=function(a,b){return this.getById(a).removeAttribute(b)},a.prototype.updateUserList=function(a,b){"user.online"==this.getSource()&&(this.updateList("online"),void 0===a?"":a(this.data.data.data.userID)),"user.offline"==this.getSource()&&(this.updateList("offline"),void 0===b?"":b(this.data.data.data.userID))},a.prototype.updateList=function(a){var b=document.querySelectorAll('[data-status="'+this.data.data.data.userID+'"]');void 0!==b[0]&&(b[0].innerHTML="status : "+a)},a.prototype.userInList=function(a){var b=document.querySelectorAll('[data-id="'+a+'"]');return void 0===b[0]},a.prototype.updateChannelOnline=function(a){if("channels"==this.getSource())return void 0===a?this.updateNumber(this.data.data.data.id):a},a.prototype.updateNumber=function(a){var b=document.querySelectorAll('[data-channel-online="'+a+'"]');void 0!==b[0]&&(b[0].innerHTML=this.getOnline())},a.prototype.getAllChannel=function(a,b,c){c=void 0===c?"streamLab/app/getAllChannels":c;var d=this;ajax().get(c).then(function(c){b=void 0===b?d.extractChannel(a,c):b(c)})},a.prototype.extractChannel=function(a,b){for(var c=b.data,d="",e=0;e<c.length;e++)this.channelTemplate.length>0?this.extractTemplate(a,this.channelTemplate,"name : "+c[e].name+"
 online : "+c[e].online+"","data-channel='"+c[e].id+"'"):(d="",d+="name : "+c[e].name+"
 online : "+c[e].online+"
",this.append(a,d))},a.prototype.getChannel=function(a,b,c,d){b=void 0===b||null==b?"":"&secret="+b,d=void 0===d?"/streamLab/app/get/channel":d,ajax().get(d+"?channelName="+a+b).then(function(a){c(a)})},a}(),StreamLabUser=function(){function a(){}return a.prototype.deleteUser=function(a,b,c){this.checkDeleteUser(a,b,c)},a.prototype.userExist=function(a,b,c){this.checkDeleteUser(a,b,c)},a.prototype.createUser=function(a,b,c){this.createUpdateUser(a,b,c)},a.prototype.updateUser=function(a,b,c){this.createUpdateUser(a,b,c)},a.prototype.getAllUser=function(a,b,c,d,e){c=void 0===c?"":"?limit="+c,d=void 0===d?"":"&offset="+d,e=void 0===e?"":"&channel="+e,ajax().get(a+c+d+e).then(function(a){return b(a)})},a.prototype.createUpdateUser=function(a,b,c){ajax().post(a,b).then(function(a){return c(a)})},a.prototype.checkDeleteUser=function(a,b,c){return void 0===b?"You Must Select id ..":(b="integer"==typeof b?b:parseInt(b),void ajax().get(a+"?id="+b).then(function(a){return c(a)}))},a.prototype.json=function(a){try{return JSON.parse(a)}catch(b){return a}},a}(),StreamLabNotification=function(){function a(){this.init()}return a.prototype.browserNotification=!0,a.prototype.icon="/StreamLab/fb-pro.png",a.prototype.time=500,a.prototype.init=function(){if(this.browserNotification)return this.notificationsPermission(this)},a.prototype.makeNotification=function(a,b){if(this.browserNotification){var c=this.notificationOption(b);return this.appendNotification(a,c)}},a.prototype.appendNotification=function(a,b){try{return new Notification(a,b)}catch(a){console.log(a)}},a.prototype.notificationOption=function(a){return{body:a,icon:this.icon,timeout:this.time}},a.prototype.notificationsPermission=function(a){Notification.requestPermission().then(function(b){if("denied"===b)return a.browserNotification=!1})},a}();
<|endoftext|>


<commit_before>const request = require('request');
const qs = require('querystring');
const Promise = require('bluebird');
const moment = require('moment');
const chrono = require('chrono-node')

const makeRequest = (path, params={}, app='mobile/euro2016', version=2) => {
    const url = `http://daaseuro2016.uefa.com/api/v${version}/${app}/en/${path}?${qs.stringify(params).replace('%24', '$')}`;
    // console.log(url);
    return new Promise((resolve, reject) => {
        request.get(url, (err, response, body) => {
            if (err) {
                reject(new Error('Oops! I can\t get that for you right now. Try again later?'));
                return;
            }
            if (response.statusCode !== 200) {
                reject(new Error('Oops! I can\'t get that for you right now. Try again later?'));
                return;
            }
            resolve(JSON.parse(body));
        });
    });
};

const getGroups = () => {
    return makeRequest('groups', { tournamentPhase: 2 });
};

const getGroup = groupId => {
    return new Promise((resolve, reject) => {
        getGroups().then(resp => {
            const group = resp.groups.filter(group => group.groupName.toUpperCase() === `GROUP ${groupId.toUpperCase()}`).shift();
            if (!group) {
                reject(new Error('No such group.'));
                return;
            }
            return resolve(group);
        });
    });
};

const getGroupByTeam = findTeam => {
    return new Promise((resolve, reject) => {
        getGroups().then(resp => {
            const group = resp.groups.filter(group => {
                return group.standings.filter(({ team }) => {
                    const reg = new RegExp(findTeam.replace(' ', '.*'));
                    return reg.test(team.officialName);
                }).length > 0
            }).shift();
            if (!group) {
                reject(new Error('Oops! I can\'t find that country.'));
                return;
            }
            return resolve(group);
        });
    });
};

const getMatches = (queryDate) => {
    if (!queryDate) {
        queryDate = moment();
    }
    if (typeof queryDate === 'string') {
        queryDate = moment(chrono.parseDate(queryDate));
    }
    return new Promise((resolve, reject) => {
        makeRequest('competitions/3/seasons/2016/matches', {
            dateFrom: '20160501',
            dateTo: '20160712',
            isMobileApp: 'true',
            '$top': 100
        }, 'football')
        .then(resp => {
            const matches = resp.matchInfoItems.filter(({ dateTime }) => moment(dateTime).isSame(queryDate, 'day')).sort((a, b) => moment(a.dateTime).isAfter(moment(b.dateTime)));
            resolve({
                matches, queryDate
            })
        });
    });
};

module.exports = { getGroups, getGroup, getGroupByTeam, getMatches };
<commit_msg>allow case insensitive search for teams<commit_after>const request = require('request');
const qs = require('querystring');
const Promise = require('bluebird');
const moment = require('moment');
const chrono = require('chrono-node')

const makeRequest = (path, params={}, app='mobile/euro2016', version=2) => {
    const url = `http://daaseuro2016.uefa.com/api/v${version}/${app}/en/${path}?${qs.stringify(params).replace('%24', '$')}`;
    // console.log(url);
    return new Promise((resolve, reject) => {
        request.get(url, (err, response, body) => {
            if (err) {
                reject(new Error('Oops! I can\t get that for you right now. Try again later?'));
                return;
            }
            if (response.statusCode !== 200) {
                reject(new Error('Oops! I can\'t get that for you right now. Try again later?'));
                return;
            }
            resolve(JSON.parse(body));
        });
    });
};

const getGroups = () => {
    return makeRequest('groups', { tournamentPhase: 2 });
};

const getGroup = groupId => {
    return new Promise((resolve, reject) => {
        getGroups().then(resp => {
            const group = resp.groups.filter(group => group.groupName.toUpperCase() === `GROUP ${groupId.toUpperCase()}`).shift();
            if (!group) {
                reject(new Error('No such group.'));
                return;
            }
            return resolve(group);
        });
    });
};

const getGroupByTeam = findTeam => {
    return new Promise((resolve, reject) => {
        getGroups().then(resp => {
            const group = resp.groups.filter(group => {
                return group.standings.filter(({ team }) => {
                    const reg = new RegExp(findTeam.replace(' ', '.*'), 'i');
                    return reg.test(team.officialName);
                }).length > 0
            }).shift();
            if (!group) {
                reject(new Error('Oops! I can\'t find that country.'));
                return;
            }
            return resolve(group);
        });
    });
};

const getMatches = (queryDate) => {
    if (!queryDate) {
        queryDate = moment();
    }
    if (typeof queryDate === 'string') {
        queryDate = moment(chrono.parseDate(queryDate));
    }
    return new Promise((resolve, reject) => {
        makeRequest('competitions/3/seasons/2016/matches', {
            dateFrom: '20160501',
            dateTo: '20160712',
            isMobileApp: 'true',
            '$top': 100
        }, 'football')
        .then(resp => {
            const matches = resp.matchInfoItems.filter(({ dateTime }) => moment(dateTime).isSame(queryDate, 'day')).sort((a, b) => moment(a.dateTime).isAfter(moment(b.dateTime)));
            resolve({
                matches, queryDate
            })
        });
    });
};

module.exports = { getGroups, getGroup, getGroupByTeam, getMatches };
<|endoftext|>