<commit_before>/*
 * The MIT License
 *
 * Copyright 2015 Cheng Deng, Xing Liu and Mi Tian
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/* global d3, L, moment */

// Variables
var map,
        svg,
        g,
        circlesGroup,
        tip,
        dataJson,
        feature,
        width = $(window).width(),
        height = $(window).height(),
        startingValue,
        endingValue,
        currentTag = "#ParisAttacks";

// Unix date converter
function dateConverter(unixTime) {
    return new Date(unixTime * 1000);
}

function unixConverter(date) {
    return moment(date).unix();
}

// No image handler
function imgError(image) {
    image.onerror = "";
    image.src = "images/noimage.jpg";
    return true;
}

function setup(dataUrl, mapUrl, viewCenter, zoom) {
    // Load data
    d3.json(dataUrl, function (data) {
        // Pre-processing data
        var i, obj;
        dataJson = [];

        // Sort array by time
        data.sort(function (a, b) {
            return dateConverter(a.created_time) - dateConverter(b.created_time);
        });
        //    console.log(data);
        if (data.length > 0) {
            for (i = 0; i < data.length; i++) {
                row = data[i];
                obj = {
                    images: row.images,
                    location: row.location,
                    created_time: dateConverter(row.created_time),
                    caption: row.caption,
                    tagCounts: i + 1
                };
                dataJson.push(obj);
            }
        }

        //    drawCircles();
        drawAreaChart();
        startWatchingMap();
    });

    /*
     * Credits
     * Leafletjs
     * Openstreetmap
     */
    map = new L.Map("hashtagTrendsMapSvg", {
        attributionControl: false
    })
            .setView(viewCenter, zoom);

    // Map dark matter
    // https://cartodb.com/basemaps/
    L.tileLayer(mapUrl, {
        minZoom: 2,
        maxZoom: 12
    }).addTo(map);

    // Initialize the SVG layer
    map._initPathRoot();

    // Add an SVG element to Leaflet’s overlay pane
    svg = d3.select("#hashtagTrendsMapSvg").select("svg"),
            circlesGroup = svg.append("g").attr("class", "circlesGroup");

    tip = d3.tip().attr("class", "tooltip").html(function (d, i) {
        return "

"
                + ""
                + "
"
                + "
"
                + "
Created on:
" + moment(d.created_time).format("llll z") + "
"
                + "
Location:
" + d.location.name + "

";
    });

    svg.call(tip);
}
setup("data/parisattacks.json",
        "http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", [7.8, 60], 2);

function drawCircles(newData) {

    newData.forEach(function (d) {
        // Lat & Lng
        if (d.location.latitude && d.location.longitude) {
            d.LatLng = new L.LatLng(d.location.latitude,
                    d.location.longitude);
        }
    });

    // Remove old circles
    circlesGroup.selectAll("circle").remove();

    // Append new circles
    feature = circlesGroup.selectAll("circle")
            .data(newData)
            .enter().append("circle")
            .attr("r", 8)
            .attr("class", "hashTagCircles")
            .on("mouseover", tip.show);

    visUpdate();
}

function startWatchingMap() {
    map.on("viewreset", visUpdate);
    visUpdate();
}

function visUpdate() {

    feature.attr("transform",
            function (d) {
                if (d.LatLng) {
                    return "translate(" +
                            map.latLngToLayerPoint(d.LatLng).x + "," +
                            map.latLngToLayerPoint(d.LatLng).y + ")";
                }
            }
    );
}

// Function to draw area chart
function drawAreaChart() {

    // References
    // Area chart timeline
    // http://bl.ocks.org/mbostock/3883195

    var margin = {top: 40, right: 20, bottom: 40, left: 50},
    h = 180,
            areaChartWidth = width - margin.left - margin.right - 40,
            areaChartHeight = h - margin.top - margin.bottom;

    startingValue = dataJson[0].created_time;
    endingValue = dataJson[dataJson.length - 1].created_time;

    // Find data range
    var xMin = d3.min(dataJson, function (d) {
        return Math.min(d.created_time);
    }),
            xMax = d3.max(dataJson, function (d) {
                return Math.max(d.created_time);
            }),
            yMin = d3.min(dataJson, function (d) {
                return Math.min(d.tagCounts);
            }),
            yMax = d3.max(dataJson, function (d) {
                return Math.max(d.tagCounts);
            });

    var x = d3.time.scale()
            .domain([xMin, xMax])
            .range([0, areaChartWidth])
            .clamp(true);

    var y = d3.scale.linear()
            .domain([yMin, yMax])
            .range([areaChartHeight, 0]);

    var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom")
            .tickFormat(d3.time.format("%m/%d %I%p"));

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left")
            .ticks(4);

    var line = d3.svg.line()
            .interpolate("basis")
            .x(function (d) {
                return x(d.created_time);
            })
            .y(function (d) {
                return y(d.tagCounts);
            });

    var area = d3.svg.area()
            .x(function (d) {
                return x(d.created_time);
            })
            .y0(areaChartHeight)
            .y1(function (d) {
                return y(d.tagCounts);
            });

    var areaChartSvg = d3.select("#areaChartSvg").append("svg")
            .attr("width", "75%")
            .attr("height", "100%")
            .attr("viewBox", "0 0 " + width + " " + h)
            .attr("preserveAspectRatio", "xMinYMid meet")
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    areaChartSvg.append("clipPath")
            .attr("id", "rectClip")
            .append("rect")
            .attr("width", 0)
            .attr("height", areaChartHeight);

    areaChartSvg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + areaChartHeight + ")")
            .call(xAxis)
            .selectAll("text")
            .attr("x", 39)
            .attr("dx", "-.8em")
            .attr("dy", ".72em")
            //            .attr("transform", "rotate(-15)")
            .style("text-anchor", "end");

    areaChartSvg.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("Hashtags");

    areaChartSvg.append("path")
            .datum(dataJson)
            .attr("class", "line")
            .attr("d", line)
            .attr("clip-path", "url(#rectClip)");

    areaChartSvg.append("path")
            .datum(dataJson)
            .attr("class", "area")
            .attr("d", area)
            .attr("clip-path", "url(#rectClip)");

    var brush = d3.svg.brush()
            .x(x)
            .extent([startingValue, startingValue])
            .on("brush", brushed);

    var slider = areaChartSvg.append("g")
            .attr("class", "slider")
            .call(brush);

    slider.selectAll(".extent,.resize")
            .remove();

    slider.select(".background")
            .attr("height", areaChartHeight);

    var handle = slider.append("g")
            .attr("class", "handle");

    handle.append("path")
            .attr("transform", "translate(0," + areaChartHeight + ")")
            .attr("d", "M 0 -100 V 0");

    handle.append("text")
            .text(startingValue)
            .attr("transform", "translate(" + (-18) + " ," + (areaChartHeight - 125) + ")");

    slider
            .call(brush.event);

    function brushed() {
        var value = brush.extent()[0];

        if (d3.event.sourceEvent) {
            handle.select('path');
            value = x.invert(d3.mouse(this)[0]);
            brush.extent([value, value]);
        }

        handle.attr("transform", "translate(" + x(value) + ",0)");
        handle.select("text").text(moment(value).format("MM/DD HH:mm"));

        var newData = dataJson.filter(function (circle) {
            return circle.created_time < value;
        });

        drawCircles(newData);
        showImages(newData);
    }

    function playAnimation(timeout) {

        // Show image section
        $("#hashtagTrendsDesc").addClass("hide");
        $("#hashtagImages").removeClass("hide");

        // Play animated slider
        slider
                .call(brush.event)
                .transition() // gratuitous intro!
                .duration(timeout)
                .call(brush.extent([x.domain()[1], x.domain()[1]]))
                .call(brush.event);

        // Play animated area chart
        d3.select("#rectClip rect")
                .transition().duration(timeout)
                .attr("width", areaChartWidth);
    }

    function reset() {
        // Reset slider
        slider
                .call(brush.event)
                .call(brush.extent([startingValue, startingValue]))
                .call(brush.event);
        // Reset area chart
        d3.select("#rectClip rect")
                .attr("width", 0);
        // Reset image section
        $("#hashtagImages").html("");
        $("#hashtagImages").addClass("hide");
        $("#hashtagTrendsDesc").removeClass("hide");
    }

    $("#playButton").click(function () {
        playAnimation(20000);
        $("#playButton").attr("disabled", "disabled");
        $("#resetButton").attr("disabled", "disabled");

        setTimeout(function () {
            $("#playButton").removeAttr("disabled");
            $("#resetButton").removeAttr("disabled");
        }, 20000);
    });

    // Listen to click of reset button
    $("#resetButton").click(function () {
        reset();
    });

    // Listen to hashtag selector dropdown
    $(".dropdown-menu li a").click(function () {
        var selText = $(this).text();
        if (selText !== currentTag) {
            currentTag = selText;
            $(this).parents('.btn-group').find('.dropdown-toggle').html(selText + ' ');

            reset();
            // Reset map and area chart container
            map.remove();
            $("#areaChartSvg").html("");
            switch (currentTag) {
                case "#BostonStrong":
                    setup("data/bostonstrong.json",
                            "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", [7.8, 60], 2);
                    $("body").addClass("normal").removeClass("invert");
                    $("p.tagDescription").html("The hashtag #BostonStrong spread on "
                            + "Instagram after the Boston Marathon bombing.");
                    break;
                default:
                    setup("data/parisattacks.json",
                            "http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", [7.8, 60], 2);
                    $("body").addClass("invert").removeClass("normal");
                    $("p.tagDescription").html("The hashtag #ParisAttacks spread on "
                            + "Instagram after a series of attacks shook Paris.");
                    break;
            }
        }
        $("body").on("click", tip.hide);
    });
}

var lastDrawnIndex = 0;

function showImages(newData) {

    // Append to element
    var elem = $("#hashtagImages");

    while (lastDrawnIndex < newData.length) {
        // some image does not have a caption
        var captionText = "";
        if (newData[lastDrawnIndex].caption !== null) {
            captionText = newData[lastDrawnIndex].caption.text;
        }

        elem.prepend(""
                + "");
        lastDrawnIndex++;
    }
}

// Close tooltip when click elsewhere
$("body").on("click", tip.hide);<commit_msg>fix image append bug<commit_after>/*
 * The MIT License
 *
 * Copyright 2015 Cheng Deng, Xing Liu and Mi Tian
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/* global d3, L, moment */

// Variables
var map,
        svg,
        g,
        circlesGroup,
        tip,
        dataJson,
        feature,
        width = $(window).width(),
        height = $(window).height(),
        startingValue,
        endingValue,
        currentTag = "#ParisAttacks",
        lastDrawnIndex = 0;

// Unix date converter
function dateConverter(unixTime) {
    return new Date(unixTime * 1000);
}

function unixConverter(date) {
    return moment(date).unix();
}

// No image handler
function imgError(image) {
    image.onerror = "";
    image.src = "images/noimage.jpg";
    return true;
}

function setup(dataUrl, mapUrl, viewCenter, zoom) {
    // Load data
    d3.json(dataUrl, function (data) {
        // Pre-processing data
        var i, obj;
        dataJson = [];

        // Sort array by time
        data.sort(function (a, b) {
            return dateConverter(a.created_time) - dateConverter(b.created_time);
        });
        //    console.log(data);
        if (data.length > 0) {
            for (i = 0; i < data.length; i++) {
                row = data[i];
                obj = {
                    images: row.images,
                    location: row.location,
                    created_time: dateConverter(row.created_time),
                    caption: row.caption,
                    tagCounts: i + 1
                };
                dataJson.push(obj);
            }
        }

        //    drawCircles();
        drawAreaChart();
        startWatchingMap();
    });

    /*
     * Credits
     * Leafletjs
     * Openstreetmap
     */
    map = new L.Map("hashtagTrendsMapSvg", {
        attributionControl: false
    })
            .setView(viewCenter, zoom);

    // Map dark matter
    // https://cartodb.com/basemaps/
    L.tileLayer(mapUrl, {
        minZoom: 2,
        maxZoom: 12
    }).addTo(map);

    // Initialize the SVG layer
    map._initPathRoot();

    // Add an SVG element to Leaflet’s overlay pane
    svg = d3.select("#hashtagTrendsMapSvg").select("svg"),
            circlesGroup = svg.append("g").attr("class", "circlesGroup");

    tip = d3.tip().attr("class", "tooltip").html(function (d, i) {
        return "

"
                + ""
                + "
"
                + "
"
                + "
Created on:
" + moment(d.created_time).format("llll z") + "
"
                + "
Location:
" + d.location.name + "

";
    });

    svg.call(tip);
}
setup("data/parisattacks.json",
        "http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", [7.8, 60], 2);

function drawCircles(newData) {

    newData.forEach(function (d) {
        // Lat & Lng
        if (d.location.latitude && d.location.longitude) {
            d.LatLng = new L.LatLng(d.location.latitude,
                    d.location.longitude);
        }
    });

    // Remove old circles
    circlesGroup.selectAll("circle").remove();

    // Append new circles
    feature = circlesGroup.selectAll("circle")
            .data(newData)
            .enter().append("circle")
            .attr("r", 8)
            .attr("class", "hashTagCircles")
            .on("mouseover", tip.show);

    visUpdate();
}

function startWatchingMap() {
    map.on("viewreset", visUpdate);
    visUpdate();
}

function visUpdate() {

    feature.attr("transform",
            function (d) {
                if (d.LatLng) {
                    return "translate(" +
                            map.latLngToLayerPoint(d.LatLng).x + "," +
                            map.latLngToLayerPoint(d.LatLng).y + ")";
                }
            }
    );
}

// Function to draw area chart
function drawAreaChart() {

    // References
    // Area chart timeline
    // http://bl.ocks.org/mbostock/3883195

    var margin = {top: 40, right: 20, bottom: 40, left: 50},
    h = 180,
            areaChartWidth = width - margin.left - margin.right - 40,
            areaChartHeight = h - margin.top - margin.bottom;

    startingValue = dataJson[0].created_time;
    endingValue = dataJson[dataJson.length - 1].created_time;

    // Find data range
    var xMin = d3.min(dataJson, function (d) {
        return Math.min(d.created_time);
    }),
            xMax = d3.max(dataJson, function (d) {
                return Math.max(d.created_time);
            }),
            yMin = d3.min(dataJson, function (d) {
                return Math.min(d.tagCounts);
            }),
            yMax = d3.max(dataJson, function (d) {
                return Math.max(d.tagCounts);
            });

    var x = d3.time.scale()
            .domain([xMin, xMax])
            .range([0, areaChartWidth])
            .clamp(true);

    var y = d3.scale.linear()
            .domain([yMin, yMax])
            .range([areaChartHeight, 0]);

    var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom")
            .tickFormat(d3.time.format("%m/%d %I%p"));

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left")
            .ticks(4);

    var line = d3.svg.line()
            .interpolate("basis")
            .x(function (d) {
                return x(d.created_time);
            })
            .y(function (d) {
                return y(d.tagCounts);
            });

    var area = d3.svg.area()
            .x(function (d) {
                return x(d.created_time);
            })
            .y0(areaChartHeight)
            .y1(function (d) {
                return y(d.tagCounts);
            });

    var areaChartSvg = d3.select("#areaChartSvg").append("svg")
            .attr("width", "75%")
            .attr("height", "100%")
            .attr("viewBox", "0 0 " + width + " " + h)
            .attr("preserveAspectRatio", "xMinYMid meet")
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    areaChartSvg.append("clipPath")
            .attr("id", "rectClip")
            .append("rect")
            .attr("width", 0)
            .attr("height", areaChartHeight);

    areaChartSvg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + areaChartHeight + ")")
            .call(xAxis)
            .selectAll("text")
            .attr("x", 39)
            .attr("dx", "-.8em")
            .attr("dy", ".72em")
            //            .attr("transform", "rotate(-15)")
            .style("text-anchor", "end");

    areaChartSvg.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("Hashtags");

    areaChartSvg.append("path")
            .datum(dataJson)
            .attr("class", "line")
            .attr("d", line)
            .attr("clip-path", "url(#rectClip)");

    areaChartSvg.append("path")
            .datum(dataJson)
            .attr("class", "area")
            .attr("d", area)
            .attr("clip-path", "url(#rectClip)");

    var brush = d3.svg.brush()
            .x(x)
            .extent([startingValue, startingValue])
            .on("brush", brushed);

    var slider = areaChartSvg.append("g")
            .attr("class", "slider")
            .call(brush);

    slider.selectAll(".extent,.resize")
            .remove();

    slider.select(".background")
            .attr("height", areaChartHeight);

    var handle = slider.append("g")
            .attr("class", "handle");

    handle.append("path")
            .attr("transform", "translate(0," + areaChartHeight + ")")
            .attr("d", "M 0 -100 V 0");

    handle.append("text")
            .text(startingValue)
            .attr("transform", "translate(" + (-18) + " ," + (areaChartHeight - 125) + ")");

    slider
            .call(brush.event);

    function brushed() {
        var value = brush.extent()[0];

        if (d3.event.sourceEvent) {
            handle.select('path');
            value = x.invert(d3.mouse(this)[0]);
            brush.extent([value, value]);
        }

        handle.attr("transform", "translate(" + x(value) + ",0)");
        handle.select("text").text(moment(value).format("MM/DD HH:mm"));

        var newData = dataJson.filter(function (circle) {
            return circle.created_time < value;
        });

        drawCircles(newData);
        showImages(newData);
    }

    function playAnimation(timeout) {

        // Show image section
        $("#hashtagTrendsDesc").addClass("hide");
        $("#hashtagImages").removeClass("hide");

        // Play animated slider
        slider
                .call(brush.event)
                .transition() // gratuitous intro!
                .duration(timeout)
                .call(brush.extent([x.domain()[1], x.domain()[1]]))
                .call(brush.event);

        // Play animated area chart
        d3.select("#rectClip rect")
                .transition().duration(timeout)
                .attr("width", areaChartWidth);
    }

    function reset() {
        // Reset slider
        slider
                .call(brush.event)
                .call(brush.extent([startingValue, startingValue]))
                .call(brush.event);
        // Reset area chart
        d3.select("#rectClip rect")
                .attr("width", 0);
        // Reset image section
        $("#hashtagImages").html("");
        $("#hashtagImages").addClass("hide");
        $("#hashtagTrendsDesc").removeClass("hide");
        lastDrawnIndex = 0;
    }

    $("#playButton").click(function () {
        playAnimation(20000);
        $("#playButton").attr("disabled", "disabled");
        $("#resetButton").attr("disabled", "disabled");

        setTimeout(function () {
            $("#playButton").removeAttr("disabled");
            $("#resetButton").removeAttr("disabled");
        }, 20000);
    });

    // Listen to click of reset button
    $("#resetButton").click(function () {
        reset();
    });

    // Listen to hashtag selector dropdown
    $(".dropdown-menu li a").click(function () {
        var selText = $(this).text();
        if (selText !== currentTag) {
            currentTag = selText;
            $(this).parents('.btn-group').find('.dropdown-toggle').html(selText + ' ');

            reset();
            // Reset map and area chart container
            map.remove();
            $("#areaChartSvg").html("");
            switch (currentTag) {
                case "#BostonStrong":
                    setup("data/bostonstrong.json",
                            "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", [7.8, 60], 2);
                    $("body").addClass("normal").removeClass("invert");
                    $("p.tagDescription").html("The hashtag #BostonStrong spread on "
                            + "Instagram after the Boston Marathon bombing.");
                    break;
                default:
                    setup("data/parisattacks.json",
                            "http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", [7.8, 60], 2);
                    $("body").addClass("invert").removeClass("normal");
                    $("p.tagDescription").html("The hashtag #ParisAttacks spread on "
                            + "Instagram after a series of attacks shook Paris.");
                    break;
            }
        }
        $("body").on("click", tip.hide);
    });
}

function showImages(newData) {

    // Append to element
    var elem = $("#hashtagImages");

    while (lastDrawnIndex < newData.length) {
        // some image does not have a caption
        var captionText = "";
        if (newData[lastDrawnIndex].caption !== null) {
            captionText = newData[lastDrawnIndex].caption.text;
        }

        elem.prepend(""
                + "");
        lastDrawnIndex++;
    }
}

// Close tooltip when click elsewhere
$("body").on("click", tip.hide);<|endoftext|>


<commit_before>var opts = {
    count: 3,
    size: 50,
    sizeRandom: 10,
    sparkLife: 0.1,
    spawnOpacity: 1,

    //must be RGBA. alpha stands for opacity, usually 1
    color: "rgba(0,0,0, alpha)"
  },

  canvasBody = document.getElementById("canvas"),
  canvas = canvasBody.getContext("2d"),
  h = canvasBody.width = window.innerWidth,
  w = canvasBody.height = window.innerHeight;
//document.getElementsByClassName("card")[0].style["background-color"] = opts.color.replace("alp", "1");
function step() {
  var fillColor = opts.color.replace("alpha", opts.spawnOpacity);
  canvas.fillStyle = fillColor;
  for (var i = 0; i < Math.round(opts.count); i++) {
    var random = Math.random() * opts.sizeRandom;
    canvas.fillRect(-(opts.size/2) + Math.random() * h, -(opts.size/2) + Math.random() * w, opts.size + random, opts.size + random)
  }
  canvas.fillStyle = "rgba(255,255,255," + opts.sparkLife + ")"
  canvas.fillRect(0, 0, h, w)
}

function anim() {
  setTimeout(function() {
    window.requestAnimationFrame(anim)
  }, 1000 / 30)
  step();
}

anim();
window.addEventListener("resize", function(){
  w = canvasBody.width = window.innerWidth;
  h = canvasBody.height = window.innerHeight;
})
<commit_msg>3.2.1<commit_after>var opts = {
    count: 3,
    size: 50,
    sizeRandom: 10,
    sparkLife: 0.1,
    spawnOpacity: 1,

    //must be RGBA. alpha stands for opacity, usually 1
    color: "rgba(0,0,0, alpha)"
  },

  canvasBody = document.getElementById("canvas"),
  canvas = canvasBody.getContext("2d"),
  w = canvasBody.width = window.innerWidth,
  h = canvasBody.height = window.innerHeight;
//document.getElementsByClassName("card")[0].style["background-color"] = opts.color.replace("alp", "1");
function step() {
  var fillColor = opts.color.replace("alpha", opts.spawnOpacity);
  canvas.fillStyle = fillColor;
  for (var i = 0; i < Math.round(opts.count); i++) {
    var random = Math.random() * opts.sizeRandom;
    canvas.fillRect(-(opts.size/2) + Math.random() * w, -(opts.size/2) + Math.random() * h, opts.size + random, opts.size + random)
  }
  canvas.fillStyle = "rgba(255,255,255," + opts.sparkLife + ")"
  canvas.fillRect(0, 0, w, h)
}

function anim() {
  setTimeout(function() {
    window.requestAnimationFrame(anim)
  }, 1000 / 30)
  step();
}

anim();
window.addEventListener("resize", function(){
  w = canvasBody.width = window.innerWidth;
  h = canvasBody.height = window.innerHeight;
})
<|endoftext|>


<commit_before>/*
   Copyright 2014 Nebez Briefkani
   floppybird - main.js

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

var debugmode = false;

var states = Object.freeze({
   SplashScreen: 0,
   GameScreen: 1,
   ScoreScreen: 2
});

var currentstate;

var gravity = 0.25;
var velocity = 0;
var position = 180;
var rotation = 0;
var jump = -4.6;

var score = 0;
var highscore = 0;

var pipeheight = 90;
var pipewidth = 52;
var pipes = new Array();

var replayclickable = false;

//sounds
var volume = 30;
var soundJump = new buzz.sound("assets/sounds/sfx_wing.ogg");
var soundScore = new buzz.sound("assets/sounds/sfx_point.ogg");
var soundHit = new buzz.sound("assets/sounds/sfx_hit.ogg");
var soundDie = new buzz.sound("assets/sounds/sfx_die.ogg");
var soundSwoosh = new buzz.sound("assets/sounds/sfx_swooshing.ogg");
buzz.all().setVolume(volume);

//loops
var loopGameloop;
var loopPipeloop;

$(document).ready(function() {
   if(window.location.search == "?debug")
      debugmode = true;
   if(window.location.search == "?easy")
      pipeheight = 200;

   //get the highscore
   var savedscore = getCookie("highscore");
   if(savedscore != "")
      highscore = parseInt(savedscore);

   //start with the splash screen
   showSplash();
});

function getCookie(cname)
{
   var name = cname + "=";
   var ca = document.cookie.split(';');
   for(var i=0; i<ca.length; i++)
   {
      var c = ca[i].trim();
      if (c.indexOf(name)==0) return c.substring(name.length,c.length);
   }
   return "";
}

function setCookie(cname,cvalue,exdays)
{
   var d = new Date();
   d.setTime(d.getTime()+(exdays*24*60*60*1000));
   var expires = "expires="+d.toGMTString();
   document.cookie = cname + "=" + cvalue + "; " + expires;
}

function showSplash()
{
   currentstate = states.SplashScreen;

   //set the defaults (again)
   velocity = 0;
   position = 180;
   rotation = 0;
   score = 0;

   //update the player in preparation for the next game
   $("#player").css({ y: 0, x: 0});
   updatePlayer($("#player"));

   soundSwoosh.stop();
   soundSwoosh.play();

   //clear out all the pipes if there are any
   $(".pipe").remove();
   pipes = new Array();

   //make everything animated again
   $(".animated").css('animation-play-state', 'running');
   $(".animated").css('-webkit-animation-play-state', 'running');

   //fade in the splash
   $("#splash").transition({ opacity: 1 }, 2000, 'ease');
}

function startGame()
{
   currentstate = states.GameScreen;

   //fade out the splash
   $("#splash").stop();
   $("#splash").transition({ opacity: 0 }, 500, 'ease');

   //update the big score
   setBigScore();

   //debug mode?
   if(debugmode)
   {
      //show the bounding boxes
      $(".boundingbox").show();
   }

   //start up our loops
   var updaterate = 1000.0 / 60.0 ; //60 times a second
   loopGameloop = setInterval(gameloop, updaterate);
   loopPipeloop = setInterval(updatePipes, 1400);

   //jump from the start!
   playerJump();
}

function updatePlayer(player)
{
   //rotation
   rotation = Math.min((velocity / 10) * 90, 90);

   //apply rotation and position
   $(player).css({ rotate: rotation, top: position });
}

function gameloop() {
   var player = $("#player");

   //update the player speed/position
   velocity += gravity;
   position += velocity;

   //update the player
   updatePlayer(player);

   //create the bounding box
   var box = document.getElementById('player').getBoundingClientRect();
   var origwidth = 34.0;
   var origheight = 24.0;

   var boxwidth = origwidth - (Math.sin(Math.abs(rotation) / 90) * 8);
   var boxheight = (origheight + box.height) / 2;
   var boxleft = ((box.width - boxwidth) / 2) + box.left;
   var boxtop = ((box.height - boxheight) / 2) + box.top;
   var boxright = boxleft + boxwidth;
   var boxbottom = boxtop + boxheight;

   //if we're in debug mode, draw the bounding box
   if(debugmode)
   {
      var boundingbox = $("#playerbox");
      boundingbox.css('left', boxleft);
      boundingbox.css('top', boxtop);
      boundingbox.css('height', boxheight);
      boundingbox.css('width', boxwidth);
   }

   //did we hit the ground?
   if(box.bottom >= $("#land").offset().top)
   {
      playerDead();
      return;
   }

   //have they tried to escape through the ceiling? :o
   var ceiling = $("#ceiling");
   if(boxtop <= (ceiling.offset().top + ceiling.height()))
      position = 0;

   //we can't go any further without a pipe
   if(pipes[0] == null)
      return;

   //determine the bounding box of the next pipes inner area
   var nextpipe = pipes[0];
   var nextpipeupper = nextpipe.children(".pipe_upper");

   var pipetop = nextpipeupper.offset().top + nextpipeupper.height();
   var pipeleft = nextpipeupper.offset().left - 2; // for some reason it starts at the inner pipes offset, not the outer pipes.
   var piperight = pipeleft + pipewidth;
   var pipebottom = pipetop + pipeheight;

   if(debugmode)
   {
      var boundingbox = $("#pipebox");
      boundingbox.css('left', pipeleft);
      boundingbox.css('top', pipetop);
      boundingbox.css('height', pipeheight);
      boundingbox.css('width', pipewidth);
   }

   //have we gotten inside the pipe yet?
   if(boxright > pipeleft)
   {
      //we're within the pipe, have we passed between upper and lower pipes?
      if(boxtop > pipetop && boxbottom < pipebottom)
      {
         //yeah! we're within bounds

      }
      else
      {
         //no! we touched the pipe
         playerDead();
         return;
      }
   }

   //have we passed the imminent danger?
   if(boxleft > piperight)
   {
      //yes, remove it
      pipes.splice(0, 1);

      //and score a point
      playerScore();
   }
}

//Handle space bar
$(document).keydown(function(e){
   //space bar!
   if(e.keyCode == 32)
   {
      //in ScoreScreen, hitting space should click the "replay" button. else it's just a regular spacebar hit
      if(currentstate == states.ScoreScreen)
         $("#replay").click();
      else
         screenClick();
   }
});

//Handle mouse down OR touch start
if("ontouchstart" in window)
   $(document).on("touchstart", screenClick);
else
   $(document).on("mousedown", screenClick);

function screenClick()
{
   if(currentstate == states.GameScreen)
   {
      playerJump();
   }
   else if(currentstate == states.SplashScreen)
   {
      startGame();
   }
}

function playerJump()
{
   velocity = jump;
   //play jump sound
   soundJump.stop();
   soundJump.play();
}

function setBigScore(erase)
{
   var elemscore = $("#bigscore");
   elemscore.empty();

   if(erase)
      return;

   var digits = score.toString().split('');
   for(var i = 0; i < digits.length; i++)
      elemscore.append("");
}

function setSmallScore()
{
   var elemscore = $("#currentscore");
   elemscore.empty();

   var digits = score.toString().split('');
   for(var i = 0; i < digits.length; i++)
      elemscore.append("");
}

function setHighScore()
{
   var elemscore = $("#highscore");
   elemscore.empty();

   var digits = highscore.toString().split('');
   for(var i = 0; i < digits.length; i++)
      elemscore.append("");
}

function setMedal()
{
   var elemmedal = $("#medal");
   elemmedal.empty();

   if(score < 10)
      //signal that no medal has been won
      return false;

   if(score >= 10)
      medal = "bronze";
   if(score >= 20)
      medal = "silver";
   if(score >= 30)
      medal = "gold";
   if(score >= 40)
      medal = "platinum";

   elemmedal.append('');

   //signal that a medal has been won
   return true;
}

function playerDead()
{
   //stop animating everything!
   $(".animated").css('animation-play-state', 'paused');
   $(".animated").css('-webkit-animation-play-state', 'paused');

   //drop the bird to the floor
   var playerbottom = $("#player").position().top + $("#player").width(); //we use width because he'll be rotated 90 deg
   var floor = $("#flyarea").height();
   var movey = Math.max(0, floor - playerbottom);
   $("#player").transition({ y: movey + 'px', rotate: 90}, 1000, 'easeInOutCubic');

   //it's time to change states. as of now we're considered ScoreScreen to disable left click/flying
   currentstate = states.ScoreScreen;

   //destroy our gameloops
   clearInterval(loopGameloop);
   clearInterval(loopPipeloop);
   loopGameloop = null;
   loopPipeloop = null;

   //mobile browsers don't support buzz bindOnce event
   if(isIncompatible.any())
   {
      //skip right to showing score
      showScore();
   }
   else
   {
      //play the hit sound (then the dead sound) and then show score
      soundHit.play().bindOnce("ended", function() {
         soundDie.play().bindOnce("ended", function() {
            showScore();
         });
      });
   }
}

function showScore()
{
   //unhide us
   $("#scoreboard").css("display", "block");

   //remove the big score
   setBigScore(true);

   //have they beaten their high score?
   if(score > highscore)
   {
      //yeah!
      highscore = score;
      //save it!
      setCookie("highscore", highscore, 999);
   }

   //update the scoreboard
   setSmallScore();
   setHighScore();
   var wonmedal = setMedal();

   //SWOOSH!
   soundSwoosh.stop();
   soundSwoosh.play();

   //show the scoreboard
   $("#scoreboard").css({ y: '40px', opacity: 0 }); //move it down so we can slide it up
   $("#replay").css({ y: '40px', opacity: 0 });
   $("#scoreboard").transition({ y: '0px', opacity: 1}, 600, 'ease', function() {
      //When the animation is done, animate in the replay button and SWOOSH!
      soundSwoosh.stop();
      soundSwoosh.play();
      $("#replay").transition({ y: '0px', opacity: 1}, 600, 'ease');

      //also animate in the MEDAL! WOO!
      if(wonmedal)
      {
         $("#medal").css({ scale: 2, opacity: 0 });
         $("#medal").transition({ opacity: 1, scale: 1 }, 1200, 'ease');
      }
   });

   //make the replay button clickable
   replayclickable = true;
}

$("#replay").click(function() {
   //make sure we can only click once
   if(!replayclickable)
      return;
   else
      replayclickable = false;
   //SWOOSH!
   soundSwoosh.stop();
   soundSwoosh.play();

   //fade out the scoreboard
   $("#scoreboard").transition({ y: '-40px', opacity: 0}, 1000, 'ease', function() {
      //when that's done, display us back to nothing
      $("#scoreboard").css("display", "none");

      //start the game over!
      showSplash();
   });
});

function playerScore()
{
   score += 1;
   //play score sound
   soundScore.stop();
   soundScore.play();
   setBigScore();
}

function updatePipes()
{
   //Do any pipes need removal?
   $(".pipe").filter(function() { return $(this).position().left <= -100; }).remove()

   //add a new pipe (top height + bottom height  + pipeheight == 420) and put it in our tracker
   var padding = 80;
   var constraint = 420 - pipeheight - (padding * 2); //double padding (for top and bottom)
   var topheight = Math.floor((Math.random()*constraint) + padding); //add lower padding
   var bottomheight = (420 - pipeheight) - topheight;
   var newpipe = $('

');
   $("#flyarea").append(newpipe);
   pipes.push(newpipe);
}

var isIncompatible = {
   Android: function() {
   return navigator.userAgent.match(/Android/i);
   },
   BlackBerry: function() {
   return navigator.userAgent.match(/BlackBerry/i);
   },
   iOS: function() {
   return navigator.userAgent.match(/iPhone|iPad|iPod/i);
   },
   Opera: function() {
   return navigator.userAgent.match(/Opera Mini/i);
   },
   Safari: function() {
   return (navigator.userAgent.match(/OS X.*Safari/) && ! navigator.userAgent.match(/Chrome/));
   },
   Windows: function() {
   return navigator.userAgent.match(/IEMobile/i);
   },
   any: function() {
   return (isIncompatible.Android() || isIncompatible.BlackBerry() || isIncompatible.iOS() || isIncompatible.Opera() || isIncompatible.Safari() || isIncompatible.Windows());
   }
};<commit_msg>always win a bronze medal to make the delicate flower happier<commit_after>/*
   Copyright 2014 Nebez Briefkani
   floppybird - main.js

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

var debugmode = false;

var states = Object.freeze({
   SplashScreen: 0,
   GameScreen: 1,
   ScoreScreen: 2
});

var currentstate;

var gravity = 0.25;
var velocity = 0;
var position = 180;
var rotation = 0;
var jump = -4.6;

var score = 0;
var highscore = 0;

var pipeheight = 90;
var pipewidth = 52;
var pipes = new Array();

var replayclickable = false;

//sounds
var volume = 30;
var soundJump = new buzz.sound("assets/sounds/sfx_wing.ogg");
var soundScore = new buzz.sound("assets/sounds/sfx_point.ogg");
var soundHit = new buzz.sound("assets/sounds/sfx_hit.ogg");
var soundDie = new buzz.sound("assets/sounds/sfx_die.ogg");
var soundSwoosh = new buzz.sound("assets/sounds/sfx_swooshing.ogg");
buzz.all().setVolume(volume);

//loops
var loopGameloop;
var loopPipeloop;

$(document).ready(function() {
   if(window.location.search == "?debug")
      debugmode = true;
   if(window.location.search == "?easy")
      pipeheight = 200;

   //get the highscore
   var savedscore = getCookie("highscore");
   if(savedscore != "")
      highscore = parseInt(savedscore);

   //start with the splash screen
   showSplash();
});

function getCookie(cname)
{
   var name = cname + "=";
   var ca = document.cookie.split(';');
   for(var i=0; i<ca.length; i++)
   {
      var c = ca[i].trim();
      if (c.indexOf(name)==0) return c.substring(name.length,c.length);
   }
   return "";
}

function setCookie(cname,cvalue,exdays)
{
   var d = new Date();
   d.setTime(d.getTime()+(exdays*24*60*60*1000));
   var expires = "expires="+d.toGMTString();
   document.cookie = cname + "=" + cvalue + "; " + expires;
}

function showSplash()
{
   currentstate = states.SplashScreen;

   //set the defaults (again)
   velocity = 0;
   position = 180;
   rotation = 0;
   score = 0;

   //update the player in preparation for the next game
   $("#player").css({ y: 0, x: 0});
   updatePlayer($("#player"));

   soundSwoosh.stop();
   soundSwoosh.play();

   //clear out all the pipes if there are any
   $(".pipe").remove();
   pipes = new Array();

   //make everything animated again
   $(".animated").css('animation-play-state', 'running');
   $(".animated").css('-webkit-animation-play-state', 'running');

   //fade in the splash
   $("#splash").transition({ opacity: 1 }, 2000, 'ease');
}

function startGame()
{
   currentstate = states.GameScreen;

   //fade out the splash
   $("#splash").stop();
   $("#splash").transition({ opacity: 0 }, 500, 'ease');

   //update the big score
   setBigScore();

   //debug mode?
   if(debugmode)
   {
      //show the bounding boxes
      $(".boundingbox").show();
   }

   //start up our loops
   var updaterate = 1000.0 / 60.0 ; //60 times a second
   loopGameloop = setInterval(gameloop, updaterate);
   loopPipeloop = setInterval(updatePipes, 1400);

   //jump from the start!
   playerJump();
}

function updatePlayer(player)
{
   //rotation
   rotation = Math.min((velocity / 10) * 90, 90);

   //apply rotation and position
   $(player).css({ rotate: rotation, top: position });
}

function gameloop() {
   var player = $("#player");

   //update the player speed/position
   velocity += gravity;
   position += velocity;

   //update the player
   updatePlayer(player);

   //create the bounding box
   var box = document.getElementById('player').getBoundingClientRect();
   var origwidth = 34.0;
   var origheight = 24.0;

   var boxwidth = origwidth - (Math.sin(Math.abs(rotation) / 90) * 8);
   var boxheight = (origheight + box.height) / 2;
   var boxleft = ((box.width - boxwidth) / 2) + box.left;
   var boxtop = ((box.height - boxheight) / 2) + box.top;
   var boxright = boxleft + boxwidth;
   var boxbottom = boxtop + boxheight;

   //if we're in debug mode, draw the bounding box
   if(debugmode)
   {
      var boundingbox = $("#playerbox");
      boundingbox.css('left', boxleft);
      boundingbox.css('top', boxtop);
      boundingbox.css('height', boxheight);
      boundingbox.css('width', boxwidth);
   }

   //did we hit the ground?
   if(box.bottom >= $("#land").offset().top)
   {
      playerDead();
      return;
   }

   //have they tried to escape through the ceiling? :o
   var ceiling = $("#ceiling");
   if(boxtop <= (ceiling.offset().top + ceiling.height()))
      position = 0;

   //we can't go any further without a pipe
   if(pipes[0] == null)
      return;

   //determine the bounding box of the next pipes inner area
   var nextpipe = pipes[0];
   var nextpipeupper = nextpipe.children(".pipe_upper");

   var pipetop = nextpipeupper.offset().top + nextpipeupper.height();
   var pipeleft = nextpipeupper.offset().left - 2; // for some reason it starts at the inner pipes offset, not the outer pipes.
   var piperight = pipeleft + pipewidth;
   var pipebottom = pipetop + pipeheight;

   if(debugmode)
   {
      var boundingbox = $("#pipebox");
      boundingbox.css('left', pipeleft);
      boundingbox.css('top', pipetop);
      boundingbox.css('height', pipeheight);
      boundingbox.css('width', pipewidth);
   }

   //have we gotten inside the pipe yet?
   if(boxright > pipeleft)
   {
      //we're within the pipe, have we passed between upper and lower pipes?
      if(boxtop > pipetop && boxbottom < pipebottom)
      {
         //yeah! we're within bounds

      }
      else
      {
         //no! we touched the pipe
         playerDead();
         return;
      }
   }

   //have we passed the imminent danger?
   if(boxleft > piperight)
   {
      //yes, remove it
      pipes.splice(0, 1);

      //and score a point
      playerScore();
   }
}

//Handle space bar
$(document).keydown(function(e){
   //space bar!
   if(e.keyCode == 32)
   {
      //in ScoreScreen, hitting space should click the "replay" button. else it's just a regular spacebar hit
      if(currentstate == states.ScoreScreen)
         $("#replay").click();
      else
         screenClick();
   }
});

//Handle mouse down OR touch start
if("ontouchstart" in window)
   $(document).on("touchstart", screenClick);
else
   $(document).on("mousedown", screenClick);

function screenClick()
{
   if(currentstate == states.GameScreen)
   {
      playerJump();
   }
   else if(currentstate == states.SplashScreen)
   {
      startGame();
   }
}

function playerJump()
{
   velocity = jump;
   //play jump sound
   soundJump.stop();
   soundJump.play();
}

function setBigScore(erase)
{
   var elemscore = $("#bigscore");
   elemscore.empty();

   if(erase)
      return;

   var digits = score.toString().split('');
   for(var i = 0; i < digits.length; i++)
      elemscore.append("");
}

function setSmallScore()
{
   var elemscore = $("#currentscore");
   elemscore.empty();

   var digits = score.toString().split('');
   for(var i = 0; i < digits.length; i++)
      elemscore.append("");
}

function setHighScore()
{
   var elemscore = $("#highscore");
   elemscore.empty();

   var digits = highscore.toString().split('');
   for(var i = 0; i < digits.length; i++)
      elemscore.append("");
}

function setMedal()
{
   var elemmedal = $("#medal");
   elemmedal.empty();

   //if(score < 10)
      //signal that no medal has been won
   //   return false;

  // if(score >= 10)
      medal = "bronze";
   if(score >= 20)
      medal = "silver";
   if(score >= 30)
      medal = "gold";
   if(score >= 40)
      medal = "platinum";

   elemmedal.append('');

   //signal that a medal has been won
   return true;
}

function playerDead()
{
   //stop animating everything!
   $(".animated").css('animation-play-state', 'paused');
   $(".animated").css('-webkit-animation-play-state', 'paused');

   //drop the bird to the floor
   var playerbottom = $("#player").position().top + $("#player").width(); //we use width because he'll be rotated 90 deg
   var floor = $("#flyarea").height();
   var movey = Math.max(0, floor - playerbottom);
   $("#player").transition({ y: movey + 'px', rotate: 90}, 1000, 'easeInOutCubic');

   //it's time to change states. as of now we're considered ScoreScreen to disable left click/flying
   currentstate = states.ScoreScreen;

   //destroy our gameloops
   clearInterval(loopGameloop);
   clearInterval(loopPipeloop);
   loopGameloop = null;
   loopPipeloop = null;

   //mobile browsers don't support buzz bindOnce event
   if(isIncompatible.any())
   {
      //skip right to showing score
      showScore();
   }
   else
   {
      //play the hit sound (then the dead sound) and then show score
      soundHit.play().bindOnce("ended", function() {
         soundDie.play().bindOnce("ended", function() {
            showScore();
         });
      });
   }
}

function showScore()
{
   //unhide us
   $("#scoreboard").css("display", "block");

   //remove the big score
   setBigScore(true);

   //have they beaten their high score?
   if(score > highscore)
   {
      //yeah!
      highscore = score;
      //save it!
      setCookie("highscore", highscore, 999);
   }

   //update the scoreboard
   setSmallScore();
   setHighScore();
   var wonmedal = setMedal();

   //SWOOSH!
   soundSwoosh.stop();
   soundSwoosh.play();

   //show the scoreboard
   $("#scoreboard").css({ y: '40px', opacity: 0 }); //move it down so we can slide it up
   $("#replay").css({ y: '40px', opacity: 0 });
   $("#scoreboard").transition({ y: '0px', opacity: 1}, 600, 'ease', function() {
      //When the animation is done, animate in the replay button and SWOOSH!
      soundSwoosh.stop();
      soundSwoosh.play();
      $("#replay").transition({ y: '0px', opacity: 1}, 600, 'ease');

      //also animate in the MEDAL! WOO!
      if(wonmedal)
      {
         $("#medal").css({ scale: 2, opacity: 0 });
         $("#medal").transition({ opacity: 1, scale: 1 }, 1200, 'ease');
      }
   });

   //make the replay button clickable
   replayclickable = true;
}

$("#replay").click(function() {
   //make sure we can only click once
   if(!replayclickable)
      return;
   else
      replayclickable = false;
   //SWOOSH!
   soundSwoosh.stop();
   soundSwoosh.play();

   //fade out the scoreboard
   $("#scoreboard").transition({ y: '-40px', opacity: 0}, 1000, 'ease', function() {
      //when that's done, display us back to nothing
      $("#scoreboard").css("display", "none");

      //start the game over!
      showSplash();
   });
});

function playerScore()
{
   score += 1;
   //play score sound
   soundScore.stop();
   soundScore.play();
   setBigScore();
}

function updatePipes()
{
   //Do any pipes need removal?
   $(".pipe").filter(function() { return $(this).position().left <= -100; }).remove()

   //add a new pipe (top height + bottom height  + pipeheight == 420) and put it in our tracker
   var padding = 80;
   var constraint = 420 - pipeheight - (padding * 2); //double padding (for top and bottom)
   var topheight = Math.floor((Math.random()*constraint) + padding); //add lower padding
   var bottomheight = (420 - pipeheight) - topheight;
   var newpipe = $('

');
   $("#flyarea").append(newpipe);
   pipes.push(newpipe);
}

var isIncompatible = {
   Android: function() {
   return navigator.userAgent.match(/Android/i);
   },
   BlackBerry: function() {
   return navigator.userAgent.match(/BlackBerry/i);
   },
   iOS: function() {
   return navigator.userAgent.match(/iPhone|iPad|iPod/i);
   },
   Opera: function() {
   return navigator.userAgent.match(/Opera Mini/i);
   },
   Safari: function() {
   return (navigator.userAgent.match(/OS X.*Safari/) && ! navigator.userAgent.match(/Chrome/));
   },
   Windows: function() {
   return navigator.userAgent.match(/IEMobile/i);
   },
   any: function() {
   return (isIncompatible.Android() || isIncompatible.BlackBerry() || isIncompatible.iOS() || isIncompatible.Opera() || isIncompatible.Safari() || isIncompatible.Windows());
   }
};
<|endoftext|>


<commit_before>$(document).ready(function () {
	//Init Variables
	var choices = [".choice1", ".choice2", ".choice3", ".choice4"];
	var randomQ = Math.floor(Math.random() * choices.length);
	//log random answer
	console.log(randomQ);
	var Num = 0;
	var pointcounter = 0;
	var NoClicks = true;
	var notification = $('.notification');

	//Question

	function Question(image, answer, choice, etchoice) {
		this.image = image;
		this.answer = answer;
		this.choice = choice;
		this.etchoice = etchoice;

		this.game = function () {
			//hide next and retry button
			$('.notification, .quiz-nav, .new').hide();
			$('#nba-player').attr("src", image);
			$(choice).addClass('answer').append(answer);

			var i = 0;

			for (var x = 0; x < choices.length; x++) {
				falseAnswers = choices[x];

				if (falseAnswers != choice) {
					$(falseAnswers).append(etchoice[i]);
				}
				i++;
			}

			$('.choice').click(function () {
				if (NoClicks) {
					if ($(this).hasClass('answer')) {
						//prompt me if the answer is correct

						console.log('Answer is correct');
						notification.show().addClass('blue').html("Awesome! You got it!");
						/*$('.answer').addClass('success');   */
						pointcounter++;

					} else {

						console.log('Answer is wrong');
					 notification.show().addClass('red').html("Sorry! Wrong Answer!");
						/* $(this).addClass('error');
           $('.answer').addClass('success');*/
					}
					$('.quiz-nav').fadeIn();

				}
				NoClicks = false;
				$(this).removeClass('answer');
			});

		};

	}
	//init array of questions
	var questions = [];

	questions[0] = new Question("img/lebron.png", "LeBron James", ".choice2", ["Dwayne Wade", "Kobe Bryant", "Chris Rock", "Derrick Rose"]);
	questions[1] = new Question("img/wade.png", "Dwayne Wade", ".choice1", ["Tim Duncan", "Kobe Bryant", "Dwayne Wade", "Derrick Rose"]);
	questions[2] = new Question("img/kobe.png", "Kobe Bryant", ".choice3", ["Dwayne Wade", "Tim Duncan", "LeBron James", "Derrick Rose"]);
	questions[3] = new Question("img/rose.png", "Derrick Rose", ".choice4", ["Dwayne Wade", "Kobe Bryant", "LeBron James", "Tim Duncan"]);
  questions[4] = new Question("img/duncan.png", "Tim Duncan", ".choice2", ["Chris Rock", "Kobe Bryant", "LeBron James", "Derrick Rose"]);

	questions[0].game();

	$('.next').click(function () {
		NoClicks = true;
		$('.notification').hide();
		$('.choice').empty().removeClass('answer');
		questions[Num].game();
		Num++;

		if (Num === questions.length) {
			//Clear out the question area
			$(".game").empty();
			console.log("end of game");
			$('.game').prepend("You got " + pointcounter + "  out of " + (Num) + "!");
			$('.new').show().click(function () {
				console.log("retry button clicked");
				/* Reset game here*/
				location.reload();
			});

		}
	});

});<commit_msg>Updated JS file<commit_after>$(document).ready(function () {
	//Init Variables
	var choices = [".choice1", ".choice2", ".choice3", ".choice4"];
	var randomQ = Math.floor(Math.random() * choices.length);
	//log random answer
	console.log(randomQ);
	var Num = 0;
	var pointcounter = 0;
	var NoClicks = true;
	var notification = $('.notification');

	//Question

	function Question(image, answer, choice, etchoice) {
		this.image = image;
		this.answer = answer;
		this.choice = choice;
		this.etchoice = etchoice;

		this.game = function () {
			//hide next and retry button
			$('.notification, .quiz-nav, .new').hide();
			$('#nba-player').attr("src", image);
			$(choice).addClass('answer').append(answer);

			var i = 0;

			for (var x = 0; x < choices.length; x++) {
				falseAnswers = choices[x];

				if (falseAnswers != choice) {
					$(falseAnswers).append(etchoice[i]);
				}
				i++;
			}

			$('.choice').click(function () {
				if (NoClicks) {
					if ($(this).hasClass('answer')) {
						//prompt me if the answer is correct

						console.log('Answer is correct');
						notification.show().addClass('blue').html("Awesome! You got it!");
						/*$('.answer').addClass('success');   */
						pointcounter++;

					} else {

						console.log('Answer is wrong');
					 notification.show().addClass('red').html("Sorry! Wrong Answer!");
						/* $(this).addClass('error');
           $('.answer').addClass('success');*/
					}
					$('.quiz-nav').fadeIn();

				}
				NoClicks = false;
				$(this).removeClass('answer');
			});

		};

	}
	//init array of questions
	var questions = [];

	questions[0] = new Question("img/lebron.png", "LeBron James", ".choice2", ["Dwayne Wade", "Kobe Bryant", "Chris Rock", "Derrick Rose"]);
	questions[1] = new Question("img/wade.png", "Dwayne Wade", ".choice1", ["Tim Duncan", "Kobe Bryant", "Chris Rock", "Derrick Rose"]);
	questions[2] = new Question("img/kobe.png", "Kobe Bryant", ".choice3", ["Dwayne Wade", "Tim Duncan", "LeBron James", "Derrick Rose"]);
	questions[3] = new Question("img/rose.png", "Derrick Rose", ".choice4", ["Dwayne Wade", "Kobe Bryant", "LeBron James", "Tim Duncan"]);
  questions[4] = new Question("img/duncan.png", "Tim Duncan", ".choice2", ["Chris Rock", "Kobe Bryant", "LeBron James", "Derrick Rose"]);

	questions[0].game();

	$('.next').click(function () {
		NoClicks = true;
		$('.notification').hide();
		$('.choice').empty().removeClass('answer');
		questions[Num].game();
		Num++;

		if (Num === questions.length) {
			//Clear out the question area
			$(".game").empty();
			console.log("end of game");
			$('.game').prepend("You got " + pointcounter + "  out of " + (Num) + "!");
			$('.new').show().click(function () {
				console.log("retry button clicked");
				/* Reset game here*/
				location.reload();
			});

		}
	});

});<|endoftext|>


<commit_before>
<commit_msg>added alert<commit_after>alert("Hello World");
<|endoftext|>


<commit_before>//Animate banner-text
$("#banner-text").addClass("load");

//mobile nav
$("#menuIcon").click(function(){
	$(".small-nav").toggleClass("dropOpen");
})

//scrollspy
$('a[href*=\\#]').on('click', function(event){
    event.preventDefault();
    $('html,body').animate({scrollTop:$(thishash).offset().top-70}, 500);
});

//resize nav on scroll
function collapseNavbar() {
    if ($(".main-nav").offset().top > 100) {
        $(".main-nav").addClass('scroll-nav');
				highlight.style.height = `52px`;
				highlight.style.borderRadius = `0%`;
				bottomBounds = 52;
    } else {
        $(".main-nav").removeClass('scroll-nav');
				highlight.style.height = `70px`;
				highlight.style.borderRadius = `0 0 30% 30%`;
				bottomBounds = 72;
    }
}

$(window).scroll(collapseNavbar);

//nav highlight
const menuItems = document.querySelectorAll('.menuItems');
const highlight = document.createElement('span');
var leftBounds = menuItems.item(menuItems.length-1).getBoundingClientRect().left-10;
var bottomBounds = 100;
highlight.classList.add('hl');
highlight.classList.add('hidden');
highlight.style.transform = `translateX(${leftBounds}px)`;
document.body.append(highlight);

function highlightNav(){
	highlight.classList.remove('hidden');
	highlight.style.opacity = `100`;
	const coords = this.getBoundingClientRect();
	const normalizedCoords = {
		width: coords.width,
		height: coords.height + 2,
		top: 0,
		left: coords.left + window.scrollX - 10
	};

	highlight.style.width = `${normalizedCoords.width}px`;
	highlight.style.height = `${normalizedCoords.height}px`;
	highlight.style.transform = `translate(${normalizedCoords.left}px, ${normalizedCoords.top}px)`;
}

function hideHighlight(e){
	e = e || window.event;
	if(e.clientY > bottomBounds || e.clientX < leftBounds)
		highlight.style.opacity = `0`;
	else
		highlight.style.opacity = `100`;
}

menuItems.forEach(a => a.addEventListener('mouseenter', highlightNav));
document.addEventListener('mousemove', hideHighlight);

//banner particles
particles = {
  "particles": {
    "number": {
      "value": 80,
      "density": {
        "enable": true,
        "value_area": 800
      }
    },
    "color": {
      "value": "#ffffff"
    },
    "shape": {
      "type": "circle",
      "stroke": {
        "width": 0,
        "color": "#000000"
      },
      "polygon": {
        "nb_sides": 5
      },
      "image": {
        "src": "img/github.svg",
        "width": 100,
        "height": 100
      }
    },
    "opacity": {
      "value": 0.5,
      "random": false,
      "anim": {
        "enable": false,
        "speed": 1,
        "opacity_min": 0.1,
        "sync": false
      }
    },
    "size": {
      "value": 3,
      "random": true,
      "anim": {
        "enable": false,
        "speed": 40,
        "size_min": 0.1,
        "sync": false
      }
    },
    "line_linked": {
      "enable": true,
      "distance": 128.27296486924183,
      "color": "#ffffff",
      "opacity": 0.4,
      "width": 1
    },
    "move": {
      "enable": true,
      "speed": 1,
      "direction": "none",
      "random": true,
      "straight": false,
      "out_mode": "out",
      "bounce": false,
      "attract": {
        "enable": false,
        "rotateX": 600,
        "rotateY": 1200
      }
    }
  },
  "interactivity": {
    "detect_on": "canvas",
    "events": {
      "onhover": {
        "enable": false,
        "mode": "grab"
      },
      "onclick": {
        "enable": false,
        "mode": "push"
      },
      "resize": true
    },
    "modes": {
      "grab": {
        "distance": 400,
        "line_linked": {
          "opacity": 1
        }
      },
      "bubble": {
        "distance": 400,
        "size": 40,
        "duration": 2,
        "opacity": 8,
        "speed": 3
      },
      "repulse": {
        "distance": 200,
        "duration": 0.4
      },
      "push": {
        "particles_nb": 4
      },
      "remove": {
        "particles_nb": 2
      }
    }
  },
  "retina_detect": true
}

particlesJS('particle-js', particles, function() {
  console.log('callback - particles.js config loaded');
});

var options = [
	{
		selector: '#banner',
		vh: 100
	}
]

//mobile vh fix
var vhFix = new VHChromeFix(options)
<commit_msg>fix scroll bug<commit_after>//Animate banner-text
$("#banner-text").addClass("load");

//mobile nav
$("#menuIcon").click(function(){
	$(".small-nav").toggleClass("dropOpen");
})

//scrollspy
$('a[href*=\\#]').on('click', function(event){
    event.preventDefault();
    $('html,body').animate({scrollTop:$(this.hash).offset().top-70}, 500);
});

//resize nav on scroll
function collapseNavbar() {
    if ($(".main-nav").offset().top > 100) {
        $(".main-nav").addClass('scroll-nav');
				highlight.style.height = `52px`;
				highlight.style.borderRadius = `0%`;
				bottomBounds = 52;
    } else {
        $(".main-nav").removeClass('scroll-nav');
				highlight.style.height = `70px`;
				highlight.style.borderRadius = `0 0 30% 30%`;
				bottomBounds = 72;
    }
}

$(window).scroll(collapseNavbar);

//nav highlight
const menuItems = document.querySelectorAll('.menuItems');
const highlight = document.createElement('span');
var leftBounds = menuItems.item(menuItems.length-1).getBoundingClientRect().left-10;
var bottomBounds = 100;
highlight.classList.add('hl');
highlight.classList.add('hidden');
highlight.style.transform = `translateX(${leftBounds}px)`;
document.body.append(highlight);

function highlightNav(){
	highlight.classList.remove('hidden');
	highlight.style.opacity = `100`;
	const coords = this.getBoundingClientRect();
	const normalizedCoords = {
		width: coords.width,
		height: coords.height + 2,
		top: 0,
		left: coords.left + window.scrollX - 10
	};

	highlight.style.width = `${normalizedCoords.width}px`;
	highlight.style.height = `${normalizedCoords.height}px`;
	highlight.style.transform = `translate(${normalizedCoords.left}px, ${normalizedCoords.top}px)`;
}

function hideHighlight(e){
	e = e || window.event;
	if(e.clientY > bottomBounds || e.clientX < leftBounds)
		highlight.style.opacity = `0`;
	else
		highlight.style.opacity = `100`;
}

menuItems.forEach(a => a.addEventListener('mouseenter', highlightNav));
document.addEventListener('mousemove', hideHighlight);

//banner particles
particles = {
  "particles": {
    "number": {
      "value": 80,
      "density": {
        "enable": true,
        "value_area": 800
      }
    },
    "color": {
      "value": "#ffffff"
    },
    "shape": {
      "type": "circle",
      "stroke": {
        "width": 0,
        "color": "#000000"
      },
      "polygon": {
        "nb_sides": 5
      },
      "image": {
        "src": "img/github.svg",
        "width": 100,
        "height": 100
      }
    },
    "opacity": {
      "value": 0.5,
      "random": false,
      "anim": {
        "enable": false,
        "speed": 1,
        "opacity_min": 0.1,
        "sync": false
      }
    },
    "size": {
      "value": 3,
      "random": true,
      "anim": {
        "enable": false,
        "speed": 40,
        "size_min": 0.1,
        "sync": false
      }
    },
    "line_linked": {
      "enable": true,
      "distance": 128.27296486924183,
      "color": "#ffffff",
      "opacity": 0.4,
      "width": 1
    },
    "move": {
      "enable": true,
      "speed": 1,
      "direction": "none",
      "random": true,
      "straight": false,
      "out_mode": "out",
      "bounce": false,
      "attract": {
        "enable": false,
        "rotateX": 600,
        "rotateY": 1200
      }
    }
  },
  "interactivity": {
    "detect_on": "canvas",
    "events": {
      "onhover": {
        "enable": false,
        "mode": "grab"
      },
      "onclick": {
        "enable": false,
        "mode": "push"
      },
      "resize": true
    },
    "modes": {
      "grab": {
        "distance": 400,
        "line_linked": {
          "opacity": 1
        }
      },
      "bubble": {
        "distance": 400,
        "size": 40,
        "duration": 2,
        "opacity": 8,
        "speed": 3
      },
      "repulse": {
        "distance": 200,
        "duration": 0.4
      },
      "push": {
        "particles_nb": 4
      },
      "remove": {
        "particles_nb": 2
      }
    }
  },
  "retina_detect": true
}

particlesJS('particle-js', particles, function() {
  console.log('callback - particles.js config loaded');
});

var options = [
	{
		selector: '#banner',
		vh: 100
	}
]

//mobile vh fix
var vhFix = new VHChromeFix(options)
<|endoftext|>


<commit_before>'use strict';

function repo_escape(){
    if(selected_button !== -1){
        display_number_select(selected_button);
    }
}

function repo_init(){
    core_repo_init({
      'events': {
        'check': {
          'onclick': check,
        },
        'generate': {
          'onclick': generate_puzzle,
        },
        'hint': {
          'onclick': hint,
        },
      },
      'globals': {
        'puzzle': [],
        'selected_button': -1,
      },
      'info': '<input id=generate type=button value="Generate New Puzzle">
'
        + '<input id=hint type=button value="Add 1 Hint"><input id=check type=button value="Check Solution">',
      'menu': true,
      'storage': {
        'locked': 15,
      },
      'storage-menu': '

<input id=locked min=0 step=any type=number>*2 > Locked
',
      'title': 'Sudoku.htm',
    });

    let loop_counter = 80;
    let output = '';
    do{
        output +=
          '<input class=gridbuttonclickable id='
          + loop_counter
          + ' onclick=display_number_select('
          + loop_counter
          + ') type=button>';
        if(loop_counter % 9 === 0
          && loop_counter !== 0){
            output += '
';
        }
    }while(loop_counter--);
    let element = document.getElementById('game-div');
    element.innerHTML = output;
    element.style.marginTop = '50px';
    element.style.minWidth = '600px';

    loop_counter = 8;
    do{
        document.getElementById(3 + 9 * loop_counter).style.marginRight = '5px';
        document.getElementById(27 + loop_counter).style.marginBottom = '5px';
        document.getElementById(54 + loop_counter).style.marginBottom = '5px';
        document.getElementById(6 + 9 * loop_counter).style.marginRight = '5px';
    }while(loop_counter--);

    element = document.getElementById('number-select');
    element.style.position = 'fixed';
    element.style.zIndex = 1;

    generate_puzzle();

    loop_counter = 9;
    do{
        document.getElementById('select-' + loop_counter).onclick = function(){
            const id = this.id;
            select_number(id.substring(id.indexOf('-') + 1));
        };
    }while(loop_counter--);

    globalThis.onresize
      = globalThis.onscroll = function(e){
        if(selected_button !== -1){
            update_number_select(selected_button);
        }
    };
}
<commit_msg>added mini class to storage inputs<commit_after>'use strict';

function repo_escape(){
    if(selected_button !== -1){
        display_number_select(selected_button);
    }
}

function repo_init(){
    core_repo_init({
      'events': {
        'check': {
          'onclick': check,
        },
        'generate': {
          'onclick': generate_puzzle,
        },
        'hint': {
          'onclick': hint,
        },
      },
      'globals': {
        'puzzle': [],
        'selected_button': -1,
      },
      'info': '<input id=generate type=button value="Generate New Puzzle">
'
        + '<input id=hint type=button value="Add 1 Hint"><input id=check type=button value="Check Solution">',
      'menu': true,
      'storage': {
        'locked': 15,
      },
      'storage-menu': '

<input class=mini id=locked min=0 step=any type=number>*2 > Locked
',
      'title': 'Sudoku.htm',
    });

    let loop_counter = 80;
    let output = '';
    do{
        output +=
          '<input class=gridbuttonclickable id='
          + loop_counter
          + ' onclick=display_number_select('
          + loop_counter
          + ') type=button>';
        if(loop_counter % 9 === 0
          && loop_counter !== 0){
            output += '
';
        }
    }while(loop_counter--);
    let element = document.getElementById('game-div');
    element.innerHTML = output;
    element.style.marginTop = '50px';
    element.style.minWidth = '600px';

    loop_counter = 8;
    do{
        document.getElementById(3 + 9 * loop_counter).style.marginRight = '5px';
        document.getElementById(27 + loop_counter).style.marginBottom = '5px';
        document.getElementById(54 + loop_counter).style.marginBottom = '5px';
        document.getElementById(6 + 9 * loop_counter).style.marginRight = '5px';
    }while(loop_counter--);

    element = document.getElementById('number-select');
    element.style.position = 'fixed';
    element.style.zIndex = 1;

    generate_puzzle();

    loop_counter = 9;
    do{
        document.getElementById('select-' + loop_counter).onclick = function(){
            const id = this.id;
            select_number(id.substring(id.indexOf('-') + 1));
        };
    }while(loop_counter--);

    globalThis.onresize
      = globalThis.onscroll = function(e){
        if(selected_button !== -1){
            update_number_select(selected_button);
        }
    };
}
<|endoftext|>


<commit_before>'use strict';
/*global L, instgrm, twttr, cartodb, jQuery */
// NOTE
// cartodb.js is bundled with its own internal Leaflet (@v0.7.3)
// do not add another Leaflet or it will break!
// It is also bundled with its own jQuery! (@v1.7.2)
(function () {
  var VIZ_2014 = 'https://lou.cartodb.com/api/v2/viz/d00a8afc-752e-11e4-8ec0-0e018d66dc29/viz.json'
  var VIZ_2015 = 'https://lou.cartodb.com/api/v2/viz/c9440e96-8fb3-11e5-861b-0ea31932ec1d/viz.json'

  function resizeMapWindow () {
    var aboutBoxHeight = document.getElementById('about').offsetHeight
    document.getElementById('map').style.top = Math.floor(aboutBoxHeight).toString() + 'px'
  }

  function checkForInfowindowData () {
    var data = document.querySelector('#data-container').dataset

    if (data.source === 'twitter') {
      renderTwitter(data, afterInfowindowRender)
    } else if (data.source === 'instagram') {
      renderInstagram(data, afterInfowindowRender)
    } else {
      setTimeout(checkForInfowindowData, 200)
    }
  }

  function renderInstagram (data, callback) {
    var url = data.url

    // Replace http:// links with https
    url = url.replace(/^http:/, 'https:')

    if (typeof instgrm === 'undefined') {
      renderInfowindowError('Unable to connect to Instagram.')
      return
    }

    $.ajax({
      url: 'https://api.instagram.com/oembed?url=' + url + '&beta=true&omitscript=true',
      dataType: 'jsonp',
      cache: false,
      success: function (response) {
        var embedEl = document.getElementById('embedded-content')

        if (response.html) {
          embedEl.innerHTML = response.html
          instgrm.Embeds.process()
        } else {
          embedEl.innerHTML = '
Could not embed the instagram
'
        }

        if (typeof callback === 'function') callback()
      },
      error: function () {
        console.log('Could not process the instagram url')
        renderInfowindowError('Unable to connect to Instagram.')
      }
    })
  }

  function renderTwitter (data, callback) {
    var username = data.username
    var identifier = data.identifier

    var embedEl = document.getElementById('embedded-content')

    if (typeof twttr === 'undefined') {
      renderInfowindowError('Unable to connect to Twitter.')
      return
    }

    // Set the bare minimum HTML required for Twitter to render a widget
    embedEl.innerHTML = '

'
    embedEl.style.display = 'block'

    // Tell twitter to do its job
    twttr.widgets.load(embedEl)
    twttr.events.bind('rendered', function (event) {
      if (typeof callback === 'function') callback()
    })
  }

  function renderInfowindowError (message) {
    var embedEl = document.getElementById('embedded-content')

    if (!message) message = 'There was an error loading this, please try again.'

    embedEl.innerHTML = '
' + message + '
'
    afterInfowindowRender()
  }

  function afterInfowindowRender () {
    document.querySelector('#infowindow-loader').style.display = 'none'
    panViewportIfNeeded()
  }

  function panViewportIfNeeded () {
    var buffer = 24
    var popupEl = document.querySelector('#embedded-content')
    var mapEl = document.querySelector('#map')

    var popupRect = popupEl.getBoundingClientRect()
    var mapRect = mapEl.getBoundingClientRect()

    var mustPanTop = (popupRect.top <= mapRect.top)
    var mustPanLeft = (popupRect.right >= mapRect.right)
    var topDiff = mapRect.top - popupRect.top
    var leftDiff = mapRect.right - popupRect.right

    if (mustPanTop && mustPanLeft) {
      map.panBy([leftDiff + buffer, -(topDiff + buffer)])
    } else if (mustPanTop) {
      map.panBy([0, -(topDiff + buffer)])
    } else if (mustPanLeft) {
      map.panBy([leftDiff + buffer, 0])
    }
  }

  function modifyAnchorTargets () {
    var anchors = document.querySelectorAll('a')
    for (var i = 0, j = anchors.length; i < j; i++) {
      anchors[i].target = '_top'
    }
  }

  if (window.self === window.top) {
    // Show the about box if we're not in an iframe
    document.getElementById('about').style.display = 'block'

    // Resize the map to fit
    resizeMapWindow()
    window.addEventListener('resize', resizeMapWindow)
  }

  // Map time
  // We are going to make our own Leaflet map so we can
  // set the tile layer and have control over stuff

  // Fit to USA
  var bounds = [
    [
      25.4035,
      -124.8046
    ],
    [
      49.4395,
      -66.3574
    ]
  ]

  var map = L.map('map', {
    scrollWheelZoom: (window.self === window.top),
    center: [(bounds[0][0] + bounds[1][0]) / 2, (bounds[0][1] + bounds[1][1]) / 2],
    zoom: 4
  })

  map.fitBounds(bounds)

  var hash
  map.on('moveend', function () {
    hash = new L.Hash(map)
  })

  var basemapUrl = 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png'
  if (window.devicePixelRatio >= 2) {
    basemapUrl = 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}@2x.png'
  }

  var layer = L.tileLayer(basemapUrl, {
    attribution: '© OpenStreetMap contributors, © CartoDB'
  }).addTo(map)

  var geocoder = L.control.geocoder('search-c0qrIOY', {
    pointIcon: false,
    polygonIcon: false,
    bounds: bounds,
    latlng: true,
    expanded: true,
    position: 'topright'
  }).addTo(map)

  // Hijack params
  geocoder.getBoundingBoxParam = function (param) {
    param['boundary.country'] = 'USA'
    return param
  }

  cartodb.createLayer(map, VIZ_2015)
    .addTo(map)
    .on('done', function (layer) {
      if (window.self !== window.top) {
        modifyAnchorTargets()
      }

      layer
        .on('featureClick', function (e, latlng, pos, data) {
          checkForInfowindowData()
        })
        .on('error', function (err) {
          console.log('[CartoDB] error: ' + err)
        })
    })
    .on('error', function (err) {
      console.log('[CartoDB] some error occurred: ' + err)
    })

}())
<commit_msg>force a 1px border from twitter to go away<commit_after>'use strict';
/*global L, instgrm, twttr, cartodb, jQuery */
// NOTE
// cartodb.js is bundled with its own internal Leaflet (@v0.7.3)
// do not add another Leaflet or it will break!
// It is also bundled with its own jQuery! (@v1.7.2)
(function () {
  var VIZ_2014 = 'https://lou.cartodb.com/api/v2/viz/d00a8afc-752e-11e4-8ec0-0e018d66dc29/viz.json'
  var VIZ_2015 = 'https://lou.cartodb.com/api/v2/viz/c9440e96-8fb3-11e5-861b-0ea31932ec1d/viz.json'

  function resizeMapWindow () {
    var aboutBoxHeight = document.getElementById('about').offsetHeight
    document.getElementById('map').style.top = Math.floor(aboutBoxHeight).toString() + 'px'
  }

  function checkForInfowindowData () {
    var data = document.querySelector('#data-container').dataset

    if (data.source === 'twitter') {
      renderTwitter(data, afterInfowindowRender)
    } else if (data.source === 'instagram') {
      renderInstagram(data, afterInfowindowRender)
    } else {
      setTimeout(checkForInfowindowData, 200)
    }
  }

  function renderInstagram (data, callback) {
    var url = data.url

    // Replace http:// links with https
    url = url.replace(/^http:/, 'https:')

    if (typeof instgrm === 'undefined') {
      renderInfowindowError('Unable to connect to Instagram.')
      return
    }

    $.ajax({
      url: 'https://api.instagram.com/oembed?url=' + url + '&beta=true&omitscript=true',
      dataType: 'jsonp',
      cache: false,
      success: function (response) {
        var embedEl = document.getElementById('embedded-content')

        if (response.html) {
          embedEl.innerHTML = response.html
          instgrm.Embeds.process()
        } else {
          embedEl.innerHTML = '
Could not embed the instagram
'
        }

        if (typeof callback === 'function') callback()
      },
      error: function () {
        console.log('Could not process the instagram url')
        renderInfowindowError('Unable to connect to Instagram.')
      }
    })
  }

  function renderTwitter (data, callback) {
    var username = data.username
    var identifier = data.identifier

    var embedEl = document.getElementById('embedded-content')

    if (typeof twttr === 'undefined') {
      renderInfowindowError('Unable to connect to Twitter.')
      return
    }

    // Set the bare minimum HTML required for Twitter to render a widget
    embedEl.innerHTML = '

'
    embedEl.style.display = 'block'

    // Tell twitter to do its job
    twttr.widgets.load(embedEl)
    twttr.events.bind('rendered', function (event) {
      // Get rid of a pesky 1px border around the tweet content box
      // that does not appear to go away even though I set border style
      // on the blockquote that got replaced
      var iframeEl = document.querySelector('iframe')
      var iframeContents = iframeEl.contentDocument || iframeEl.contentWindow.document
      var renderedEmbedEl = iframeContents.querySelector('.EmbeddedTweet-tweet')
      if (renderedEmbedEl) {
        renderedEmbedEl.style.border = 0;
      }

      if (typeof callback === 'function') callback()
    })
  }

  function renderInfowindowError (message) {
    var embedEl = document.getElementById('embedded-content')

    if (!message) message = 'There was an error loading this, please try again.'

    embedEl.innerHTML = '
' + message + '
'
    afterInfowindowRender()
  }

  function afterInfowindowRender () {
    document.querySelector('#infowindow-loader').style.display = 'none'
    panViewportIfNeeded()
  }

  function panViewportIfNeeded () {
    var buffer = 24
    var popupEl = document.querySelector('#embedded-content')
    var mapEl = document.querySelector('#map')

    var popupRect = popupEl.getBoundingClientRect()
    var mapRect = mapEl.getBoundingClientRect()

    var mustPanTop = (popupRect.top <= mapRect.top)
    var mustPanLeft = (popupRect.right >= mapRect.right)
    var topDiff = mapRect.top - popupRect.top
    var leftDiff = mapRect.right - popupRect.right

    if (mustPanTop && mustPanLeft) {
      map.panBy([leftDiff + buffer, -(topDiff + buffer)])
    } else if (mustPanTop) {
      map.panBy([0, -(topDiff + buffer)])
    } else if (mustPanLeft) {
      map.panBy([leftDiff + buffer, 0])
    }
  }

  function modifyAnchorTargets () {
    var anchors = document.querySelectorAll('a')
    for (var i = 0, j = anchors.length; i < j; i++) {
      anchors[i].target = '_top'
    }
  }

  if (window.self === window.top) {
    // Show the about box if we're not in an iframe
    document.getElementById('about').style.display = 'block'

    // Resize the map to fit
    resizeMapWindow()
    window.addEventListener('resize', resizeMapWindow)
  }

  // Map time
  // We are going to make our own Leaflet map so we can
  // set the tile layer and have control over stuff

  // Fit to USA
  var bounds = [
    [
      25.4035,
      -124.8046
    ],
    [
      49.4395,
      -66.3574
    ]
  ]

  var map = L.map('map', {
    scrollWheelZoom: (window.self === window.top),
    center: [(bounds[0][0] + bounds[1][0]) / 2, (bounds[0][1] + bounds[1][1]) / 2],
    zoom: 4
  })

  map.fitBounds(bounds)

  var hash
  map.on('moveend', function () {
    hash = new L.Hash(map)
  })

  var basemapUrl = 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png'
  if (window.devicePixelRatio >= 2) {
    basemapUrl = 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}@2x.png'
  }

  var layer = L.tileLayer(basemapUrl, {
    attribution: '© OpenStreetMap contributors, © CartoDB'
  }).addTo(map)

  var geocoder = L.control.geocoder('search-c0qrIOY', {
    pointIcon: false,
    polygonIcon: false,
    bounds: bounds,
    latlng: true,
    expanded: true,
    position: 'topright'
  }).addTo(map)

  // Hijack params
  geocoder.getBoundingBoxParam = function (param) {
    param['boundary.country'] = 'USA'
    return param
  }

  cartodb.createLayer(map, VIZ_2015)
    .addTo(map)
    .on('done', function (layer) {
      if (window.self !== window.top) {
        modifyAnchorTargets()
      }

      layer
        .on('featureClick', function (e, latlng, pos, data) {
          checkForInfowindowData()
        })
        .on('error', function (err) {
          console.log('[CartoDB] error: ' + err)
        })
    })
    .on('error', function (err) {
      console.log('[CartoDB] some error occurred: ' + err)
    })

}())
<|endoftext|>


<commit_before>var hashids = new Hashids("justgiving the data", 2, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");

function randomNumber(min,max) {
    return (Math.round((max-min) * Math.random() + min));
}

function createRandomArray(numElements,min,max) {

    var nums = new Array;

    for (var element=0; element<numElements; element++) {
        nums[element] = randomNumber(min,max);
    }

    return (nums);
}

function getJGID() {
	if(typeof(Storage) === "undefined") {
	    return null;
	}

	if(localStorage.getItem("JGID") !== null){
		return localStorage.getItem("JGID");
	}

	var numArray = createRandomArray(8,1,9);
	var id = hashids.encode(numArray);

    localStorage.setItem("JGID", id);
	return id;
}

var JGID = getJGID();

$("#Identify").click(function() {
	analytics.identify(JGID, {
	  email: $("#exampleInputEmail1").val()
	});
	console.log(JGID);
});

$("#exampleInputEmail2").blur(function() {
	analytics.track('Blur email field', {
	  typed: $(this).val()
	});
});

$("#checkbox").click(function() {
	analytics.track('Magic checkbox', {
	  typed: $(this).prop("checked")
	});
});

analytics.page({
	"server": "1.1.1.1"
});

var form = document.getElementById('testform');

analytics.trackForm(form, 'test_form', {
  textbox: $("#exampleInputEmail3").val(),
  checkbox: $("#checkbox2").prop("checked")
});

analytics.user().anonymousId(JGID);

analytics.debug();<commit_msg>aet anonymous when ready<commit_after>var hashids = new Hashids("justgiving the data", 2, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");

function randomNumber(min,max) {
    return (Math.round((max-min) * Math.random() + min));
}

function createRandomArray(numElements,min,max) {

    var nums = new Array;

    for (var element=0; element<numElements; element++) {
        nums[element] = randomNumber(min,max);
    }

    return (nums);
}

function getJGID() {
	if(typeof(Storage) === "undefined") {
	    return null;
	}

	if(localStorage.getItem("JGID") !== null){
		return localStorage.getItem("JGID");
	}

	var numArray = createRandomArray(8,1,9);
	var id = hashids.encode(numArray);

    localStorage.setItem("JGID", id);
	return id;
}

var JGID = getJGID();

$("#Identify").click(function() {
	analytics.identify(JGID, {
	  email: $("#exampleInputEmail1").val()
	});
	console.log(JGID);
});

$("#exampleInputEmail2").blur(function() {
	analytics.track('Blur email field', {
	  typed: $(this).val()
	});
});

$("#checkbox").click(function() {
	analytics.track('Magic checkbox', {
	  typed: $(this).prop("checked")
	});
});

analytics.page({
	"server": "1.1.1.1"
});

var form = document.getElementById('testform');

analytics.trackForm(form, 'test_form', {
  textbox: $("#exampleInputEmail3").val(),
  checkbox: $("#checkbox2").prop("checked")
});

analytics.ready(function(){
	analytics.user().anonymousId(JGID);
});

analytics.debug();<|endoftext|>


<commit_before>var tabs = {};

$('#saveButton').click(function(){
    saveCurrentTabs();
});

$('#clearTabs').click(function(){
    closeAllTabs();
});

$('#myModal').on('hidden.bs.modal', function () {
    $(this).removeData('bs.modal');
});

$(document.body).on('click', '#displayModal', function(){
    $('#myModal').modal('show');
    $('.modal-body').empty();
    var key = $(this).context.name;
    var size = Object.keys(tabs[key].data).length;
    $('.modal-body').append(
        '
'+
        '
'+
        '
'+
        '
'
        );

    for (var i=0; i < size; i++){
        $('#tabcontent').append(
            '
'+
            '<img src="'+tabs[key].data[i].favIconUrl+'"	'+
            ''+tabs[key].data[i].title+'	'+
            '
'
            );
    }
});

len = function(obj){
    var size = 0;
    for(var i in obj){
        ++size;
    }
    return size;
};

saveCurrentTabs = function(){
    var temp_tabs = {};
    var key = moment().format("MMMM Do YYYY, h:mm:ss a");

    chrome.tabs.query({}, function(tab_array){
        for(var i = 0; i < tab_array.length; i++){
            temp_tabs[i] =
                {
                    "title":tab_array[i].title,
                    "url":tab_array[i].url,
                    "favIconUrl":tab_array[i].favIconUrl
                };
        }
        tabs[key] = {"data": temp_tabs};
        chrome.storage.local.set({'tabs':tabs}, function(){console.log(key + ' saved');});
        displaySavedTabs();
    });
};

closeAllTabs = function(){
    chrome.tabs.query({}, function(tabs){
        for(var i in tabs){
            if (tabs[i].url != "chrome://newtab/"){
                chrome.tabs.remove(tabs[i].id);
            }
        }
    });
};

displaySavedTabs = function(){
    var keys = Object.keys(tabs);
    $('#tabview').empty();
    for (var i=keys.length-1; i >= 0; i--){
        $('#tabview').append(
                "
"+
                "" + keys[i] + "	"+
                "
"+
                "<button data-toggle='modal' data-target='myModal' name='"+keys[i]+"' id='displayModal' class='btn btn-default btn-xs name='preview'> Preview</button>"+
                "<button type='button' class='btn btn-default btn-xs' name='restore' value='"+keys[i]+"'> Restore</button>"+
                "<button type='button' class='btn btn-danger btn-xs' name='remove' value='"+keys[i]+"'> Delete</button>
	"+
                "
"
                );
    }

    $('.tabname').hover(function(){
        $(this).toggleClass('active');
    });

    $('button').click(function(){
        var key = $(this).context.value;
        if($(this).context.name == "remove"){
            removeFromHistory(key);
        } else if($(this).context.name == "restore"){
            restoreTabs(key);
        }
    });

//    $(document.body).on('click', '#displayModal', function(){
//        $('#myModal').modal('show');
//        $('.modal-body').empty();
//        var key = $(this).context.name;
//        var size = Object.keys(tabs[key].data).length;
//
//        for (var i=0; i < size; i++){
//            $('.modal-body').append('
'+tabs[key].data[i].title+'
');
//        }
//    });
};

loadTabHistory = function() {
    chrome.storage.local.get('tabs',function(stored_tabs){
        if(stored_tabs.tabs){
            tabs = stored_tabs.tabs;
        }
        displaySavedTabs();
    });
};

restoreTabs = function(key) {
    var size = Object.keys(tabs[key].data).length;
    for(var i=0; i < size; i++){
        chrome.tabs.create({"url":tabs[key].data[i].url});
    }
};

removeFromHistory = function(key) {
    delete tabs[key];
    chrome.storage.local.set({'tabs':tabs}, function(){console.log('saved tabs');});
    displaySavedTabs();
};

loadTabHistory();
<commit_msg>fire events to background.js to remove and create tabs<commit_after>var tabs = {};

$('#saveButton').click(function(){
    saveCurrentTabs();
});

$('#closeTabs').click(function(){
    chrome.runtime.sendMessage({"closeTabs":true});
});

$('#myModal').on('hidden.bs.modal', function () {
    $(this).removeData('bs.modal');
});

$(document.body).on('click', '#displayModal', function(){
    $('#myModal').modal('show');
    $('.modal-body').empty();
    var key = $(this).context.value;
    var size = Object.keys(tabs[key].data).length;
    $('.modal-body').append(
        '
'+
        '
'+
        '
'+
        '
'
        );

    for (var i=0; i < size; i++){
        $('#tabcontent').append(
            '
'+
            '<img src="'+tabs[key].data[i].favIconUrl+'"	'+
            ''+tabs[key].data[i].title+'	'+
            '
'
            );
    }
});

$(document.body).on('blue keyup paste', '#editable', function(){
    var key = $(this).attr('name');
    tabs[key].th_description = $(this).html();
    chrome.storage.local.set({'tabs':tabs}, function(){console.log(key + ' saved');});
});

$(document.body).on('click', '#closeWindow', function(){
    window.close();
});

len = function(obj){
    var size = 0;
    for(var i in obj){
        ++size;
    }
    return size;
};

saveCurrentTabs = function(){
    var temp_tabs = {};
    var key = moment().format("l hh:mm:ss A");

    chrome.tabs.query({}, function(tab_array){
        for(var i = 0; i < tab_array.length; i++){
            temp_tabs[i] =
                {
                    "title":tab_array[i].title,
                    "url":tab_array[i].url,
                    "favIconUrl":tab_array[i].favIconUrl,
                };
        }
        tabs[key] = {"data": temp_tabs, "th_description":"click to edit"};
        chrome.storage.local.set({'tabs':tabs}, function(){console.log(key + ' saved');});
        displaySavedTabs();
    });
};

closeAllTabs = function(){
    chrome.tabs.query({}, function(tabs){
        for(var i in tabs){
            if (tabs[i].url != "chrome://newtab/"){
                chrome.tabs.remove(tabs[i].id);
            }
        }
    });
};

displaySavedTabs = function(){
    var keys = Object.keys(tabs);
    $('#tabview').empty();
    for (var i=keys.length-1; i >= 0; i--){
        $('#tabview').append(
                "
"+
                ""+tabs[keys[i]].th_description+"	"+
                "" + keys[i] + "	"+
                "
"+
                "<button data-toggle='modal' data-target='myModal' value='"+keys[i]+"' id='displayModal' class='btn btn-default btn-xs' name='preview'> Preview</button>"+
                "<button type='button' class='btn btn-default btn-xs' name='restore' value='"+keys[i]+"'> Restore</button>"+
                "<button type='button' class='btn btn-danger btn-xs' name='remove' value='"+keys[i]+"'> Delete</button>
	"+
                "
"
                );
    }

    $('.tabname').hover(function(){
        $(this).toggleClass('active');
    });

    $('button').click(function(){
        var key = $(this).context.value;
        if($(this).context.name == "remove"){
            removeFromHistory(key);
        } else if($(this).context.name == "restore"){
            restoreTabs(key);
        }
    });

//    $(document.body).on('click', '#displayModal', function(){
//        $('#myModal').modal('show');
//        $('.modal-body').empty();
//        var key = $(this).context.name;
//        var size = Object.keys(tabs[key].data).length;
//
//        for (var i=0; i < size; i++){
//            $('.modal-body').append('
'+tabs[key].data[i].title+'
');
//        }
//    });
};

loadTabHistory = function() {
    chrome.storage.local.get('tabs',function(stored_tabs){
        if(stored_tabs.tabs){
            tabs = stored_tabs.tabs;
        }
        displaySavedTabs();
    });
};

restoreTabs = function(key) {
    chrome.runtime.sendMessage({"restoreTabs":true, "tabs":tabs, "key":key});
};

removeFromHistory = function(key) {
    delete tabs[key];
    chrome.storage.local.set({'tabs':tabs}, function(){console.log('saved tabs');});
    displaySavedTabs();
};

loadTabHistory();
<|endoftext|>