<commit_before>/**
 * jQuery Ajax w/ Progress
 */
$.customAjax = function (params) {

    var $ajax;
    var progressFuncs = [];
    var uploadProgressFuncs = [];

    params.xhr = function () {
        var xhr = $.ajaxSettings.xhr();

        xhr.addEventListener("progress", function (e) {
            for (var i in progressFuncs) {
                progressFuncs[i].apply($ajax, [e]);
            }
        });

        xhr.upload.addEventListener("progress", function (e) {
            for (var i in uploadProgressFuncs) {
                uploadProgressFuncs[i].apply($ajax, [e]);
            }
        });

        return xhr;
    };

    $ajax = $.ajax(params);

    // extend

    // std progress
    $ajax.progress = function (func) {
        progressFuncs.push(func);
        // allow chaining
        return $ajax;
    };

    // upload progress
    $ajax.uploadProgress = function (func) {
        uploadProgressFuncs.push(func);
        // allow chaining
        return $ajax;
    };

    return $ajax;
};

/**
 * Fade the HTML of an object.
 *
 * Storyboard:
 * - fade out element
 * - change html
 * - fade element in
 *
 * @param   {string}   html        HTML to transition to (can also be a DOM object)
 * @param   {number}   [speed]     Speed of animation
 * @param   {function} [complete]  Animation complete callback
 */
$.fn.fadeHTML = function (html, speed, complete) {
    $(this).fadeTo(speed, 0, function () {
        $(this).html("").append(html).fadeTo(speed, 1, complete);
    });
    return this;
};

function bootstrapModal(args) {

    args = args || {};

    var modal = $("
", {class: "modal fade", role: "dialog", "data-keyboard": false, "data-backdrop": "static"});
    var modalDialog = $("
", {class: "modal-dialog"});
    //
    var modalContent = $("
", {class: "modal-content"});
    var modalHeader = $("
", {class: "modal-header", html: args.header});
    var modalTitle = $("
", {class: "modal-title", html: args.title});
    var modalBody = $("
", {class: "modal-body", html: args.body});
    var modalFooter = $("
", {class: "modal-footer", html: args.footer});

    modalHeader.append(modalTitle);
    modalContent.append(modalHeader).append(modalBody).append(modalFooter);

    modal.append(modalDialog);
    modalDialog.append(modalContent);

    return modal;
}

/**
 * Nav bar
 */
(function () {
    var $header = $("#header");

    $("#header-nav").on("show.bs.collapse", function () {
        $header.addClass("nav-open");
    }).on("hide.bs.collapse", function () {
        $header.removeClass("nav-open");
    });
}());

/**
 * Hero cloud carousel
 */

(function () {

    $(".cloud-carousel-inner").each(function () {

        var $this = $(this);

        var $carouselItemsParent = $this.children(".cloud-carousel-dest");
        var $carouselItems = $carouselItemsParent.children();

        var $carouselBtnsParent = $this.children(".cloud-carousel-btns");
        var $carouselBtns = [];

        var currentPosition = 0;
        var positionMax = $carouselItems.length - 1;
        var timeout = "0";

        function goTo(newPosition) {

            // clear active state of old button (corresponding to carousel item)
            $carouselBtns.eq(currentPosition).removeClass("is-active");

            var $carouselItem = $carouselItems.eq(newPosition);

            // add active state to new button (corresponding to carousel item)
            $carouselBtns.eq(newPosition).addClass("is-active");

            $carouselItemsParent.animate({
                scrollLeft: $carouselItem.get(0).offsetLeft
            }, 1200, "easeInOutExpo");

            currentPosition = newPosition;

            timeout = setTimeout(function () {
                var _position = currentPosition + 1;

                if (_position > positionMax)
                    _position = 0;

                goTo(_position);
            }, 3000);
        }

        $carouselItems.each(function (i) {
            var $newBtn = $("");
            $carouselBtnsParent.append($newBtn);

            $newBtn.click(function () {
                clearTimeout(timeout);
                goTo(i);
            });
        });

        // update now that carousel btns are populated
        $carouselBtns = $carouselBtnsParent.children();

        // init
        goTo(0);

    });
}());

/**
 * Hero upload modal stuff
 */
(function () {
    var files;

    function validateEmail(email) {
        var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return re.test(email);
    }

    //
    // CHOOSE FILES (STEP ONE)
    //

    // reset progress bar here to
    // avoid unnecessary CSS visuals
    $("#upl-modal1").on("show.bs.modal", function () {
        $progressBar.css({width: "0%"})
    });

    $("#upl-modal1-browse").click(function () {
        var $fileInput = $("<input>", {type: "file", /*multiple: "multiple",*/ accept: ".pdf"});
        $fileInput.click();

        $fileInput.change(function () {

            var validationComplete = true;

            files = this.files;

            for (var i = 0; i < files.length; i++) {

                if (files[i].type != "application/pdf" || files[i].size > 25000000) {
                    validationComplete = false;
                    break;
                }
            }

            if (validationComplete) {
                $("#upl-modal1").modal("hide");
                $("#upl-modal2").modal("show");
            }
            else {
                alert("Your file doesn't match type PDF or exceeds 25 MB. Please select another file and try again.");
            }
        });
    });

    //
    // EMAIL VALIDATION (STEP TWO)
    //

    var $emailInput = $("#upl-modal2-input");
    var $emailInputParent = $emailInput.parent().addClass("hint").attr("data-hint", "Invalid email address");

    $("#upl-modal2").on("shown.bs.modal", function () {
        $emailInput.select();
    });

    $("#upl-modal2-next").click(function (e) {

        if (!validateEmail($emailInput.val())) {
            $emailInput.select();
            $emailInputParent.addClass("hint--visible");

            $emailInput.one("input", function () {
                $emailInputParent.removeClass("hint--visible");
            });

            e.stopPropagation();
        }
    });

    // allow enter key on email input
    $emailInput.keydown(function (e) {
        if (e.keyCode == 13) {
            $("#upl-modal2-next").click();
        }
    });

    //
    // SPECIAL INSTRUCTIONS VALIDATION (STEP THREE)
    //
    var $messageInput = $("#upl-modal3-input");
    var $messageInputParent = $messageInput.parent().addClass("hint").attr("data-hint", "Special instructions required");

    $("#upl-modal3").on("shown.bs.modal", function () {
        $messageInput.select();
    });

    $("#upl-modal3-next").click(function (e) {
        if ($.trim($messageInput.val()) == "") {

            $messageInputParent.addClass("hint--visible");

            $messageInput.one("input", function () {
                $messageInputParent.removeClass("hint--visible").select();
            });

            e.stopPropagation();
        }
    });

    //
    // FILE UPLOAD (STEP FOUR)
    //

    var $progressBar = $("#upl-modal4-progress-bar");
    var $progressStatus = $("#upl-modal4-title");

    $("#upl-modal4").on("shown.bs.modal", function () {

        if (files) {

            var formData = new FormData();

            formData.append("email", $emailInput.val());
            formData.append("message", $messageInput.val());

            // clear inputs
            $emailInput.add($messageInput).val("");

            for (var i = 0; i < files.length; i++) {
                formData.append("files[]", files[i]);
            }

            $progressStatus.html("Uploading...");
            $progressBar.addClass("is-visible");

            $.customAjax({
                url: "api/upload.php",
                type: "POST",
                dataType: "JSON",
                data: formData,
                processData: false,
                contentType: false,
                cache: false
            }).uploadProgress(function (e) {
                var currentProgress = e.loaded / e.total;
                $progressBar.css({width: Math.round(currentProgress * 100) + "%"});
            }).done(function (json) {

                if (!json.error) {

                    setTimeout(function () {
                        $progressStatus.fadeHTML("Success!");
                    }, 200);
                }
                else {
                    $progressStatus.fadeHTML(json.error);
                }

                files = null;
            }).fail(function (e) {
                $progressStatus.fadeHTML("Error uploading :(");
            }).always(function () {
                $progressBar.removeClass("is-visible");
            });
        }
        else {

        }
    });

    //
    // HELP DOCUMENTATION
    //
    $(".modal-header-hint").each(function () {
        var $this = $(this);

        $this.click(function () {
            // generate overlay
            var $modalContent = $("
", {class: "modal-content modal-content--help"});
            var $modalHeader = $("
", {class: "modal-header"});
            var $modalHeaderClose = $('<button>', {type: "button", class: "close", html: "&times"});

            $modalHeader.append($modalHeaderClose).append('
Help
');

            $modalHeaderClose.click(function () {
                $modalContent.remove();
                $(window).off("resize.uplhelp");
            });

            var $modalBody = $("
", {
                class: "modal-body",
                html: '

' + $this.attr("data-help") + '

'
            });

            var $modalFooter = $("
", {
                class: "modal-footer xs",
                html: '
support@magnificent.com
'
                + '
magnificent.com/support
'
            });

            // build
            $modalContent.append($modalHeader).append($modalBody).append($modalFooter);

            $this.parents(".modal-dialog").append($modalContent);

            $(window).on("resize.uplhelp", function () {
                $modalBody.css({height: $this.parent().parent().children('.modal-body')[0].offsetHeight + "px"})
            }).trigger("resize.uplhelp");
        });
    });

}());

/**
 * Contact page
 */
(function () {
    var $contactForm = $("#contact-form");

    $contactForm.submit(function (e) {

        $.ajax({
            method: $contactForm.attr("data-method"),
            url: $contactForm.attr("data-action"),
            dataType: "JSON",
            data: $contactForm.serialize()
        }).done(function (json) {
            if (!json.error) {
                $contactForm.addClass("has-success");
            }
            else {
                alert(json.error);
            }
        }).error(function () {

        });

        e.preventDefault();
    });
}());<commit_msg>Change copy on Modals<commit_after>/**
 * jQuery Ajax w/ Progress
 */
$.customAjax = function (params) {

    var $ajax;
    var progressFuncs = [];
    var uploadProgressFuncs = [];

    params.xhr = function () {
        var xhr = $.ajaxSettings.xhr();

        xhr.addEventListener("progress", function (e) {
            for (var i in progressFuncs) {
                progressFuncs[i].apply($ajax, [e]);
            }
        });

        xhr.upload.addEventListener("progress", function (e) {
            for (var i in uploadProgressFuncs) {
                uploadProgressFuncs[i].apply($ajax, [e]);
            }
        });

        return xhr;
    };

    $ajax = $.ajax(params);

    // extend

    // std progress
    $ajax.progress = function (func) {
        progressFuncs.push(func);
        // allow chaining
        return $ajax;
    };

    // upload progress
    $ajax.uploadProgress = function (func) {
        uploadProgressFuncs.push(func);
        // allow chaining
        return $ajax;
    };

    return $ajax;
};

/**
 * Fade the HTML of an object.
 *
 * Storyboard:
 * - fade out element
 * - change html
 * - fade element in
 *
 * @param   {string}   html        HTML to transition to (can also be a DOM object)
 * @param   {number}   [speed]     Speed of animation
 * @param   {function} [complete]  Animation complete callback
 */
$.fn.fadeHTML = function (html, speed, complete) {
    $(this).fadeTo(speed, 0, function () {
        $(this).html("").append(html).fadeTo(speed, 1, complete);
    });
    return this;
};

function bootstrapModal(args) {

    args = args || {};

    var modal = $("
", {class: "modal fade", role: "dialog", "data-keyboard": false, "data-backdrop": "static"});
    var modalDialog = $("
", {class: "modal-dialog"});
    //
    var modalContent = $("
", {class: "modal-content"});
    var modalHeader = $("
", {class: "modal-header", html: args.header});
    var modalTitle = $("
", {class: "modal-title", html: args.title});
    var modalBody = $("
", {class: "modal-body", html: args.body});
    var modalFooter = $("
", {class: "modal-footer", html: args.footer});

    modalHeader.append(modalTitle);
    modalContent.append(modalHeader).append(modalBody).append(modalFooter);

    modal.append(modalDialog);
    modalDialog.append(modalContent);

    return modal;
}

/**
 * Nav bar
 */
(function () {
    var $header = $("#header");

    $("#header-nav").on("show.bs.collapse", function () {
        $header.addClass("nav-open");
    }).on("hide.bs.collapse", function () {
        $header.removeClass("nav-open");
    });
}());

/**
 * Hero cloud carousel
 */

(function () {

    $(".cloud-carousel-inner").each(function () {

        var $this = $(this);

        var $carouselItemsParent = $this.children(".cloud-carousel-dest");
        var $carouselItems = $carouselItemsParent.children();

        var $carouselBtnsParent = $this.children(".cloud-carousel-btns");
        var $carouselBtns = [];

        var currentPosition = 0;
        var positionMax = $carouselItems.length - 1;
        var timeout = "0";

        function goTo(newPosition) {

            // clear active state of old button (corresponding to carousel item)
            $carouselBtns.eq(currentPosition).removeClass("is-active");

            var $carouselItem = $carouselItems.eq(newPosition);

            // add active state to new button (corresponding to carousel item)
            $carouselBtns.eq(newPosition).addClass("is-active");

            $carouselItemsParent.animate({
                scrollLeft: $carouselItem.get(0).offsetLeft
            }, 1200, "easeInOutExpo");

            currentPosition = newPosition;

            timeout = setTimeout(function () {
                var _position = currentPosition + 1;

                if (_position > positionMax)
                    _position = 0;

                goTo(_position);
            }, 3000);
        }

        $carouselItems.each(function (i) {
            var $newBtn = $("");
            $carouselBtnsParent.append($newBtn);

            $newBtn.click(function () {
                clearTimeout(timeout);
                goTo(i);
            });
        });

        // update now that carousel btns are populated
        $carouselBtns = $carouselBtnsParent.children();

        // init
        goTo(0);

    });
}());

/**
 * Hero upload modal stuff
 */
(function () {
    var files;

    function validateEmail(email) {
        var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return re.test(email);
    }

    //
    // CHOOSE FILES (STEP ONE)
    //

    // reset progress bar here to
    // avoid unnecessary CSS visuals
    $("#upl-modal1").on("show.bs.modal", function () {
        $progressBar.css({width: "0%"})
    });

    $("#upl-modal1-browse").click(function () {
        var $fileInput = $("<input>", {type: "file", /*multiple: "multiple",*/ accept: ".pdf"});
        $fileInput.click();

        $fileInput.change(function () {

            var validationComplete = true;

            files = this.files;

            for (var i = 0; i < files.length; i++) {

                if (files[i].type != "application/pdf" || files[i].size > 25000000) {
                    validationComplete = false;
                    break;
                }
            }

            if (validationComplete) {
                $("#upl-modal1").modal("hide");
                $("#upl-modal2").modal("show");
            }
            else {
                alert("Your file doesn't match type PDF or exceeds 25 MB. Please select another file and try again.");
            }
        });
    });

    //
    // EMAIL VALIDATION (STEP TWO)
    //

    var $emailInput = $("#upl-modal2-input");
    var $emailInputParent = $emailInput.parent().addClass("hint").attr("data-hint", "Invalid email address");

    $("#upl-modal2").on("shown.bs.modal", function () {
        $emailInput.select();
    });

    $("#upl-modal2-next").click(function (e) {

        if (!validateEmail($emailInput.val())) {
            $emailInput.select();
            $emailInputParent.addClass("hint--visible");

            $emailInput.one("input", function () {
                $emailInputParent.removeClass("hint--visible");
            });

            e.stopPropagation();
        }
    });

    // allow enter key on email input
    $emailInput.keydown(function (e) {
        if (e.keyCode == 13) {
            $("#upl-modal2-next").click();
        }
    });

    //
    // SPECIAL INSTRUCTIONS VALIDATION (STEP THREE)
    //
    var $messageInput = $("#upl-modal3-input");
    var $messageInputParent = $messageInput.parent().addClass("hint").attr("data-hint", "Special instructions required");

    $("#upl-modal3").on("shown.bs.modal", function () {
        $messageInput.select();
    });

    $("#upl-modal3-next").click(function (e) {
        if ($.trim($messageInput.val()) == "") {

            $messageInputParent.addClass("hint--visible");

            $messageInput.one("input", function () {
                $messageInputParent.removeClass("hint--visible").select();
            });

            e.stopPropagation();
        }
    });

    //
    // FILE UPLOAD (STEP FOUR)
    //

    var $progressBar = $("#upl-modal4-progress-bar");
    var $progressStatus = $("#upl-modal4-title");

    $("#upl-modal4").on("shown.bs.modal", function () {

        if (files) {

            var formData = new FormData();

            formData.append("email", $emailInput.val());
            formData.append("message", $messageInput.val());

            // clear inputs
            $emailInput.add($messageInput).val("");

            for (var i = 0; i < files.length; i++) {
                formData.append("files[]", files[i]);
            }

            $progressStatus.html("Uploading...");
            $progressBar.addClass("is-visible");

            $.customAjax({
                url: "api/upload.php",
                type: "POST",
                dataType: "JSON",
                data: formData,
                processData: false,
                contentType: false,
                cache: false
            }).uploadProgress(function (e) {
                var currentProgress = e.loaded / e.total;
                $progressBar.css({width: Math.round(currentProgress * 100) + "%"});
            }).done(function (json) {

                if (!json.error) {

                    setTimeout(function () {
                        $progressStatus.fadeHTML("Success!");
                    }, 200);
                }
                else {
                    $progressStatus.fadeHTML(json.error);
                }

                files = null;
            }).fail(function (e) {
                $progressStatus.fadeHTML("Error uploading :(");
            }).always(function () {
                $progressBar.removeClass("is-visible");
            });
        }
        else {

        }
    });

    //
    // HELP DOCUMENTATION
    //
    $(".modal-header-hint").each(function () {
        var $this = $(this);

        $this.click(function () {
            // generate overlay
            var $modalContent = $("
", {class: "modal-content modal-content--help"});
            var $modalHeader = $("
", {class: "modal-header"});
            var $modalHeaderClose = $('<button>', {type: "button", class: "close", html: "&times"});

            $modalHeader.append($modalHeaderClose).append('
Help
');

            $modalHeaderClose.click(function () {
                $modalContent.remove();
                $(window).off("resize.uplhelp");
            });

            var $modalBody = $("
", {
                class: "modal-body",
                html: '

' + $this.attr("data-help") + '

'
            });

            var $modalFooter = $("
", {
                class: "modal-footer xs",
                html: '
Email Support
'
                + '
Contact Support
'
            });

            // build
            $modalContent.append($modalHeader).append($modalBody).append($modalFooter);

            $this.parents(".modal-dialog").append($modalContent);

            $(window).on("resize.uplhelp", function () {
                $modalBody.css({height: $this.parent().parent().children('.modal-body')[0].offsetHeight + "px"})
            }).trigger("resize.uplhelp");
        });
    });

}());

/**
 * Contact page
 */
(function () {
    var $contactForm = $("#contact-form");

    $contactForm.submit(function (e) {

        $.ajax({
            method: $contactForm.attr("data-method"),
            url: $contactForm.attr("data-action"),
            dataType: "JSON",
            data: $contactForm.serialize()
        }).done(function (json) {
            if (!json.error) {
                $contactForm.addClass("has-success");
            }
            else {
                alert(json.error);
            }
        }).error(function () {

        });

        e.preventDefault();
    });
}());<|endoftext|>


<commit_before>$(document).ready(function() {

  var ANNOTATION_TYPE_VIDEO = 'video';
  var ANNOTATION_TYPE_TEXT = 'text';
  var ANNOTATION_TYPE_AUDIO = 'audio';

  // Create annotations manifest
  var annotations = [];
  var videoPlayer = {};

  var appWidth = $('body').css('width');
  var appHeight = $('body').css('height');

  function init() {

    setupFullscreenVideo();
    setupScreenSaver();

    var paintingImg = $('.painting img').first();

    $('.annotations button').each(function() {

      var mediaPath = $(this).attr('media-path');
      var a = { id: $(this).attr('id'),
                btn: this,
                x: parseInt($(this).attr('annotation-x'), 10),
                y: parseInt($(this).attr('annotation-y'), 10),
                type: getMediaType(mediaPath),
                path: mediaPath,
      };

      annotations.push(a);

      // Position & style button (offset for button size)
      $(this).css('left', a.x - 20);
      $(this).css('top', a.y - 20);
      $(this).addClass('btn');
      $(this).append('');

      var cutout = $(this).attr('cutout');
      if (cutout === undefined) {
        cutout = {x:-70, y: -70, w: 140, h: 140};
      } else {
        cutout = getProperJSON(cutout);
      }

      a.cutRect = cutout;
      a.cutout = getCutoutFromImage(a.id, paintingImg, a.x + a.cutRect.x, a.y + a.cutRect.y, a.cutRect.w, a.cutRect.h);

    });

    // Create hit regions by building Vernoi diagram
    console.log(appWidth,appHeight);
    var svgElement = '<svg id="veronoi_ui" width="'+appWidth+'" height="'+appHeight+'"></svg>';
    $('.annotations').prepend(svgElement);

    // Allow time for size recalc...
    setTimeout(function() {
      var vornoi = new VoronoiLayer(annotations, $('#veronoi_ui'), onAnnotationSelected, onAnnotationActive, false);
    }, 200);

    cutoutsGoHome();

  }

  var onAnnotationActive = function(annId, annBtn) {

    for (var i = 0; i < annotations.length; i++) {

      var a = annotations[i];

      if (annId === a.id) {

        $(a.btn).addClass('active');

        break;
      }

    }

  };

  var onAnnotationSelected = function(annId, annBtn) {

    console.log('annotationSelected(): ' + annId);

    for (var i = 0; i < annotations.length; i++) {

      var a = annotations[i];

      if (annId === a.id) {

        // Block mouse/touch interaction
        $('.overlay').css('pointer-events', 'auto');
        $(a.btn).removeClass('active');

        // Transition

        TweenMax.to($(a.btn), 0.15, {
          opacity:0,
        });

        setTimeout(function() {

          TweenMax.to($('.overlay'), 1, {
              opacity:1,
              ease:Power2.easeOut,
            });

          $(a.cutout).show();

          TweenMax.set($(a.cutout), {
            boxShadow:'0px 0px 8px 2px rgba(0, 0, 0, 0)',
            zIndex:1,
            backgroundColor:'rgba(0,0,0,0.0)',
            padding:0,
          });

          TweenMax.to($(a.cutout), 1.75, {
            delay: 0.5,
            left:20,
            top:20,
            padding:10,
            backgroundColor:'rgba(0,0,0,0.5)',
            boxShadow:'0px 3px 8px 2px rgba(0, 0, 0, 0.3)',
            ease:Power2.easeInOut,
            onComplete:showAnnotationContent,
            onCompleteParams:[a],
          });

        }, 150);

        break;

      }
    };

  };

  function showAnnotationContent(ann) {

    switch (ann.type) {
      case ANNOTATION_TYPE_VIDEO:
        showFullscreenVideo(ann.path);
        break;
      default:
        console.log('Whoops! Presentation for annotation type:', ann.type, ' has not been built out yet!');
        break;
    }
  }

  function getCutoutFromImage(id, imgElement, x, y, w, h) {

    id = id + '_cutout';
    var imgSrc = $(imgElement).attr('src');

    var cnvs = '<canvas id="' + id + '" style="position:absolute" width="' + w + '" height="' + h + '"></canvas>';

    $(imgElement).parent().append(cnvs);
    var cnvs = $('#' + id);
    var context = $(cnvs).get(0).getContext('2d');
    var imageObj = new Image();

    imageObj.onload = function() {

      context.drawImage(imageObj, x, y, w, h, 0, 0, w, h);
      TweenMax.set($(cnvs), {left:x, top:y});

    };

    imageObj.src = imgSrc;

    return cnvs;

  }

  function setupFullscreenVideo() {

    // Create video tag
    var options = { controls:false, autoplay: true, loop: false, preload: 'auto' };

    videoPlayer = $('video');

    videoPlayer.on('playing', function() {

      console.log('Video is playing');

      $('.content').show();

      TweenMax.set($('.content'), {
        opacity:0,
      });

      TweenMax.to($('.content'), 0.5, {
        opacity:1,
        ease:Power2.easeIn,
      });

    });

    videoPlayer.on('ended', function() {

      console.log('Video has ended!');

      hideFullscreenVideo();

    });

    // Home button
    $('.home-btn').on('click', function() {

      hideFullscreenVideo();

    });

  }

  function showFullscreenVideo(vidSrc) {

    videoPlayer.attr('src', vidSrc);
    videoPlayer.load();

  }

  function hideFullscreenVideo() {

    $('.content').fadeOut('fast', function() {
      videoPlayer.get(0).pause();
      $('.content').hide();

      cutoutsGoHome();

    });

  }

  function cutoutsGoHome() {
    for (var i = 0; i < annotations.length; i++) {

      TweenMax.to($(annotations[i].cutout), 1.5, {
        delay: 0.0,
        left:annotations[i].x + annotations[i].cutRect.x,
        top:annotations[i].y + annotations[i].cutRect.y,
        backgroundColor:'rgba(0,0,0,0.0)',
        boxShadow:'0px 0px 8px 2px rgba(0, 0, 0, 0)',
        padding:0,
        ease:Power2.easeInOut,
        onCompleteParams:[annotations[i]],
        onComplete:function(a) {
          TweenMax.set($(a.cutout),  {
            zIndex:0,
          });
          TweenMax.to($(a.btn), 0.5, {
            opacity:1,
          });
          $(a.cutout).hide();

          // Unblock mouse/touch interaction
          $('.overlay').css('pointer-events', 'none');
        },
      });

    };

    TweenMax.to($('.overlay'), 0.75, {
      opacity:0,
      delay:0.25,
    });

  }

  function setupScreenSaver() {

    var screensaver = new Screensaver(5 * 60, 'videos/Screensaver.mp4', function() {

      console.log('onSleepCallback');

    });

  }

  function getMediaType(mediaPath) {

    var ext = mediaPath.split('.').pop();
    var type = '';

    if (ext === 'mp4' || ext === 'mov') {
      type = ANNOTATION_TYPE_VIDEO;
    } else if (ext === 'mp3' || ext === 'ogg') {
      type = ANNOTATION_TYPE_AUDIO;
    } else if (ext === 'txt' || ext === 'json' || ext === 'xml' || ext === 'html') {
      type = ANNOTATION_TYPE_TEXT;
    } else {
      console.log('Unrecognized media type for file:', mediaPath);
    }

    return type;
  }

  function getProperJSON(improperJSON) {
    var properJSON = improperJSON.replace(/([a-z][^:]*)(?=\s*:)/g, '"$1"');
    return JSON.parse(properJSON);
  }

  // TEMP - Tool for logging annotation points
  $('body').click(function(e) {
    console.log(e.pageX + ' , ' + e.pageY);
  });

  init();

});
<commit_msg>Lowercase filename for screensaver video<commit_after>$(document).ready(function() {

  var ANNOTATION_TYPE_VIDEO = 'video';
  var ANNOTATION_TYPE_TEXT = 'text';
  var ANNOTATION_TYPE_AUDIO = 'audio';

  // Create annotations manifest
  var annotations = [];
  var videoPlayer = {};

  var appWidth = $('body').css('width');
  var appHeight = $('body').css('height');

  function init() {

    setupFullscreenVideo();
    setupScreenSaver();

    var paintingImg = $('.painting img').first();

    $('.annotations button').each(function() {

      var mediaPath = $(this).attr('media-path');
      var a = { id: $(this).attr('id'),
                btn: this,
                x: parseInt($(this).attr('annotation-x'), 10),
                y: parseInt($(this).attr('annotation-y'), 10),
                type: getMediaType(mediaPath),
                path: mediaPath,
      };

      annotations.push(a);

      // Position & style button (offset for button size)
      $(this).css('left', a.x - 20);
      $(this).css('top', a.y - 20);
      $(this).addClass('btn');
      $(this).append('');

      var cutout = $(this).attr('cutout');
      if (cutout === undefined) {
        cutout = {x:-70, y: -70, w: 140, h: 140};
      } else {
        cutout = getProperJSON(cutout);
      }

      a.cutRect = cutout;
      a.cutout = getCutoutFromImage(a.id, paintingImg, a.x + a.cutRect.x, a.y + a.cutRect.y, a.cutRect.w, a.cutRect.h);

    });

    // Create hit regions by building Vernoi diagram
    console.log(appWidth,appHeight);
    var svgElement = '<svg id="veronoi_ui" width="'+appWidth+'" height="'+appHeight+'"></svg>';
    $('.annotations').prepend(svgElement);

    // Allow time for size recalc...
    setTimeout(function() {
      var vornoi = new VoronoiLayer(annotations, $('#veronoi_ui'), onAnnotationSelected, onAnnotationActive, false);
    }, 200);

    cutoutsGoHome();

  }

  var onAnnotationActive = function(annId, annBtn) {

    for (var i = 0; i < annotations.length; i++) {

      var a = annotations[i];

      if (annId === a.id) {

        $(a.btn).addClass('active');

        break;
      }

    }

  };

  var onAnnotationSelected = function(annId, annBtn) {

    console.log('annotationSelected(): ' + annId);

    for (var i = 0; i < annotations.length; i++) {

      var a = annotations[i];

      if (annId === a.id) {

        // Block mouse/touch interaction
        $('.overlay').css('pointer-events', 'auto');
        $(a.btn).removeClass('active');

        // Transition

        TweenMax.to($(a.btn), 0.15, {
          opacity:0,
        });

        setTimeout(function() {

          TweenMax.to($('.overlay'), 1, {
              opacity:1,
              ease:Power2.easeOut,
            });

          $(a.cutout).show();

          TweenMax.set($(a.cutout), {
            boxShadow:'0px 0px 8px 2px rgba(0, 0, 0, 0)',
            zIndex:1,
            backgroundColor:'rgba(0,0,0,0.0)',
            padding:0,
          });

          TweenMax.to($(a.cutout), 1.75, {
            delay: 0.5,
            left:20,
            top:20,
            padding:10,
            backgroundColor:'rgba(0,0,0,0.5)',
            boxShadow:'0px 3px 8px 2px rgba(0, 0, 0, 0.3)',
            ease:Power2.easeInOut,
            onComplete:showAnnotationContent,
            onCompleteParams:[a],
          });

        }, 150);

        break;

      }
    };

  };

  function showAnnotationContent(ann) {

    switch (ann.type) {
      case ANNOTATION_TYPE_VIDEO:
        showFullscreenVideo(ann.path);
        break;
      default:
        console.log('Whoops! Presentation for annotation type:', ann.type, ' has not been built out yet!');
        break;
    }
  }

  function getCutoutFromImage(id, imgElement, x, y, w, h) {

    id = id + '_cutout';
    var imgSrc = $(imgElement).attr('src');

    var cnvs = '<canvas id="' + id + '" style="position:absolute" width="' + w + '" height="' + h + '"></canvas>';

    $(imgElement).parent().append(cnvs);
    var cnvs = $('#' + id);
    var context = $(cnvs).get(0).getContext('2d');
    var imageObj = new Image();

    imageObj.onload = function() {

      context.drawImage(imageObj, x, y, w, h, 0, 0, w, h);
      TweenMax.set($(cnvs), {left:x, top:y});

    };

    imageObj.src = imgSrc;

    return cnvs;

  }

  function setupFullscreenVideo() {

    // Create video tag
    var options = { controls:false, autoplay: true, loop: false, preload: 'auto' };

    videoPlayer = $('video');

    videoPlayer.on('playing', function() {

      console.log('Video is playing');

      $('.content').show();

      TweenMax.set($('.content'), {
        opacity:0,
      });

      TweenMax.to($('.content'), 0.5, {
        opacity:1,
        ease:Power2.easeIn,
      });

    });

    videoPlayer.on('ended', function() {

      console.log('Video has ended!');

      hideFullscreenVideo();

    });

    // Home button
    $('.home-btn').on('click', function() {

      hideFullscreenVideo();

    });

  }

  function showFullscreenVideo(vidSrc) {

    videoPlayer.attr('src', vidSrc);
    videoPlayer.load();

  }

  function hideFullscreenVideo() {

    $('.content').fadeOut('fast', function() {
      videoPlayer.get(0).pause();
      $('.content').hide();

      cutoutsGoHome();

    });

  }

  function cutoutsGoHome() {
    for (var i = 0; i < annotations.length; i++) {

      TweenMax.to($(annotations[i].cutout), 1.5, {
        delay: 0.0,
        left:annotations[i].x + annotations[i].cutRect.x,
        top:annotations[i].y + annotations[i].cutRect.y,
        backgroundColor:'rgba(0,0,0,0.0)',
        boxShadow:'0px 0px 8px 2px rgba(0, 0, 0, 0)',
        padding:0,
        ease:Power2.easeInOut,
        onCompleteParams:[annotations[i]],
        onComplete:function(a) {
          TweenMax.set($(a.cutout),  {
            zIndex:0,
          });
          TweenMax.to($(a.btn), 0.5, {
            opacity:1,
          });
          $(a.cutout).hide();

          // Unblock mouse/touch interaction
          $('.overlay').css('pointer-events', 'none');
        },
      });

    };

    TweenMax.to($('.overlay'), 0.75, {
      opacity:0,
      delay:0.25,
    });

  }

  function setupScreenSaver() {

    var screensaver = new Screensaver(5 * 60, 'videos/screensaver.mp4', function() {

      console.log('onSleepCallback');

    });

  }

  function getMediaType(mediaPath) {

    var ext = mediaPath.split('.').pop();
    var type = '';

    if (ext === 'mp4' || ext === 'mov') {
      type = ANNOTATION_TYPE_VIDEO;
    } else if (ext === 'mp3' || ext === 'ogg') {
      type = ANNOTATION_TYPE_AUDIO;
    } else if (ext === 'txt' || ext === 'json' || ext === 'xml' || ext === 'html') {
      type = ANNOTATION_TYPE_TEXT;
    } else {
      console.log('Unrecognized media type for file:', mediaPath);
    }

    return type;
  }

  function getProperJSON(improperJSON) {
    var properJSON = improperJSON.replace(/([a-z][^:]*)(?=\s*:)/g, '"$1"');
    return JSON.parse(properJSON);
  }

  // TEMP - Tool for logging annotation points
  $('body').click(function(e) {
    console.log(e.pageX + ' , ' + e.pageY);
  });

  init();

});
<|endoftext|>


<commit_before>

  (function(globals){
  // Don't worry if that seems a little funky...

    /**
     * Internal representation of the game board in its current state.
     *
     * @see game.board
     * @see game.tracer
     * @see initial
     * @var {Array} of {Array} of {String|null}
     */
    var board = initial(); // initialize the `board`

    /**
     * List of moves for the "Catalan Opening: Closed Variation" suitable for use
     * as arguments to `applyMove` below.
     *
     * @see applyMove
     * @var {Array} of...?
     */
    var moves = [
      // TODO: Fill me in!
    ]; // END moves

    // var current; TODO: do we need this?

    // You don't need to understand `globals` yet...
    var game = globals.game = {
      /**
       * Provide a _copy_ of the game board in order to update the View from it
       *
       * @return {Array} of {Array} of {String|null}
       */
      board: function(){
        return board.map(function(row){
          return row.slice();
        });
      },
      /**
       * Reset the internal game board to it's initial state.
       *
       * @return {Object} the game object for Method Chaining
       */
      reset: function(){
        board = initial();

        return this;
      },
      /**
       * Advance the internal game board to the next move.
       *
       * @return {Object} the game object for Method Chaining
       * @todo Make this work!
       */
      next: function(){
        // Doesn't this seem to be missing something?
        return this;
      },
      /**
       * Advance the internal game board to the previous move.
       *
       * @return {Object} the game object for Method Chaining
       * @todo Make this work!
       */
      prev: function(){
        // Another good place for code...
        return this;
      },
      /**
       * Advance the internal game board to the last move.
       *
       * @return {Object} the game object for Method Chaining
       * @todo Make this work!
       */
      end: function(){
        // Write some code here...
        return this;
      },
      /**
       * Provide a printable representation of the game board for use as a tracer
       *
       * @return {String} representation of `board`
       * @todo Refactor to use Array methods?
       */
      tracer: function(){
        var bullet = '';

        for ( var rank = 0; rank < board.length; rank++ ){
          bullet += '|';
          for ( var file = 0; file < board[rank].length; file++ ){
            bullet += board[rank][file] || ' |';
          }
          bullet += '\n';
        }

        return bullet;
      },
      /**
       * Apply a move to the game board, given a `from` and `to` position that both
       * contain values for `rank` and `file`.
       *
       * @param {Object} from with `rank` and `file`
       * @param {Object} to with `rank` and `file`
       * @return undefined
       *
       * @todo Fill me in! ...and remove this comment.
       */
      applyMove: function (from, to){
        // You should write something in here...
      } // END applyMove
    }; // END game

    /**
     * Provide the initial state of the game board, useful for any game.
     *
     * @return {Array} of {Array} of {String|null}
     */
    function initial(){
      return [
        [ 'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R' ],
        [ 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' ],
        Array(8).fill(null),
        Array(8).fill(null),
        Array(8).fill(null),
        Array(8).fill(null),
        [ 'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p' ],
        [ 'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r' ],
      ];
    }; // END initial

  // You are not expected to understand anything below this line...
  })(window || module && module.exports || this);
<commit_msg>adds moves value<commit_after>

  (function(globals){
  // Don't worry if that seems a little funky...

    /**
     * Internal representation of the game board in its current state.
     *
     * @see game.board
     * @see game.tracer
     * @see initial
     * @var {Array} of {Array} of {String|null}
     */
    var board = initial(); // initialize the `board`

    /**
     * List of moves for the "Catalan Opening: Closed Variation" suitable for use
     * as arguments to `applyMove` below.
     *
     * @see applyMove
     * @var {Array} of...?
     */
    var moves = [                   //list with an object whose parameter "from"
      {from:{rank: " ", file: " "}, //has a value of another object with the parameters of "rank"
       to:{rank: " ", file: " "}    //and "file" whose properties will correlate to the position of the
     };                             //piece on the board before moving. The first obj also has a parameter "to" with
                                    //the value of another obj with "rank" and "file". In example " " are used as a placeholder.
    ]; // END moves

    // var current; TODO: do we need this?

    // You don't need to understand `globals` yet...
    var game = globals.game = {
      /**
       * Provide a _copy_ of the game board in order to update the View from it
       *
       * @return {Array} of {Array} of {String|null}
       */
      board: function(){
        return board.map(function(row){
          return row.slice();
        });
      },
      /**
       * Reset the internal game board to it's initial state.
       *
       * @return {Object} the game object for Method Chaining
       */
      reset: function(){
        board = initial();

        return this;
      },
      /**
       * Advance the internal game board to the next move.
       *
       * @return {Object} the game object for Method Chaining
       * @todo Make this work!
       */
      next: function(){
        // Doesn't this seem to be missing something?
        return this;
      },
      /**
       * Advance the internal game board to the previous move.
       *
       * @return {Object} the game object for Method Chaining
       * @todo Make this work!
       */
      prev: function(){
        // Another good place for code...
        return this;
      },
      /**
       * Advance the internal game board to the last move.
       *
       * @return {Object} the game object for Method Chaining
       * @todo Make this work!
       */
      end: function(){
        // Write some code here...
        return this;
      },
      /**
       * Provide a printable representation of the game board for use as a tracer
       *
       * @return {String} representation of `board`
       * @todo Refactor to use Array methods?
       */
      tracer: function(){
        var bullet = '';

        for ( var rank = 0; rank < board.length; rank++ ){
          bullet += '|';
          for ( var file = 0; file < board[rank].length; file++ ){
            bullet += board[rank][file] || ' |';
          }
          bullet += '\n';
        }

        return bullet;
      },
      /**
       * Apply a move to the game board, given a `from` and `to` position that both
       * contain values for `rank` and `file`.
       *
       * @param {Object} from with `rank` and `file`
       * @param {Object} to with `rank` and `file`
       * @return undefined
       *
       * @todo Fill me in! ...and remove this comment.
       */
      applyMove: function (from, to){
        // You should write something in here...
      } // END applyMove
    }; // END game

    /**
     * Provide the initial state of the game board, useful for any game.
     *
     * @return {Array} of {Array} of {String|null}
     */
    function initial(){
      return [
        [ 'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R' ],
        [ 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' ],
        Array(8).fill(null),
        Array(8).fill(null),
        Array(8).fill(null),
        Array(8).fill(null),
        [ 'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p' ],
        [ 'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r' ],
      ];
    }; // END initial

  // You are not expected to understand anything below this line...
  })(window || module && module.exports || this);
<|endoftext|>


<commit_before>/**
 * [base description]
 * @require M.MObjectUtil
 * @require M.interface
 * @type {Object}
 */

Mayjs.util.run(function(M) {
    var traverseChain = M.MObjectUtil.traverseChain;
    var mix = M.MObjectUtil.mix;

    var BaseObj = {
        __interfaces__: [],
        initialize: function(){
        },
        extend: function(objDefine){
            var obj = Object.create(this);

            if(!Object["__proto__"]) {//for IE browser
                obj["__proto__"] = this;
            }

            for(var name in objDefine){
                var member = objDefine[name];
                obj[name] = member;

                //add __name__ to method
                if(typeof(member) == "function"){
                    member.__name__ = name;
                }
            }

            this.initialize.call(obj);
            return obj;
        },
        base: function(){
            var caller = arguments.callee.caller;
            var callerName = caller.name || caller.__name__;
            var callerOwner = this.__getCallerOwner(caller, callerName);
            if(!callerName)callerName = caller.__name__; //在this._getCallerOwner方法中会为caller设置name meta;

            var base = callerOwner ? callerOwner.__proto__ : null;
            var fn = base ? base[callerName] : null;

            if(typeof fn == "function") {
                return fn.apply(this, arguments);
            }
        },
        __getCallerOwner: function(caller, callerName){
            var callerOwner = null;
            if(callerName){
                if(this.hasOwnProperty(callerName) && this[callerName] === caller)return this;

                if(this["__proto__"][callerName] == caller){
                    return this["__proto__"];
                }

                traverseChain(this, "__proto__", function(proto) {
                    if(proto.hasOwnProperty(callerName) && proto[callerName] == caller){
                        callerOwner = proto;
                        return false;
                    }
                });
            }else{
                for(var p in this){
                    if(this[p] === caller){
                        callerOwner = this;
                        caller.__name__ = p;
                        break;
                    }
                }
                if(callerOwner)return callerOwner;

                traverseChain(this, "__proto__", function(proto) {
                    Object.keys(proto).forEach(function(p) {
                        if(proto[p] == caller) {
                            callerOwner = proto;
                            caller.__name__ = p;
                            return false;
                        }
                    });
                });
            }
            return callerOwner;
        }
    }

    function Klass(){}
    Klass.prototype = BaseObj.extend({
        initialize: function(){
            this.__interfaces__ = [];
            this.base(); //call BaseObj.initialize
        }
    });
    Klass.extend = function(classDefine){
        var proto = this.prototype.extend(classDefine);

        if(!proto.hasOwnProperty("initialize")){
            proto.initialize = function(){
                this.base.apply(this, arguments);
            }
        }

        var clazz;
        if(!Object["__proto__"]) {//for IE browser
            clazz = function(){
                if(!proto.isPrototypeOf(this)){
                    return new (arguments.callee);
                }
                this.constructor = clazz;
                this["__proto__"] = proto;
                proto.initialize.apply(this, arguments);
            }
        }else{
            clazz = function(){
                if(!proto.isPrototypeOf(this)){
                    return new (arguments.callee);
                }
                this.constructor = clazz;
                proto.initialize.apply(this, arguments);
            }
        }

        clazz.prototype = proto;
        var excludes = ["prototype"];
        for(var p in Klass){
            if(excludes.indexOf(p) == -1){
                clazz[p] = this[p];
            }
        }

        return clazz;
    }

    var BaseClass = Klass.extend({})

    /**
     * @memberof M
     * @type {Interface}
     */
    var IBase = M.$interface({
        "initialize": [],
        "base": [],
        "__interfaces__": Array
    });

    M.$implement(BaseObj, IBase);

    function $class(prototype){
        return BaseClass.extend(prototype);
    }

    function $obj(obj){
        return BaseObj.extend(obj);
    }

    M.IBase = IBase;
    M.BaseObj = BaseObj;
    M.BaseClass = BaseClass;
    M.$class = $class;
    M.$obj = $obj;
}, Mayjs);<commit_msg>让proto.constructor指向父类<commit_after>/**
 * [base description]
 * @require M.MObjectUtil
 * @require M.interface
 * @type {Object}
 */

Mayjs.util.run(function(M) {
    var traverseChain = M.MObjectUtil.traverseChain;
    var mix = M.MObjectUtil.mix;

    var BaseObj = {
        __interfaces__: [],
        initialize: function(){
        },
        extend: function(objDefine){
            var obj = Object.create(this);

            if(!Object["__proto__"]) {//for IE browser
                obj["__proto__"] = this;
            }

            for(var name in objDefine){
                var member = objDefine[name];
                obj[name] = member;

                //add __name__ to method
                if(typeof(member) == "function"){
                    member.__name__ = name;
                }
            }

            this.initialize.call(obj);
            return obj;
        },
        base: function(){
            var caller = arguments.callee.caller;
            var callerName = caller.name || caller.__name__;
            var callerOwner = this.__getCallerOwner(caller, callerName);
            if(!callerName)callerName = caller.__name__; //在this._getCallerOwner方法中会为caller设置name meta;

            var base = callerOwner ? callerOwner.__proto__ : null;
            var fn = base ? base[callerName] : null;

            if(typeof fn == "function") {
                return fn.apply(this, arguments);
            }
        },
        __getCallerOwner: function(caller, callerName){
            var callerOwner = null;
            if(callerName){
                if(this.hasOwnProperty(callerName) && this[callerName] === caller)return this;

                if(this["__proto__"][callerName] == caller){
                    return this["__proto__"];
                }

                traverseChain(this, "__proto__", function(proto) {
                    if(proto.hasOwnProperty(callerName) && proto[callerName] == caller){
                        callerOwner = proto;
                        return false;
                    }
                });
            }else{
                for(var p in this){
                    if(this[p] === caller){
                        callerOwner = this;
                        caller.__name__ = p;
                        break;
                    }
                }
                if(callerOwner)return callerOwner;

                traverseChain(this, "__proto__", function(proto) {
                    Object.keys(proto).forEach(function(p) {
                        if(proto[p] == caller) {
                            callerOwner = proto;
                            caller.__name__ = p;
                            return false;
                        }
                    });
                });
            }
            return callerOwner;
        }
    }

    function Klass(){}
    Klass.prototype = BaseObj.extend({
        initialize: function(){
            this.__interfaces__ = [];
            this.base(); //call BaseObj.initialize
        }
    });
    Klass.extend = function(classDefine){
        var proto = this.prototype.extend(classDefine);

        if(!proto.hasOwnProperty("initialize")){
            proto.initialize = function(){
                this.base.apply(this, arguments);
            }
        }

        var clazz;
        if(!Object["__proto__"]) {//for IE browser
            clazz = function(){
                if(!proto.isPrototypeOf(this)){
                    return new (arguments.callee);
                }
                this.constructor = clazz;
                this["__proto__"] = proto;
                proto.initialize.apply(this, arguments);
            }
        }else{
            clazz = function(){
                if(!proto.isPrototypeOf(this)){
                    return new (arguments.callee);
                }
                this.constructor = clazz;
                proto.initialize.apply(this, arguments);
            }
        }

        proto.constructor = this;
        clazz.prototype = proto;
        var excludes = ["prototype"];
        for(var p in Klass){
            if(excludes.indexOf(p) == -1){
                clazz[p] = this[p];
            }
        }

        return clazz;
    }

    var BaseClass = Klass.extend({})

    /**
     * @memberof M
     * @type {Interface}
     */
    var IBase = M.$interface({
        "initialize": [],
        "base": [],
        "__interfaces__": Array
    });

    M.$implement(BaseObj, IBase);

    function $class(prototype){
        return BaseClass.extend(prototype);
    }

    function $obj(obj){
        return BaseObj.extend(obj);
    }

    M.IBase = IBase;
    M.BaseObj = BaseObj;
    M.BaseClass = BaseClass;
    M.$class = $class;
    M.$obj = $obj;
}, Mayjs);<|endoftext|>


<commit_before>require([
  'jquery',
  'backbone',
  'views/root',
  'routers/main-polis-router',
  'bootstrap_alert',
  'bootstrap_tab',
  'bootstrap_tooltip',
  'bootstrap_button',
  'bootstrap_transition',
  // 'bootstrap_popover',
], function ($, Backbone, RootView, MainPolisRouter) {

  initialize(function(next) {
    // Load any data that your app requires to boot
    // and initialize all routers here, the callback
    // `next` is provided in case the operations
    // needed are aysynchronous
    new MainPolisRouter();

    next();
  });

  function initialize(complete) {
    $(function() {
      Backbone.history.start({
        pushState: false,
        root: '/',
        silent: true
      });

      // RootView may use link or url helpers which
      // depend on Backbone history being setup
      // so need to wait to loadUrl() (which will)
      // actually execute the route
      RootView.getInstance(document.body);

      complete(function() {
        Backbone.history.loadUrl();
      });
    });
  }

});
<commit_msg>window.deregister debug function<commit_after>require([
  'jquery',
  'backbone',
  'views/root',
  'routers/main-polis-router',
  'util/polisStorage',
  'bootstrap_alert',
  'bootstrap_tab',
  'bootstrap_tooltip',
  'bootstrap_button',
  // 'bootstrap_popover',
  'bootstrap_transition'
], function ($, Backbone, RootView, MainPolisRouter, PolisStorage) {

  // debug convenience function for deregistering.
  window.deregister = function() {
    PolisStorage.clearAll();
  };

  initialize(function(next) {
    // Load any data that your app requires to boot
    // and initialize all routers here, the callback
    // `next` is provided in case the operations
    // needed are aysynchronous
    new MainPolisRouter();

    next();
  });

  function initialize(complete) {
    $(function() {
      Backbone.history.start({
        pushState: false,
        root: '/',
        silent: true
      });

      // RootView may use link or url helpers which
      // depend on Backbone history being setup
      // so need to wait to loadUrl() (which will)
      // actually execute the route
      RootView.getInstance(document.body);

      complete(function() {
        Backbone.history.loadUrl();
      });
    });
  }

});
<|endoftext|>


<commit_before>CatDefense.GameState = function(game) {
        this.MAX_CATS = 5; // number of cats
        this.MAX_YARN = 2;
        this.catsLeft = 15;
        this.health = 3;
        this.catTypes = [
         // [name, health, speed],
            ['garfield',    50, 110],
            ['marie',       60, 100],
            ['mimi',        70, 90],
            ['calico',      80, 80],
            ['fluff',       90, 70],
            ['friday',      100, 60],
            ['tabby',       110, 50],
        ];
};

CatDefense.GameState.prototype.preload = function() {
    this.game.load.image('tile', 'assets/env/tile.png');
    this.game.load.image('room', 'assets/env/room.png');
    this.game.load.spritesheet('heart', 'assets/env/heart-sprite.png', 100, 100);

    // Load items assets
    this.game.load.image('yarn', 'assets/items/yarn.png');

    // Load cat assets
    this.catTypes.forEach(function(elem) {
        this.game.load.spritesheet(elem[0], 'assets/cats/sprite-' + elem[0] + '.png', 100, 100);
        this.game.load.audio(elem[0], 'assets/audio/' + elem[0] + '.ogg');
    });

    // Audio!
    this.game.load.audio('theme', 'assets/audio/theme.ogg');
    this.game.load.audio('trill', 'assets/audio/trill.ogg');

    // Background!
    this.game.load.image('background', 'assets/background.jpg');
};

CatDefense.GameState.prototype.create = function() {
    // Set stage background
    this.game.add.image(0, 0, 'background');

    this.catsLeft = 15;
    this.health = 3;

    // Make transparent sprite for detecting mouse click
    clickablebg = this.game.add.sprite(0, 0);
    clickablebg.scale.setTo(game.width/clickablebg.width, game.height/clickablebg.height);
    clickablebg.inputEnabled = true;
    clickablebg.input.priorityID = 0;
    clickablebg.events.onInputDown.add(this.placeObstacle, this, 0, this);

    // Create a group to hold the cat
    this.catGroup = this.game.add.group();
    this.obstacleGroup = this.game.add.group();

    this.theme = this.game.add.audio('theme');

    this.meows = {};
    this.catTypes.forEach(function(cat) {
      this.meows[cat[0]] = game.add.audio(cat[0]);
    }.bind(this));

    trill = this.game.add.audio('trill');
    // Loop theme forever
    this.theme.loopFull(0.1);

    this.catsLeftText = this.game.add.text(this.game.width - 270, 20, "Cats left: " + this.catsLeft);

    // Setup pause button
    var pause_btn = this.input.keyboard.addKey(27);
    pause_btn.onDown.add(this.togglePause, this);

    // Add ammo tracker
    var yarnTile = this.game.add.image(10, 10, 'tile');
    yarnTile.scale.setTo(2, 1);

    var yarnIcon = this.game.add.image(20, 20, 'yarn');
    yarnIcon.scale.setTo(.8, .8);

    ammocount = this.MAX_YARN;
    ammotext = this.game.add.text(90, 30, this.ammocount);

    // Add ammo tracker
    var healthTile = this.game.add.image(120, 10, 'tile');
    healthTile.scale.setTo(2, 1);

    this.healthIcon = this.game.add.sprite(150, 10, 'heart');
    this.healthIcon.animations.add('beat', [0, 1], 0.5, true, true);
    this.healthIcon.scale.setTo(.8, .8);

    this.healthText = this.game.add.text(230, 30, this.health);
};

CatDefense.GameState.prototype.update = function() {
    ammotext.text = ammocount;

    this.healthIcon.animations.play('beat');

    // If there are fewer than MAX_CATS, launch a new one
    if (this.catGroup.countLiving() < this.MAX_CATS) {
        // Set the launch point to a random location past the right edge
        // of the stage
        var newcat = this.launchCat(this.game.width - 100 + this.game.rnd.integerInRange(1, 200),
			this.game.rnd.integerInRange(50, this.game.height-50));

        // Move cat to the center of the left edge of the stage
        newcat.setOnTarget();
    }

    this.game.physics.arcade.collide(this.catGroup, this.obstacleGroup);
};

CatDefense.GameState.prototype.togglePause = function() {
   if (game.physics.arcade.isPaused) {
      this.pauseText.destroy();
      game.physics.arcade.isPaused = false;
   } else {
      this.pauseText = game.add.text(game.world.centerX - 100, game.world.centerY, "Pawsed", {
        font: "65px Arial",
        fill: "#ffffff",
        align: "center"
      });
      game.physics.arcade.isPaused = true;
   }
};

CatDefense.GameState.prototype.launchCat = function(x, y) {
    // Get the first dead cat from the catGroup :'(
    var cat = this.catGroup.getFirstDead();

    // If there aren't any available, create a new one
    if (cat === null) {
        cat = new Cat(this.game);
        this.catGroup.add(cat);
    } else {
        this.catsLeft--;
        this.catsLeftText.setText("Cats Left: " + this.catsLeft);

        if (this.catsLeft == 0) {
            // End game
            this.theme.stop();
            this.state.start('end', true, false, 'win');
        }
    }

    // Revive the cat (set it's alive property to true)
    // You can also define a onRevived event handler in your cat objects
    // to do stuff when they are revived.
    cat.revive();
    cat.walking = true;

    // Move the cat to the given coordinates
    cat.x = x;
    cat.y = y;

    return cat;
};

CatDefense.GameState.prototype.loseHealth = function() {
   this.health--;

   this.healthText.setText(this.health);

   if (this.health == 0) {
      // endgame
      this.theme.stop();
      this.state.start('end', true, false, 'lose');
   }
}

var Cat = function (game, x, y) {
    var state = CatDefense.getCurrentState();
    var numTypes = state.catTypes.length;
    var catType = state.catTypes[game.rnd.integerInRange(0,numTypes-1)];
    this.catType = catType;

    Phaser.Sprite.call(this, game, x, y, catType[0]);
    this.health = catType[1];
    var step = [[0,1],[1,0]][game.rnd.integerInRange(0,1)];
    this.animations.add('left', step, 2, true, true);
    this.animations.add('meow', [2,1,2,1], 5, false, true);
    game.physics.enable(this, Phaser.Physics.ARCADE);

    this.body.onCollide = new Phaser.Signal();
    this.body.onCollide.add(function(me, other) {
      // When a cat collides with an obstacle, that obstacle should lose one
      // hit point and the cat should lose one hit point.
      //
      // This can probably be done with sprite health things. If the health
      // gets to zero, either the obstacle or the cat is kill.
      //
      // If the cat is alive after a collision it should try to move again. If
      // the obstacle is alive again, it'll collide again. This repeats until
      // one or both dies.
      //
      // If the cat survives and obstacle dies, the cat should begin moving
      // back to the target.
      me.walking = false;
      meows = CatDefense.getCurrentState().meows;
      meows[me.catType[0]].play();
      me.damage(35);
      other.damage(50);

      if (me.alive) {
         var timer = game.time.create(false);
         timer.add(500, function(cat) {
            cat.setOnTarget();
            cat.walking = true;
         }, game, me);
         timer.start();
      }
    });
}

Cat.prototype = Object.create(Phaser.Sprite.prototype);
Cat.prototype.constructor = Cat;

Cat.prototype.setOnTarget = function () {
    var game = CatDefense.getCurrentState().game;
    game.physics.arcade.moveToXY(this, 0, game.width / 2, this.catType[2]);
}

Cat.prototype.meow = function() {
   var typeName = this.catType[0];
   var meows = CatDefense.getCurrentState().meows;
   meows[typeName].play();
}

Cat.prototype.update = function() {
    if (this.x < 100) {
      trill.play();
      this.kill();

      CatDefense.getCurrentState().loseHealth();
    }
    if(this.walking)
        this.play('left');
    else
        this.play('meow');
};

/*
    Obstacles code
*/

CatDefense.GameState.prototype.placeObstacle = function (sprite, pointer) {
    var x = pointer.x;
    var y = pointer.y;
    // Get the first dead cat from the catGroup :'(
    var obstacle = this.obstacleGroup.getFirstDead();

    // If there aren't any available, create a new one
    if (obstacle === null) {
      if (this.obstacleGroup.length < this.MAX_YARN) {
         obstacle = new Obstacle(this.game);
         this.obstacleGroup.add(obstacle);
      } else {
         return;
      }
    }

    // Revive the cat (set it's alive property to true)
    // You can also define a onRevived event handler in your cat objects
    // to do stuff when they are revived.
    obstacle.revive();

    // Move the cat to the given coordinates
    obstacle.x = x;
    obstacle.y = y;

    // Accounting
    ammocount -= 1;

    return obstacle;
}

var Obstacle = function (game, x, y) {
    Phaser.Sprite.call(this, game, x, y, 'yarn');
    this.game.physics.enable(this, Phaser.Physics.ARCADE);
    this.body.immovable = true;
    this.events.onKilled.add(function() {
        ammocount += 1;
    });
    this.inputEnabled = true;
    this.input.priorityID = 1;
    this.events.onInputDown.add(function (elem) {
        elem.kill();
    }, this);
    this.anchor = new Phaser.Point(.5,.5);
}

Obstacle.prototype = Object.create(Phaser.Sprite.prototype);
Obstacle.prototype.constructor = Obstacle;

CatDefense.getCurrentState = function () {
    return game.state.states[game.state.current];
}

var game = new Phaser.Game(1024, 768, Phaser.AUTO, 'game');
game.state.add('start', CatDefense.StartState);
game.state.add('game', CatDefense.GameState);
game.state.add('end', CatDefense.EndState);

game.state.start('start');
<commit_msg>Restrict spawn vertically<commit_after>CatDefense.GameState = function(game) {
        this.MAX_CATS = 5; // number of cats
        this.MAX_YARN = 2;
        this.catsLeft = 15;
        this.health = 3;
        this.catTypes = [
         // [name, health, speed],
            ['garfield',    50, 110],
            ['marie',       60, 100],
            ['mimi',        70, 90],
            ['calico',      80, 80],
            ['fluff',       90, 70],
            ['friday',      100, 60],
            ['tabby',       110, 50],
        ];
};

CatDefense.GameState.prototype.preload = function() {
    this.game.load.image('tile', 'assets/env/tile.png');
    this.game.load.image('room', 'assets/env/room.png');
    this.game.load.spritesheet('heart', 'assets/env/heart-sprite.png', 100, 100);

    // Load items assets
    this.game.load.image('yarn', 'assets/items/yarn.png');

    // Load cat assets
    this.catTypes.forEach(function(elem) {
        this.game.load.spritesheet(elem[0], 'assets/cats/sprite-' + elem[0] + '.png', 100, 100);
        this.game.load.audio(elem[0], 'assets/audio/' + elem[0] + '.ogg');
    });

    // Audio!
    this.game.load.audio('theme', 'assets/audio/theme.ogg');
    this.game.load.audio('trill', 'assets/audio/trill.ogg');

    // Background!
    this.game.load.image('background', 'assets/background.jpg');
};

CatDefense.GameState.prototype.create = function() {
    // Set stage background
    this.game.add.image(0, 0, 'background');

    this.catsLeft = 15;
    this.health = 3;

    // Make transparent sprite for detecting mouse click
    clickablebg = this.game.add.sprite(0, 0);
    clickablebg.scale.setTo(game.width/clickablebg.width, game.height/clickablebg.height);
    clickablebg.inputEnabled = true;
    clickablebg.input.priorityID = 0;
    clickablebg.events.onInputDown.add(this.placeObstacle, this, 0, this);

    // Create a group to hold the cat
    this.catGroup = this.game.add.group();
    this.obstacleGroup = this.game.add.group();

    this.theme = this.game.add.audio('theme');

    this.meows = {};
    this.catTypes.forEach(function(cat) {
      this.meows[cat[0]] = game.add.audio(cat[0]);
    }.bind(this));

    trill = this.game.add.audio('trill');
    // Loop theme forever
    this.theme.loopFull(0.1);

    this.catsLeftText = this.game.add.text(this.game.width - 270, 20, "Cats left: " + this.catsLeft);

    // Setup pause button
    var pause_btn = this.input.keyboard.addKey(27);
    pause_btn.onDown.add(this.togglePause, this);

    // Add ammo tracker
    var yarnTile = this.game.add.image(10, 10, 'tile');
    yarnTile.scale.setTo(2, 1);

    var yarnIcon = this.game.add.image(20, 20, 'yarn');
    yarnIcon.scale.setTo(.8, .8);

    ammocount = this.MAX_YARN;
    ammotext = this.game.add.text(90, 30, this.ammocount);

    // Add ammo tracker
    var healthTile = this.game.add.image(120, 10, 'tile');
    healthTile.scale.setTo(2, 1);

    this.healthIcon = this.game.add.sprite(150, 10, 'heart');
    this.healthIcon.animations.add('beat', [0, 1], 0.5, true, true);
    this.healthIcon.scale.setTo(.8, .8);

    this.healthText = this.game.add.text(230, 30, this.health);
};

CatDefense.GameState.prototype.update = function() {
    ammotext.text = ammocount;

    this.healthIcon.animations.play('beat');

    // If there are fewer than MAX_CATS, launch a new one
    if (this.catGroup.countLiving() < this.MAX_CATS) {
        // Set the launch point to a random location past the right edge
        // of the stage
        var newcat = this.launchCat(this.game.width - 100 + this.game.rnd.integerInRange(1, 200),
			this.game.rnd.integerInRange(300, this.game.height-50));

        // Move cat to the center of the left edge of the stage
        newcat.setOnTarget();
    }

    this.game.physics.arcade.collide(this.catGroup, this.obstacleGroup);
};

CatDefense.GameState.prototype.togglePause = function() {
   if (game.physics.arcade.isPaused) {
      this.pauseText.destroy();
      game.physics.arcade.isPaused = false;
   } else {
      this.pauseText = game.add.text(game.world.centerX - 100, game.world.centerY, "Pawsed", {
        font: "65px Arial",
        fill: "#ffffff",
        align: "center"
      });
      game.physics.arcade.isPaused = true;
   }
};

CatDefense.GameState.prototype.launchCat = function(x, y) {
    // Get the first dead cat from the catGroup :'(
    var cat = this.catGroup.getFirstDead();

    // If there aren't any available, create a new one
    if (cat === null) {
        cat = new Cat(this.game);
        this.catGroup.add(cat);
    } else {
        this.catsLeft--;
        this.catsLeftText.setText("Cats Left: " + this.catsLeft);

        if (this.catsLeft == 0) {
            // End game
            this.theme.stop();
            this.state.start('end', true, false, 'win');
        }
    }

    // Revive the cat (set it's alive property to true)
    // You can also define a onRevived event handler in your cat objects
    // to do stuff when they are revived.
    cat.revive();
    cat.walking = true;

    // Move the cat to the given coordinates
    cat.x = x;
    cat.y = y;

    return cat;
};

CatDefense.GameState.prototype.loseHealth = function() {
   this.health--;

   this.healthText.setText(this.health);

   if (this.health == 0) {
      // endgame
      this.theme.stop();
      this.state.start('end', true, false, 'lose');
   }
}

var Cat = function (game, x, y) {
    var state = CatDefense.getCurrentState();
    var numTypes = state.catTypes.length;
    var catType = state.catTypes[game.rnd.integerInRange(0,numTypes-1)];
    this.catType = catType;

    Phaser.Sprite.call(this, game, x, y, catType[0]);
    this.health = catType[1];
    var step = [[0,1],[1,0]][game.rnd.integerInRange(0,1)];
    this.animations.add('left', step, 2, true, true);
    this.animations.add('meow', [2,1,2,1], 5, false, true);
    game.physics.enable(this, Phaser.Physics.ARCADE);

    this.body.onCollide = new Phaser.Signal();
    this.body.onCollide.add(function(me, other) {
      // When a cat collides with an obstacle, that obstacle should lose one
      // hit point and the cat should lose one hit point.
      //
      // This can probably be done with sprite health things. If the health
      // gets to zero, either the obstacle or the cat is kill.
      //
      // If the cat is alive after a collision it should try to move again. If
      // the obstacle is alive again, it'll collide again. This repeats until
      // one or both dies.
      //
      // If the cat survives and obstacle dies, the cat should begin moving
      // back to the target.
      me.walking = false;
      meows = CatDefense.getCurrentState().meows;
      meows[me.catType[0]].play();
      me.damage(35);
      other.damage(50);

      if (me.alive) {
         var timer = game.time.create(false);
         timer.add(500, function(cat) {
            cat.setOnTarget();
            cat.walking = true;
         }, game, me);
         timer.start();
      }
    });
}

Cat.prototype = Object.create(Phaser.Sprite.prototype);
Cat.prototype.constructor = Cat;

Cat.prototype.setOnTarget = function () {
    var game = CatDefense.getCurrentState().game;
    game.physics.arcade.moveToXY(this, 0, game.width / 2, this.catType[2]);
}

Cat.prototype.meow = function() {
   var typeName = this.catType[0];
   var meows = CatDefense.getCurrentState().meows;
   meows[typeName].play();
}

Cat.prototype.update = function() {
    if (this.x < 100) {
      trill.play();
      this.kill();

      CatDefense.getCurrentState().loseHealth();
    }
    if(this.walking)
        this.play('left');
    else
        this.play('meow');
};

/*
    Obstacles code
*/

CatDefense.GameState.prototype.placeObstacle = function (sprite, pointer) {
    var x = pointer.x;
    var y = pointer.y;
    // Get the first dead cat from the catGroup :'(
    var obstacle = this.obstacleGroup.getFirstDead();

    // If there aren't any available, create a new one
    if (obstacle === null) {
      if (this.obstacleGroup.length < this.MAX_YARN) {
         obstacle = new Obstacle(this.game);
         this.obstacleGroup.add(obstacle);
      } else {
         return;
      }
    }

    // Revive the cat (set it's alive property to true)
    // You can also define a onRevived event handler in your cat objects
    // to do stuff when they are revived.
    obstacle.revive();

    // Move the cat to the given coordinates
    obstacle.x = x;
    obstacle.y = y;

    // Accounting
    ammocount -= 1;

    return obstacle;
}

var Obstacle = function (game, x, y) {
    Phaser.Sprite.call(this, game, x, y, 'yarn');
    this.game.physics.enable(this, Phaser.Physics.ARCADE);
    this.body.immovable = true;
    this.events.onKilled.add(function() {
        ammocount += 1;
    });
    this.inputEnabled = true;
    this.input.priorityID = 1;
    this.events.onInputDown.add(function (elem) {
        elem.kill();
    }, this);
    this.anchor = new Phaser.Point(.5,.5);
}

Obstacle.prototype = Object.create(Phaser.Sprite.prototype);
Obstacle.prototype.constructor = Obstacle;

CatDefense.getCurrentState = function () {
    return game.state.states[game.state.current];
}

var game = new Phaser.Game(1024, 768, Phaser.AUTO, 'game');
game.state.add('start', CatDefense.StartState);
game.state.add('game', CatDefense.GameState);
game.state.add('end', CatDefense.EndState);

game.state.start('start');
<|endoftext|>