<commit_before>var newCardCounter = 0;
var editingSide = 0; // 0 Front 1 Back

function img_upload_completed()
{
    var url = $('#upload-target').contents().find('body').text();
    if (url != 'failure')
    {
        $('#cardImageContent').attr('src', '/media/' + url);
        $('#cardTextContent').addClass('hidden');
        $('#cardImageContent').removeClass('hidden');
        updateCard();
        updateMiniPreviews();
        $('#imageForm')[0].reset();
    }
}

function updateCard(){
    var txt = $('#cardTextContent').val();
    var img = $('#cardImageContent').attr('src')

    var cardId = $('#cardPreview').attr('data-cardId');

    var miniPreview = $('.cardMiniPreview[data-cardId="' + cardId + '"]');
    miniPreview.find('label').text(txt);

    if (editingSide == 0){
        $('#frontText-' + cardId).val(txt);
        $('#frontImg-' + cardId).val(img);
    }
    else{
        $('#backText-' + cardId).val(txt);
        $('#backImg-' + cardId).val(img);
    }
}

function updateTheme(theme, shortName){
    $('#themeField').val(shortName);
    theme = theme.replace(' ', '%20');
    $('#cardPreview').css('background-image', 'url(' + theme +')');
    $('.cardMiniPreview').css('background-image', 'url(' + theme +')');
}

function updateCardList(){
    var newCardList = []

    $('.cardMiniPreview').each(function() {
        newCardList[newCardList.length] = $(this).attr('data-cardId');
    });

    $(cardIdList).val(newCardList.toString());

    var visibleCount = $('.cardMiniPreview:not(.cardRemoved)').length;

    $('#cardsContainer').css('width', (80*visibleCount) + 'px')

    $('#removeCard').toggle(visibleCount > 1);
}

function selectCard(card){
        var cardId = $(card).attr('data-cardId');

        if (editingSide == 0)
        {
            $('#cardTextContent').val($('#frontText-' + cardId).val());
            $('#cardImageContent').attr('src', $('#frontImg-' + cardId).val())
        }
        else{
            $('#cardTextContent').val($('#backText-' + cardId).val());
            $('#cardImageContent').attr('src', $('#backImg-' + cardId).val())
        }

        if ($('#cardImageContent').attr('src') != '')
        {
            $('#cardTextContent').addClass('hidden');
            $('#cardImageContent').removeClass('hidden');
        }
        else
        {
            $('#cardImageContent').addClass('hidden');
            $('#cardTextContent').removeClass('hidden');
        }

        $('#cardPreview').attr('data-cardId', cardId);
        $('.cardMiniPreview').removeClass('cardSelected');
        $(card).addClass('cardSelected');
}

function previewUploadedImage() {
    if( navigator.sayswho= (function(){
            var ua= navigator.userAgent, tem,
            M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
            if(/trident/i.test(M[1])){
                tem=  /\brv[ :]+(\d+)/g.exec(ua) || [];
                return 'IE '+(tem[1] || '');
            }
            if(M[1]=== 'Chrome'){
                tem= ua.match(/\bOPR\/(\d+)/)
                if(tem!= null) return 'Opera '+tem[1];
            }
            M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
            if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
            return M.join(' ');
    })().indexOf("IE") >= 0) {
        $("#noPreview").slideDown();
        return;
    } /*else {
        console.log(
            navigator.sayswho= (function(){
            var ua= navigator.userAgent, tem,
            M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
            if(/trident/i.test(M[1])){
                tem=  /\brv[ :]+(\d+)/g.exec(ua) || [];
                return 'IE '+(tem[1] || '');
            }
            if(M[1]=== 'Chrome'){
                tem= ua.match(/\bOPR\/(\d+)/)
                if(tem!= null) return 'Opera '+tem[1];
            }
            M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
            if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
            return M.join(' ');
            })()
        );
    }*/

    var input = $("#uploadImagesButton")[0];

    if( input.files && input.files[0] ) {
        var reader = new FileReader();

        reader.onload = function(e) {
            $("#uploadedImage").attr( "src", e.target.result );
            $("#imgPreviewContainer").show();
            $("#imgPreviewContainer").css("max-width", $("body").width());

            var offset = $("body").innerHeight()/2 - $("#imageDrawer").height()/2;
            $("#imageDrawer").css( "top", offset );
        }

        reader.readAsDataURL( input.files[0] );
    }
}

function checkImgSize() {
    /* -> if the img selected is < 5MB */
    var img = $("#uploadImagesButton")[0].files[0];
    var mbytes = (img.size / (1024 * 1024)).toFixed(2);

    if( mbytes > 5 ) {
        alert("The image you are trying to upload is larger than our 5MB limit. " +
              "Your image is " + mbytes + "MB.\n\n" +
              "Try shrinking the image, then re-uploading it.");

        return false;
    }

    return true;
}

function checkImgType() {
    /* -> if the img selected is an acceptable type */
    var img = $("#uploadImagesButton")[0].files[0];
    var type = img.type;
    // console.log(type);
    if( type != "image/jpeg" && type != "image/png" &&
        type != "image/gif"  && type != "image/bmp") {
        alert("The type of file you are trying to upload is not supported or allowed. " +
              "Please only upload one of the following types of images:\n" +
              "- JPEG (.jpg or .jpeg)\n" +
              "- Portable Network Graphics (.png)\n" +
              "- Animated GIF (.gif)\n" +
              "- Bitmap (.bmp)");
        return false;
    }
    return true;
}

function validateImage() {
    try {
        var img = $("#uploadImagesButton")[0].files[0];
    } catch(err) {
        previewUploadedImage();
        var img = document.getElementById("uploadImagesButton").item(0);
        console.log("Img = ", img);
    }

    if( img == undefined )
        return false;

    var imgOK  = checkImgSize();
    var typeOK = checkImgType();
    if( !(imgOK && typeOK) ) {
        $("#imageForm").find("input[type=file]").val("");
        return false;
    }
    previewUploadedImage();
    return true;
}

function updateMiniPreviews()
{
    if (editingSide == 0)
    {
        $('.cardMiniPreview').each(function() {
            var cardId = $(this).attr('data-cardId');
            var thisTxt = $('#frontText-' + cardId).val();
            var thisImg = $('#frontImg-' + cardId).val();

            var lbl = $(this).find('label');
            var img = $(this).find('img');
            lbl.text(thisTxt);
            img.attr('src', thisImg);

            if (thisImg != '')
            {
                lbl.addClass('hidden');
                img.removeClass('hidden');
            }
            else
            {
                img.addClass('hidden');
                lbl.removeClass('hidden');
            }

        });
    }
    else{
        $('.cardMiniPreview').each(function() {
            var cardId = $(this).attr('data-cardId');
            var thisTxt = $('#backText-' + cardId).val();
            var thisImg = $('#backImg-' + cardId).val();

            var lbl = $(this).find('label');
            var img = $(this).find('img');
            lbl.text(thisTxt);
            img.attr('src', thisImg);

            if (thisImg != '')
            {
                lbl.addClass('hidden');
                img.removeClass('hidden');
            }
            else
            {
                img.addClass('hidden');
                lbl.removeClass('hidden');
            }

        });
    }

}

$(document).ready(function(){
    $('#previewContainer').on("click", ".cardMiniPreview", function(){
        selectCard($(this));
    });

    $('.themePreview').click(function(){
        $('.themePreview').removeClass('themeSelected');
        $(this).addClass('themeSelected');
        updateTheme($(this).attr('src'), $(this).attr('data-theme'));
    });

    $('#addCard').click(function(){
        var cardId = 'new_' + (newCardCounter++);
        var cardImage = $('.cardSelected').css('background-image');
        cardImage = cardImage.replace(new RegExp('"', 'g'), "'");
        var newPreviewDiv =  $('

');
        var newLabel = $('');
        var newImage = $('');
        var newFrontField = $('<input  id="frontText-' + cardId  + '" type="hidden" name="front-' + cardId + '" value="">');
        var newFrontImgField = $('<input  id="frontImg-' + cardId  + '" type="hidden" name="front-img-' + cardId + '" value="">');
        var newBackField = $('<input  id="backText-' + cardId  + '" type="hidden" name="back-' + cardId + '" value="">');
        var newBackImgField = $('<input  id="backImg-' + cardId  + '" type="hidden" name="back-img-' + cardId + '" value="">');

        $('#cardsContainer').append($(newPreviewDiv))
        //$(newPreviewDiv).insertBefore($(this));
        $(newPreviewDiv).append(newLabel);
        $(newPreviewDiv).append(newImage);
        $(newPreviewDiv).append(newFrontField);
        $(newPreviewDiv).append(newFrontImgField);
        $(newPreviewDiv).append(newBackField);
        $(newPreviewDiv).append(newBackImgField);
        updateCardList();
    });

    $('#removeCard').click(function(){
        var reallyRemove = confirm('Remove current card?');
        if (reallyRemove == true) {
            var cardToRemove = $('.cardSelected');
            cardToRemove.fadeOut('slow' );
            cardToRemove.attr('data-cardId', '*' + cardToRemove.attr('data-cardId'));
            cardToRemove.addClass('cardRemoved');

            nextSibling = cardToRemove.next('.cardMiniPreview:not(.cardRemoved)');
            prevSibling = cardToRemove.prev('.cardMiniPreview:not(.cardRemoved)');
            if (nextSibling.length > 0) {
                selectCard(nextSibling);
            }
            else if (prevSibling.length > 0) {
                selectCard(prevSibling);
            }

            updateCardList();
        }
    });

    $('.cardSideRadio').click(function(){
        editingSide = ($(this).attr('id') == 'cardFront') ? 0 : 1;
        updateMiniPreviews();
        selectCard($('.cardSelected'));
    })

    $('#submitDeckChanges').click(function(){

    })

    $('#cardTextContent').change(updateCard);
    $('#cardTextContent').keyup(updateCard);

    $('#previewScrollLeft').click(function(){
        var container = $('#cardsContainer');
        var newLeft = (container.position().left + 64);
        if (newLeft > 0) {
            newLeft = 0;
        }
        container.css('left', newLeft + 'px');
    })

    $('#previewScrollRight').click(function(){
        var container = $('#cardsContainer');
        var newLeft = (container.position().left - 64);
        var farRight = newLeft + container.width();
        if (farRight >= $(this).position().left) {
            container.css('left', newLeft + 'px');
        }
    })

    $("#uploadImages").click( function() {
        $("#overlay").show();
        $("#imageDrawer").show();
        $('#uploadedImage').attr('src', '');
        $("#imgPreviewContainer").hide();
        var offset = $("body").innerHeight()/2 - $("#imageDrawer").height()/2;
        $("#imageDrawer").css( "top", offset );
    });

    $("#cancelUpload").click( function() {
        $("#overlay").hide();
        $("#imageDrawer").hide();
        $("#imgPreviewContainer").hide();
    });

    $("#overlay").click( function() {
        $("#overlay").hide();
        $("#imageDrawer").hide();
        $("#imgPreviewContainer").hide();
    });

    $(window).resize( function() {
        var offset = $("body").innerHeight()/2 - $("#imageDrawer").height()/2;
        $("#imageDrawer").css( "top", offset );
    });

    $('#clearImages').click(function(){
        $('#cardImageContent').attr('src', '')
        updateCard();
        selectCard($('.cardSelected'))
        updateMiniPreviews();

    });

    $("#uploadImagesButton").change( validateImage );
    $("#imageForm").attr("onsubmit", "validateImage()");
    $("#imageForm").submit( validateImage );

    $('#upload-target').on('load', img_upload_completed);

    $('#imageForm input:file').change(function(){
        $('#imageForm input:submit').removeClass('disabled');
    });

    $('#imageForm input:submit').click(function(){
        if (!$(this).hasClass('disabled'))
        {
            $("#overlay").hide();
            $("#imageDrawer").hide();
            $("#imgPreviewContainer").hide();

            $(this).addClass('disabled');
            $('#uploadedImage').attr('src', '');
            $('#submitUpload').addClass('disabled');
        }
    });

    selectCard($('.cardSelected'))

    updateCardList();
    updateMiniPreviews();
});
<commit_msg>Fixed Mini and Normal sized theme images.<commit_after>var newCardCounter = 0;
var editingSide = 0; // 0 Front 1 Back

function img_upload_completed()
{
    var url = $('#upload-target').contents().find('body').text();
    if (url != 'failure')
    {
        $('#cardImageContent').attr('src', '/media/' + url);
        $('#cardTextContent').addClass('hidden');
        $('#cardImageContent').removeClass('hidden');
        updateCard();
        updateMiniPreviews();
        $('#imageForm')[0].reset();
    }
}

function updateCard(){
    var txt = $('#cardTextContent').val();
    var img = $('#cardImageContent').attr('src')

    var cardId = $('#cardPreview').attr('data-cardId');

    var miniPreview = $('.cardMiniPreview[data-cardId="' + cardId + '"]');
    miniPreview.find('label').text(txt);

    if (editingSide == 0){
        $('#frontText-' + cardId).val(txt);
        $('#frontImg-' + cardId).val(img);
    }
    else{
        $('#backText-' + cardId).val(txt);
        $('#backImg-' + cardId).val(img);
    }
}

function updateTheme(theme, shortName){
    var bigName = theme.replace('Small', '');
    var tinyName = theme.replace('Small', 'Mini');

    $('#themeField').val(shortName);
    theme = theme.replace(' ', '%20');
    $('#cardPreview').css('background-image', 'url(' + bigName +')');
    $('.cardMiniPreview').css('background-image', 'url(' + tinyName +')');
}

function updateCardList(){
    var newCardList = []

    $('.cardMiniPreview').each(function() {
        newCardList[newCardList.length] = $(this).attr('data-cardId');
    });

    $(cardIdList).val(newCardList.toString());

    var visibleCount = $('.cardMiniPreview:not(.cardRemoved)').length;

    $('#cardsContainer').css('width', (80*visibleCount) + 'px')

    $('#removeCard').toggle(visibleCount > 1);
}

function selectCard(card){
        var cardId = $(card).attr('data-cardId');

        if (editingSide == 0)
        {
            $('#cardTextContent').val($('#frontText-' + cardId).val());
            $('#cardImageContent').attr('src', $('#frontImg-' + cardId).val())
        }
        else{
            $('#cardTextContent').val($('#backText-' + cardId).val());
            $('#cardImageContent').attr('src', $('#backImg-' + cardId).val())
        }

        if ($('#cardImageContent').attr('src') != '')
        {
            $('#cardTextContent').addClass('hidden');
            $('#cardImageContent').removeClass('hidden');
        }
        else
        {
            $('#cardImageContent').addClass('hidden');
            $('#cardTextContent').removeClass('hidden');
        }

        $('#cardPreview').attr('data-cardId', cardId);
        $('.cardMiniPreview').removeClass('cardSelected');
        $(card).addClass('cardSelected');
}

function previewUploadedImage() {
    if( navigator.sayswho= (function(){
            var ua= navigator.userAgent, tem,
            M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
            if(/trident/i.test(M[1])){
                tem=  /\brv[ :]+(\d+)/g.exec(ua) || [];
                return 'IE '+(tem[1] || '');
            }
            if(M[1]=== 'Chrome'){
                tem= ua.match(/\bOPR\/(\d+)/)
                if(tem!= null) return 'Opera '+tem[1];
            }
            M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
            if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
            return M.join(' ');
    })().indexOf("IE") >= 0) {
        $("#noPreview").slideDown();
        return;
    } /*else {
        console.log(
            navigator.sayswho= (function(){
            var ua= navigator.userAgent, tem,
            M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
            if(/trident/i.test(M[1])){
                tem=  /\brv[ :]+(\d+)/g.exec(ua) || [];
                return 'IE '+(tem[1] || '');
            }
            if(M[1]=== 'Chrome'){
                tem= ua.match(/\bOPR\/(\d+)/)
                if(tem!= null) return 'Opera '+tem[1];
            }
            M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
            if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
            return M.join(' ');
            })()
        );
    }*/

    var input = $("#uploadImagesButton")[0];

    if( input.files && input.files[0] ) {
        var reader = new FileReader();

        reader.onload = function(e) {
            $("#uploadedImage").attr( "src", e.target.result );
            $("#imgPreviewContainer").show();
            $("#imgPreviewContainer").css("max-width", $("body").width());

            var offset = $("body").innerHeight()/2 - $("#imageDrawer").height()/2;
            $("#imageDrawer").css( "top", offset );
        }

        reader.readAsDataURL( input.files[0] );
    }
}

function checkImgSize() {
    /* -> if the img selected is < 5MB */
    var img = $("#uploadImagesButton")[0].files[0];
    var mbytes = (img.size / (1024 * 1024)).toFixed(2);

    if( mbytes > 5 ) {
        alert("The image you are trying to upload is larger than our 5MB limit. " +
              "Your image is " + mbytes + "MB.\n\n" +
              "Try shrinking the image, then re-uploading it.");

        return false;
    }

    return true;
}

function checkImgType() {
    /* -> if the img selected is an acceptable type */
    var img = $("#uploadImagesButton")[0].files[0];
    var type = img.type;
    // console.log(type);
    if( type != "image/jpeg" && type != "image/png" &&
        type != "image/gif"  && type != "image/bmp") {
        alert("The type of file you are trying to upload is not supported or allowed. " +
              "Please only upload one of the following types of images:\n" +
              "- JPEG (.jpg or .jpeg)\n" +
              "- Portable Network Graphics (.png)\n" +
              "- Animated GIF (.gif)\n" +
              "- Bitmap (.bmp)");
        return false;
    }
    return true;
}

function validateImage() {
    try {
        var img = $("#uploadImagesButton")[0].files[0];
    } catch(err) {
        previewUploadedImage();
        var img = document.getElementById("uploadImagesButton").item(0);
        console.log("Img = ", img);
    }

    if( img == undefined )
        return false;

    var imgOK  = checkImgSize();
    var typeOK = checkImgType();
    if( !(imgOK && typeOK) ) {
        $("#imageForm").find("input[type=file]").val("");
        return false;
    }
    previewUploadedImage();
    return true;
}

function updateMiniPreviews()
{
    if (editingSide == 0)
    {
        $('.cardMiniPreview').each(function() {
            var cardId = $(this).attr('data-cardId');
            var thisTxt = $('#frontText-' + cardId).val();
            var thisImg = $('#frontImg-' + cardId).val();

            var lbl = $(this).find('label');
            var img = $(this).find('img');
            lbl.text(thisTxt);
            img.attr('src', thisImg);

            if (thisImg != '')
            {
                lbl.addClass('hidden');
                img.removeClass('hidden');
            }
            else
            {
                img.addClass('hidden');
                lbl.removeClass('hidden');
            }

        });
    }
    else{
        $('.cardMiniPreview').each(function() {
            var cardId = $(this).attr('data-cardId');
            var thisTxt = $('#backText-' + cardId).val();
            var thisImg = $('#backImg-' + cardId).val();

            var lbl = $(this).find('label');
            var img = $(this).find('img');
            lbl.text(thisTxt);
            img.attr('src', thisImg);

            if (thisImg != '')
            {
                lbl.addClass('hidden');
                img.removeClass('hidden');
            }
            else
            {
                img.addClass('hidden');
                lbl.removeClass('hidden');
            }

        });
    }

}

$(document).ready(function(){
    $('#previewContainer').on("click", ".cardMiniPreview", function(){
        selectCard($(this));
    });

    $('.themePreview').click(function(){
        $('.themePreview').removeClass('themeSelected');
        $(this).addClass('themeSelected');
        updateTheme($(this).attr('src'), $(this).attr('data-theme'));
    });

    $('#addCard').click(function(){
        var cardId = 'new_' + (newCardCounter++);
        var cardImage = $('.cardSelected').css('background-image');
        cardImage = cardImage.replace(new RegExp('"', 'g'), "'");
        var newPreviewDiv =  $('

');
        var newLabel = $('');
        var newImage = $('');
        var newFrontField = $('<input  id="frontText-' + cardId  + '" type="hidden" name="front-' + cardId + '" value="">');
        var newFrontImgField = $('<input  id="frontImg-' + cardId  + '" type="hidden" name="front-img-' + cardId + '" value="">');
        var newBackField = $('<input  id="backText-' + cardId  + '" type="hidden" name="back-' + cardId + '" value="">');
        var newBackImgField = $('<input  id="backImg-' + cardId  + '" type="hidden" name="back-img-' + cardId + '" value="">');

        $('#cardsContainer').append($(newPreviewDiv))
        //$(newPreviewDiv).insertBefore($(this));
        $(newPreviewDiv).append(newLabel);
        $(newPreviewDiv).append(newImage);
        $(newPreviewDiv).append(newFrontField);
        $(newPreviewDiv).append(newFrontImgField);
        $(newPreviewDiv).append(newBackField);
        $(newPreviewDiv).append(newBackImgField);
        updateCardList();
    });

    $('#removeCard').click(function(){
        var reallyRemove = confirm('Remove current card?');
        if (reallyRemove == true) {
            var cardToRemove = $('.cardSelected');
            cardToRemove.fadeOut('slow' );
            cardToRemove.attr('data-cardId', '*' + cardToRemove.attr('data-cardId'));
            cardToRemove.addClass('cardRemoved');

            nextSibling = cardToRemove.next('.cardMiniPreview:not(.cardRemoved)');
            prevSibling = cardToRemove.prev('.cardMiniPreview:not(.cardRemoved)');
            if (nextSibling.length > 0) {
                selectCard(nextSibling);
            }
            else if (prevSibling.length > 0) {
                selectCard(prevSibling);
            }

            updateCardList();
        }
    });

    $('.cardSideRadio').click(function(){
        editingSide = ($(this).attr('id') == 'cardFront') ? 0 : 1;
        updateMiniPreviews();
        selectCard($('.cardSelected'));
    })

    $('#submitDeckChanges').click(function(){

    })

    $('#cardTextContent').change(updateCard);
    $('#cardTextContent').keyup(updateCard);

    $('#previewScrollLeft').click(function(){
        var container = $('#cardsContainer');
        var newLeft = (container.position().left + 64);
        if (newLeft > 0) {
            newLeft = 0;
        }
        container.css('left', newLeft + 'px');
    })

    $('#previewScrollRight').click(function(){
        var container = $('#cardsContainer');
        var newLeft = (container.position().left - 64);
        var farRight = newLeft + container.width();
        if (farRight >= $(this).position().left) {
            container.css('left', newLeft + 'px');
        }
    })

    $("#uploadImages").click( function() {
        $("#overlay").show();
        $("#imageDrawer").show();
        $('#uploadedImage').attr('src', '');
        $("#imgPreviewContainer").hide();
        var offset = $("body").innerHeight()/2 - $("#imageDrawer").height()/2;
        $("#imageDrawer").css( "top", offset );
    });

    $("#cancelUpload").click( function() {
        $("#overlay").hide();
        $("#imageDrawer").hide();
        $("#imgPreviewContainer").hide();
    });

    $("#overlay").click( function() {
        $("#overlay").hide();
        $("#imageDrawer").hide();
        $("#imgPreviewContainer").hide();
    });

    $(window).resize( function() {
        var offset = $("body").innerHeight()/2 - $("#imageDrawer").height()/2;
        $("#imageDrawer").css( "top", offset );
    });

    $('#clearImages').click(function(){
        $('#cardImageContent').attr('src', '')
        updateCard();
        selectCard($('.cardSelected'))
        updateMiniPreviews();

    });

    $("#uploadImagesButton").change( validateImage );
    $("#imageForm").attr("onsubmit", "validateImage()");
    $("#imageForm").submit( validateImage );

    $('#upload-target').on('load', img_upload_completed);

    $('#imageForm input:file').change(function(){
        $('#imageForm input:submit').removeClass('disabled');
    });

    $('#imageForm input:submit').click(function(){
        if (!$(this).hasClass('disabled'))
        {
            $("#overlay").hide();
            $("#imageDrawer").hide();
            $("#imgPreviewContainer").hide();

            $(this).addClass('disabled');
            $('#uploadedImage').attr('src', '');
            $('#submitUpload').addClass('disabled');
        }
    });

    selectCard($('.cardSelected'))

    updateCardList();
    updateMiniPreviews();
});
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var path = require('path');
var fs = require('fs');

var sh = require('shelljs');
var exec = require('../utils/exec');
var _ = require('lodash');

var log = require('../utils/log');
var env = require('../utils/env');
var plugins = require('../utils/plugins');

gulp.task('clean', function () {
  if (fs.existsSync(env.folders.build)) {
    sh.rm('-fr', path.join(env.folders.build, '*'));
  }
  if (fs.existsSync(env.folders.temp)) {
    sh.rm('-fr', path.join(env.folders.temp, '*'));
  }
});

var getAppFiles = function (filter) {
  return [env.folders.app + filter, '!' + env.folders.app + '/forks' + filter];
};

gulp.task('bowerInstall', function () {
  // 用于CI系统时，请加上--ci参数
  return exec('bower', ['install', '--config.interactive=' + !env.args.ci, '--allow-root']).catch(function () {
    log.error("bower install失败，可能网络有问题或存在版本冲突，请手动运行bower install命令来解决它。");
    process.exit(1);
  });

});

gulp.task('sass', function () {
  return gulp.src(env.folders.app + '/styles/**/*.scss')
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.sass({
      includePaths: [
        env.folders.app + '/styles'
      ],
      imagePath: env.folders.app + '/images',
      onError: function (err) {
        if (err.code === 1) {
          log.error(err.file + ' @ ' + err.line + ':' + err.column + '. error: ' + err.message);
        } else {
          log.message(err.file + ' @ ' + err.line + ':' + err.column + '. level: ' + err.code + ', message:' + err.message)
        }
      }
    }))
    .pipe(plugins.sourcemaps.write())
    .pipe(gulp.dest(env.folders.temp + '/app'));
});

var filesOf = function (extensionName) {
  return [
    env.folders.app + '/**/*.' + extensionName,
    env.folders.test + '/**/*.' + extensionName,
    env.folders.mock + '/**/*.' + extensionName,
    '!' + env.folders.mock + '/node_modules/**/*.' + extensionName
  ];
};

gulp.task('coffee', function () {
  return gulp.src(filesOf('coffee'), {base: env.folders.project})
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.coffee({bare: true}))
    .on('error', log.error)
    .pipe(plugins.sourcemaps.write())
    .pipe(gulp.dest(env.folders.temp));
});

gulp.task('es6', function () {
  return gulp.src(filesOf('es6'), {base: env.folders.project})
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.es6())
    .on('error', log.error)
    .pipe(plugins.sourcemaps.write())
    .pipe(plugins.rename({
      extname: ".js"
    }))
    .pipe(gulp.dest(env.folders.temp));
});

gulp.task('typescript', function () {
  return gulp.src(filesOf('ts').concat(['!' + env.folders.project + '/**/*.d.ts']), {base: env.folders.project})
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.typescript({
      declarationFiles: true
    })).js
    .pipe(plugins.sourcemaps.write())
    .pipe(gulp.dest(env.folders.temp));
});

gulp.task('lint', function () {
  // 第三方库的js不进行lint
  return gulp.src(filesOf('js'))
    .pipe(plugins.plumber())
    .pipe(plugins.jshint())
    .pipe(plugins.jshint.reporter('jshint-stylish'));
});

gulp.task('webFont', function () {
  var fontName = 'app-icons';
  return gulp.src(env.folders.app + '/icons/**/*.svg')
    .pipe(plugins.plumber())
    // gulp-iconfont/gulp-iconfont-css不能正确处理appendCodepoints的情况，所以自己写了一个webFontScss插件
    .pipe(plugins.webFontScss({
      fontName: fontName, // required
      fontPath: 'fonts/',
      normalize: true,
      scss: {
        base: env.folders.temp + '/app/fonts', // 必须和dest中的路径相同，否则_icons.scss写入的位置会有问题
        templateFile: env.folders.frontJet + '/app/assets/app/_icons.scss.tpl',
        filename: env.folders.app + '/styles/_icons.scss'
      },
      appendCodepoints: true // 保留原有代码位，以免新版本刚发布时css对应的图标混乱
    }))
    .pipe(gulp.dest(env.folders.temp + '/app/fonts'));
});

gulp.task('wireBowerJs', ['bowerInstall'], function () {
  // 把对bower js的引用注入到html文件中
  return gulp.src(env.folders.app + '/*.html')
    .pipe(plugins.plumber())
    .pipe(plugins.wiredep({
      directory: env.folders.library,
      dependencies: true,
      devDependencies: false,
      fileTypes: {
        html: {
          replace: {
            // 强制使用utf-8格式
            js: '<script src="{{filePath}}" charset="utf-8"></script>'
          }
        }
      }
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('wireBowerScss', ['bowerInstall'], function () {
  return gulp.src(getAppFiles('/**/*.scss'))
    .pipe(plugins.plumber())
    .pipe(plugins.wiredep({
      directory: env.folders.library,
      dependencies: true,
      devDependencies: false
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('wireBower', ['wireBowerJs', 'wireBowerScss']);

var sortByFileName = function (file1, file2) {
  return -file1.relative.localeCompare(file2.relative);
};
gulp.task('wireAppJs', function () {
  // 按照约定优于配置的原则将js文件注入所有根目录下的文件
  var injectJs = function (files) {
    return plugins.inject(files,
      {
        starttag: '<!-- inject:app:js -->',
        relative: true,
        transform: function (filepath, file) {
          // 自己的js统一使用utf-8格式
          return '<script src="' + toPosixPath(file.relative) + '" charset="utf-8"></script>';
        }
      });
  };

  var appFiles = gulp.src(getAppFiles('/**/*.js').concat(['!' + env.folders.app + '/**/*.test.js', '!' + env.folders.temp + '/app/**/*.test.js']), {base: env.folders.app});
  var sortedFiles = appFiles
    .pipe(plugins.sort(sortByFileName))
    .pipe(plugins.angularFileSort());

  return gulp.src(env.folders.app + '/*.html')
    .pipe(plugins.plumber())
    // 整理出文件依赖关系，然后注入
    .pipe(injectJs(sortedFiles))
    .pipe(gulp.dest(env.folders.app));
});

gulp.task('wireAppScss', function () {
  // 按照约定优于配置的原则将scss文件注入所有styles目录下的文件
  var injectScss = function (files) {
    return plugins.inject(files,
      {
        starttag: '// inject:page:scss',
        endtag: '// endinject',
        relative: true,
        transform: function (filepath, file) {
          return '@import "' + toPosixPath(file.relative) + '";';
        }
      });
  };

  var stylesPath = env.folders.app + '/styles';
  var filter = '/**/*.scss';
  // 除了styles中的scss以外，都注入进来
  var appFiles = gulp.src(getAppFiles(filter).concat(['!' + stylesPath + filter]), {base: stylesPath});
  //
  var sortedFiles = appFiles
    .pipe(plugins.sort(sortByFileName));

  return gulp.src(stylesPath + filter)
    .pipe(plugins.plumber())
    // 整理出文件依赖关系，然后注入
    .pipe(injectScss(sortedFiles))
    .pipe(gulp.dest(stylesPath));
});

gulp.task('wireApp', ['wireAppJs', 'wireAppScss']);

gulp.task('copyLibraries', function () {
  var files = plugins.mainBowerFiles();

  var libraryPath = env.folders.project + '/bower_components';
  // js，css交给usemin去处理，中间文件不用拷贝过去
  _.each(['js', 'css', 'scss', 'less', 'coffee', 'ts', 'dart'], function (ext) {
    files.push('!' + libraryPath + '/**/*.' + ext);
  });

  return gulp.src(files, {base: libraryPath})
    .pipe(gulp.dest(env.folders.build + '/bower_components'));
});
gulp.task('copyForks', function () {
  // 如果指定了系统，则将其文件归并到主工程中，否则原样保留
  var forkName = env.args.ios ? 'ios' : env.args.android ? 'android' : 'default';
  return sh.cp('-r', env.folders.app + '/forks/' + forkName + '/*', env.folders.build);
});

var htmlMinifyOptions = {
  conditionals: true, // ie条件注释留着
  empty: true,
  spare: true,
  quotes: true
};

gulp.task('copyViews', function () {
  // 子页面处理下，根目录下的不用管
  return gulp.src([env.folders.app + '/**/*.html', '!' + env.folders.app + '/*.html'], {base: env.folders.app})
    .pipe(plugins.plumber())
    .pipe(plugins.minifyHtml(htmlMinifyOptions))
    .pipe(plugins.ngHtml2js({
      moduleName: 'app',
      declareModule: false
    }))
    .pipe(plugins.concat('templates.js'))
    .pipe(gulp.dest(env.folders.temp + '/shadow'));
});

gulp.task('copyImages', function () {
  return gulp.src(env.folders.app + '/images/**/*.*')
    .pipe(plugins.plumber())
    .pipe(plugins.imagemin())
    .pipe(gulp.dest(env.folders.build + '/images'));
});

gulp.task('copyFonts', function () {
  return gulp.src(env.folders.temp + '/app/fonts')
    .pipe(gulp.dest(env.folders.build));
});

gulp.task('copyIcons', function () {
  return gulp.src(env.folders.app + '/*.ico')
    .pipe(gulp.dest(env.folders.build));
});

gulp.task('buildHome', function () {
  var assets = plugins.useref.assets();
  var isJs = function (file) {
    return /^.*\.js$/.test(file.relative);
  };
  var isAppJs = function (file) {
    return isJs(file) && !/^\w*\/vendor.*\.js$/.test(toPosixPath(file.relative));
  };
  return gulp.src('app/*.html')
    .pipe(plugins.plumber())
    .pipe(assets)
    .pipe(plugins.rev())
    .pipe(plugins.if(isAppJs, plugins.ngAnnotate()))
    .pipe(plugins.if(isJs, plugins.uglify()))
    .pipe(plugins.if('*.css', plugins.csso()))
    .pipe(assets.restore())
    .pipe(plugins.useref())
    .pipe(plugins.revReplace())
    .pipe(gulp.dest(env.folders.build));
});

gulp.task('buildManifest', function () {
  return gulp.src(env.folders.build + '/**/*.*')
    .pipe(plugins.plumber())
    .pipe(plugins.manifest({
      hash: true,
      preferOnline: true,
      network: ['http://*', 'https://*', '*'],
      filename: 'app.manifest',
      exclude: 'app.manifest'
    }));
});

gulp.task('compile', function (done) {
  // 全部串行，以免出现两个并发任务同时操作同一个文件的问题，这些步骤中速度不是最重要的
  plugins.runSequence('clean', 'bowerInstall', 'webFont', 'wireApp', 'wireBower', 'sass', 'coffee', 'es6', 'typescript', done);
});

gulp.task('build', function (done) {
  plugins.runSequence('compile', 'copyForks', 'copyLibraries', 'copyFonts', 'copyImages', 'copyViews',
    'copyIcons', 'buildHome', 'buildManifest', 'preview.reload', done);
});

var path = require('path');
function toPosixPath(fileName) {
  if (!fileName) {
    return fileName;
  }
  return fileName.replace(/\\/g, '/');
}
<commit_msg>加入拷贝assets的功能<commit_after>'use strict';

var gulp = require('gulp');
var path = require('path');
var fs = require('fs');

var sh = require('shelljs');
var exec = require('../utils/exec');
var _ = require('lodash');

var log = require('../utils/log');
var env = require('../utils/env');
var plugins = require('../utils/plugins');

gulp.task('clean', function () {
  if (fs.existsSync(env.folders.build)) {
    sh.rm('-fr', path.join(env.folders.build, '*'));
  }
  if (fs.existsSync(env.folders.temp)) {
    sh.rm('-fr', path.join(env.folders.temp, '*'));
  }
});

var getAppFiles = function (filter) {
  return [env.folders.app + filter, '!' + env.folders.app + '/forks' + filter];
};

gulp.task('bowerInstall', function () {
  // 用于CI系统时，请加上--ci参数
  return exec('bower', ['install', '--config.interactive=' + !env.args.ci, '--allow-root']).catch(function () {
    log.error("bower install失败，可能网络有问题或存在版本冲突，请手动运行bower install命令来解决它。");
    process.exit(1);
  });

});

gulp.task('sass', function () {
  return gulp.src(env.folders.app + '/styles/**/*.scss')
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.sass({
      includePaths: [
        env.folders.app + '/styles'
      ],
      imagePath: env.folders.app + '/images',
      onError: function (err) {
        if (err.code === 1) {
          log.error(err.file + ' @ ' + err.line + ':' + err.column + '. error: ' + err.message);
        } else {
          log.message(err.file + ' @ ' + err.line + ':' + err.column + '. level: ' + err.code + ', message:' + err.message)
        }
      }
    }))
    .pipe(plugins.sourcemaps.write())
    .pipe(gulp.dest(env.folders.temp + '/app'));
});

var filesOf = function (extensionName) {
  return [
    env.folders.app + '/**/*.' + extensionName,
    env.folders.test + '/**/*.' + extensionName,
    env.folders.mock + '/**/*.' + extensionName,
    '!' + env.folders.mock + '/node_modules/**/*.' + extensionName
  ];
};

gulp.task('coffee', function () {
  return gulp.src(filesOf('coffee'), {base: env.folders.project})
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.coffee({bare: true}))
    .on('error', log.error)
    .pipe(plugins.sourcemaps.write())
    .pipe(gulp.dest(env.folders.temp));
});

gulp.task('es6', function () {
  return gulp.src(filesOf('es6'), {base: env.folders.project})
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.es6())
    .on('error', log.error)
    .pipe(plugins.sourcemaps.write())
    .pipe(plugins.rename({
      extname: ".js"
    }))
    .pipe(gulp.dest(env.folders.temp));
});

gulp.task('typescript', function () {
  return gulp.src(filesOf('ts').concat(['!' + env.folders.project + '/**/*.d.ts']), {base: env.folders.project})
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.typescript({
      declarationFiles: true
    })).js
    .pipe(plugins.sourcemaps.write())
    .pipe(gulp.dest(env.folders.temp));
});

gulp.task('lint', function () {
  // 第三方库的js不进行lint
  return gulp.src(filesOf('js'))
    .pipe(plugins.plumber())
    .pipe(plugins.jshint())
    .pipe(plugins.jshint.reporter('jshint-stylish'));
});

gulp.task('webFont', function () {
  var fontName = 'app-icons';
  return gulp.src(env.folders.app + '/icons/**/*.svg')
    .pipe(plugins.plumber())
    // gulp-iconfont/gulp-iconfont-css不能正确处理appendCodepoints的情况，所以自己写了一个webFontScss插件
    .pipe(plugins.webFontScss({
      fontName: fontName, // required
      fontPath: 'fonts/',
      normalize: true,
      scss: {
        base: env.folders.temp + '/app/fonts', // 必须和dest中的路径相同，否则_icons.scss写入的位置会有问题
        templateFile: env.folders.frontJet + '/app/assets/app/_icons.scss.tpl',
        filename: env.folders.app + '/styles/_icons.scss'
      },
      appendCodepoints: true // 保留原有代码位，以免新版本刚发布时css对应的图标混乱
    }))
    .pipe(gulp.dest(env.folders.temp + '/app/fonts'));
});

gulp.task('wireBowerJs', ['bowerInstall'], function () {
  // 把对bower js的引用注入到html文件中
  return gulp.src(env.folders.app + '/*.html')
    .pipe(plugins.plumber())
    .pipe(plugins.wiredep({
      directory: env.folders.library,
      dependencies: true,
      devDependencies: false,
      fileTypes: {
        html: {
          replace: {
            // 强制使用utf-8格式
            js: '<script src="{{filePath}}" charset="utf-8"></script>'
          }
        }
      }
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('wireBowerScss', ['bowerInstall'], function () {
  return gulp.src(getAppFiles('/**/*.scss'))
    .pipe(plugins.plumber())
    .pipe(plugins.wiredep({
      directory: env.folders.library,
      dependencies: true,
      devDependencies: false
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('wireBower', ['wireBowerJs', 'wireBowerScss']);

var sortByFileName = function (file1, file2) {
  return -file1.relative.localeCompare(file2.relative);
};
gulp.task('wireAppJs', function () {
  // 按照约定优于配置的原则将js文件注入所有根目录下的文件
  var injectJs = function (files) {
    return plugins.inject(files,
      {
        starttag: '<!-- inject:app:js -->',
        relative: true,
        transform: function (filepath, file) {
          // 自己的js统一使用utf-8格式
          return '<script src="' + toPosixPath(file.relative) + '" charset="utf-8"></script>';
        }
      });
  };

  var appFiles = gulp.src(getAppFiles('/**/*.js').concat(['!' + env.folders.app + '/**/*.test.js', '!' + env.folders.temp + '/app/**/*.test.js']), {base: env.folders.app});
  var sortedFiles = appFiles
    .pipe(plugins.sort(sortByFileName))
    .pipe(plugins.angularFileSort());

  return gulp.src(env.folders.app + '/*.html')
    .pipe(plugins.plumber())
    // 整理出文件依赖关系，然后注入
    .pipe(injectJs(sortedFiles))
    .pipe(gulp.dest(env.folders.app));
});

gulp.task('wireAppScss', function () {
  // 按照约定优于配置的原则将scss文件注入所有styles目录下的文件
  var injectScss = function (files) {
    return plugins.inject(files,
      {
        starttag: '// inject:page:scss',
        endtag: '// endinject',
        relative: true,
        transform: function (filepath, file) {
          return '@import "' + toPosixPath(file.relative) + '";';
        }
      });
  };

  var stylesPath = env.folders.app + '/styles';
  var filter = '/**/*.scss';
  // 除了styles中的scss以外，都注入进来
  var appFiles = gulp.src(getAppFiles(filter).concat(['!' + stylesPath + filter]), {base: stylesPath});
  //
  var sortedFiles = appFiles
    .pipe(plugins.sort(sortByFileName));

  return gulp.src(stylesPath + filter)
    .pipe(plugins.plumber())
    // 整理出文件依赖关系，然后注入
    .pipe(injectScss(sortedFiles))
    .pipe(gulp.dest(stylesPath));
});

gulp.task('wireApp', ['wireAppJs', 'wireAppScss']);

gulp.task('copyLibraries', function () {
  var files = plugins.mainBowerFiles();

  var libraryPath = env.folders.project + '/bower_components';
  // js，css交给usemin去处理，中间文件不用拷贝过去
  _.each(['js', 'css', 'scss', 'less', 'coffee', 'ts', 'dart'], function (ext) {
    files.push('!' + libraryPath + '/**/*.' + ext);
  });

  return gulp.src(files, {base: libraryPath})
    .pipe(gulp.dest(env.folders.build + '/bower_components'));
});
gulp.task('copyForks', function () {
  // 如果指定了系统，则将其文件归并到主工程中，否则原样保留
  var forkName = env.args.ios ? 'ios' : env.args.android ? 'android' : 'default';
  return sh.cp('-r', env.folders.app + '/forks/' + forkName + '/*', env.folders.build);
});

var htmlMinifyOptions = {
  conditionals: true, // ie条件注释留着
  empty: true,
  spare: true,
  quotes: true
};

gulp.task('copyViews', function () {
  // 子页面处理下，根目录下的不用管
  return gulp.src([env.folders.app + '/**/*.html', '!' + env.folders.app + '/*.html'], {base: env.folders.app})
    .pipe(plugins.plumber())
    .pipe(plugins.minifyHtml(htmlMinifyOptions))
    .pipe(plugins.ngHtml2js({
      moduleName: 'app',
      declareModule: false
    }))
    .pipe(plugins.concat('templates.js'))
    .pipe(gulp.dest(env.folders.temp + '/shadow'));
});

gulp.task('copyAssets', function () {
  return gulp.src(env.folders.app + '/assets/**/*.*')
    .pipe(gulp.dest(env.folders.build + '/assets'));
});

gulp.task('copyImages', function () {
  return gulp.src(env.folders.app + '/images/**/*.*')
    .pipe(plugins.plumber())
    .pipe(plugins.imagemin())
    .pipe(gulp.dest(env.folders.build + '/images'));
});

gulp.task('copyFonts', function () {
  return gulp.src(env.folders.temp + '/app/fonts')
    .pipe(gulp.dest(env.folders.build));
});

gulp.task('copyIcons', function () {
  return gulp.src(env.folders.app + '/*.ico')
    .pipe(gulp.dest(env.folders.build));
});

gulp.task('buildHome', function () {
  var assets = plugins.useref.assets();
  var isJs = function (file) {
    return /^.*\.js$/.test(file.relative);
  };
  var isAppJs = function (file) {
    return isJs(file) && !/^\w*\/vendor.*\.js$/.test(toPosixPath(file.relative));
  };
  return gulp.src('app/*.html')
    .pipe(plugins.plumber())
    .pipe(assets)
    .pipe(plugins.rev())
    .pipe(plugins.if(isAppJs, plugins.ngAnnotate()))
    .pipe(plugins.if(isJs, plugins.uglify()))
    .pipe(plugins.if('*.css', plugins.csso()))
    .pipe(assets.restore())
    .pipe(plugins.useref())
    .pipe(plugins.revReplace())
    .pipe(gulp.dest(env.folders.build));
});

gulp.task('buildManifest', function () {
  return gulp.src(env.folders.build + '/**/*.*')
    .pipe(plugins.plumber())
    .pipe(plugins.manifest({
      hash: true,
      preferOnline: true,
      network: ['http://*', 'https://*', '*'],
      filename: 'app.manifest',
      exclude: 'app.manifest'
    }));
});

gulp.task('compile', function (done) {
  // 全部串行，以免出现两个并发任务同时操作同一个文件的问题，这些步骤中速度不是最重要的
  plugins.runSequence('clean', 'bowerInstall', 'webFont', 'wireApp', 'wireBower', 'sass', 'coffee', 'es6', 'typescript', done);
});

gulp.task('build', function (done) {
  plugins.runSequence('compile', 'copyForks', 'copyLibraries', 'copyFonts', 'copyAssets', 'copyImages', 'copyViews',
    'copyIcons', 'buildHome', 'buildManifest', 'preview.reload', done);
});

var path = require('path');
function toPosixPath(fileName) {
  if (!fileName) {
    return fileName;
  }
  return fileName.replace(/\\/g, '/');
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2018 Google LLC
 *
 * 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.
 */

/**
 * @fileoverview Integrated Development Environment for Code City.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

/**
 * If not otherwise specified, what should /code point at?
 */
Code.DEFAULT = '$';

/**
 * Raw string of selector.
 * E.g. '$.foo["bar"]'
 */
Code.selector = location.search ?
    decodeURIComponent(location.search.substring(1)) : Code.DEFAULT;

/**
 * Got a ping from someone.  Check sessionStorage to see if selector has
 * changed and, if so, propagate ping to subframes.
 * @param {?Event} event Message event, or null if called from popState.
 */
Code.receiveMessage = function(event) {
  // Check to see if the stored values have changed.
  var selector = sessionStorage.getItem(Code.Common.SELECTOR);
  if (selector === Code.selector) {
    return;
  }
  Code.selector = selector;
  if (event) {
    // Change the URL if this is NOT the result of a forwards/back navigation.
    history.pushState(selector, selector,
                      '/code?' + encodeURIComponent(selector));
  }
  // Propagate the ping down the tree of frames.
  try {
    document.getElementById('explorer').contentWindow.postMessage('ping', '*');
  } catch (e) {
    // Maybe explorer frame hasn't loaded yet.
  }
  try {
    document.getElementById('editor').contentWindow.postMessage('ping', '*');
  } catch (e) {
    // Maybe editor frame hasn't loaded yet.
  }
  Code.setTitle();
};

/**
 * User has navigated forwards or backwards.
 * @param {!Event} event History change event.
 */
Code.popState = function(event) {
  var selector = event.state || Code.DEFAULT;
  sessionStorage.setItem(Code.Common.SELECTOR, selector);
  // Attempt to pull the focus away from the explorer's input field.
  // This will allow it to update the displayed selector.
  try {
    document.getElementById('explorer').contentDocument
        .getElementById('input').blur();
  } catch (e) {
    console.log('Unable to blur input: ' + e);
  }
  Code.receiveMessage(null);
};

/**
 * Set the code editor's title.
 */
Code.setTitle = function() {
  var title = Code.selector;
  if (title.length > 36) {
    // Max title length in Chrome is 36 before truncation.
    title = '…' + title.substr(-35);
  }
  document.title = title;
};

if (!window.TEST) {
  Code.setTitle();
  sessionStorage.setItem(Code.Common.SELECTOR, Code.selector);
  window.addEventListener('message', Code.receiveMessage, false);
  window.addEventListener('popstate', Code.popState, false);
}

// Add bridge for SVG editor's clipboard.  This copy allows the clipboard to
// sync across all /code tabs even if the SVG editor isn't currently loaded.
// Copied from /code/SVG-Edit/svgcanvas.js
const CLIPBOARD_ID = 'svgedit_clipboard';

/**
* Flash the clipboard data momentarily on localStorage so all tabs can see.
*/
function flashStorage() {
  const data = sessionStorage.getItem(CLIPBOARD_ID);
  localStorage.setItem(CLIPBOARD_ID, data);
  setTimeout(function() {
    localStorage.removeItem(CLIPBOARD_ID);
  }, 1);
}

/**
* Transfers sessionStorage from one tab to another.
* @param {!Event} event Storage event.
*/
function storageChange(event) {
  if (!event.newValue) return;  // This is a call from removeItem.
  if (event.key === CLIPBOARD_ID + '_startup') {
    // Another tab asked for our sessionStorage.
    localStorage.removeItem(CLIPBOARD_ID + '_startup');
    flashStorage();
  } else if (event.key === CLIPBOARD_ID) {
    // Another tab sent data.
    sessionStorage.setItem(CLIPBOARD_ID, event.newValue);
  }
}

// Listen for changes to localStorage.
window.addEventListener('storage', storageChange, false);
// Ask other tabs for sessionStorage (this is ONLY to trigger event).
localStorage.setItem(CLIPBOARD_ID + '_startup', Math.random());
<commit_msg>Comment update.<commit_after>/**
 * @license
 * Copyright 2018 Google LLC
 *
 * 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.
 */

/**
 * @fileoverview Integrated Development Environment for Code City.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

/**
 * If not otherwise specified, what should /code point at?
 */
Code.DEFAULT = '$';

/**
 * Raw string of selector.
 * E.g. '$.foo["bar"]'
 */
Code.selector = location.search ?
    decodeURIComponent(location.search.substring(1)) : Code.DEFAULT;

/**
 * Got a ping from someone.  Check sessionStorage to see if selector has
 * changed and, if so, propagate ping to subframes.
 * @param {?Event} event Message event, or null if called from popState.
 */
Code.receiveMessage = function(event) {
  // Check to see if the stored values have changed.
  var selector = sessionStorage.getItem(Code.Common.SELECTOR);
  if (selector === Code.selector) {
    return;
  }
  Code.selector = selector;
  if (event) {
    // Change the URL if this is NOT the result of a forwards/back navigation.
    history.pushState(selector, selector,
                      '/code?' + encodeURIComponent(selector));
  }
  // Propagate the ping down the tree of frames.
  try {
    document.getElementById('explorer').contentWindow.postMessage('ping', '*');
  } catch (e) {
    // Maybe explorer frame hasn't loaded yet.
  }
  try {
    document.getElementById('editor').contentWindow.postMessage('ping', '*');
  } catch (e) {
    // Maybe editor frame hasn't loaded yet.
  }
  Code.setTitle();
};

/**
 * User has navigated forwards or backwards.
 * @param {!Event} event History change event.
 */
Code.popState = function(event) {
  var selector = event.state || Code.DEFAULT;
  sessionStorage.setItem(Code.Common.SELECTOR, selector);
  // Attempt to pull the focus away from the explorer's input field.
  // This will allow it to update the displayed selector.
  try {
    document.getElementById('explorer').contentDocument
        .getElementById('input').blur();
  } catch (e) {
    console.log('Unable to blur input: ' + e);
  }
  Code.receiveMessage(null);
};

/**
 * Set the code editor's title.
 */
Code.setTitle = function() {
  var title = Code.selector;
  if (title.length > 36) {
    // Max title length in Chrome is 36 before truncation.
    title = '…' + title.substr(-35);
  }
  document.title = title;
};

if (!window.TEST) {
  Code.setTitle();
  sessionStorage.setItem(Code.Common.SELECTOR, Code.selector);
  window.addEventListener('message', Code.receiveMessage, false);
  window.addEventListener('popstate', Code.popState, false);
}

////////////////////////////////////////////
// Add bridge for SVG editor's clipboard.  This copy allows the clipboard to
// sync across all /code tabs even if the SVG editor isn't currently loaded.
// Copied from /code/SVG-Edit/svgcanvas.js

const CLIPBOARD_ID = 'svgedit_clipboard';

/**
* Flash the clipboard data momentarily on localStorage so all tabs can see.
*/
function flashStorage() {
  const data = sessionStorage.getItem(CLIPBOARD_ID);
  localStorage.setItem(CLIPBOARD_ID, data);
  setTimeout(function() {
    localStorage.removeItem(CLIPBOARD_ID);
  }, 1);
}

/**
* Transfers sessionStorage from one tab to another.
* @param {!Event} event Storage event.
*/
function storageChange(event) {
  if (!event.newValue) return;  // This is a call from removeItem.
  if (event.key === CLIPBOARD_ID + '_startup') {
    // Another tab asked for our sessionStorage.
    localStorage.removeItem(CLIPBOARD_ID + '_startup');
    flashStorage();
  } else if (event.key === CLIPBOARD_ID) {
    // Another tab sent data.
    sessionStorage.setItem(CLIPBOARD_ID, event.newValue);
  }
}

// Listen for changes to localStorage.
window.addEventListener('storage', storageChange, false);
// Ask other tabs for sessionStorage (this is ONLY to trigger event).
localStorage.setItem(CLIPBOARD_ID + '_startup', Math.random());

// End of bridge for SVG editor's clipboard.
////////////////////////////////////////////
<|endoftext|>


<commit_before>'use strict';
var React = require('react');
var _ = require('underscore');
var globals = require('../globals');
var RestMixin = require('../rest').RestMixin;

var VariantCurationHeader = require('./header').VariantCurationHeader;
var VariantCurationActions = require('./actions').VariantCurationActions;
var VariantCurationInterpretation = require('./interpretation').VariantCurationInterpretation;
var SO_terms = require('./interpretation/mapping/SO_term.json');
var genomic_chr_mapping = require('./interpretation/mapping/NC_genomic_chr_format.json');
var external_url_map = globals.external_url_map;
var dbxref_prefix_map = globals.dbxref_prefix_map;
var queryKeyValue = globals.queryKeyValue;
var parseClinvar = require('../../libs/parse-resources').parseClinvar;

// Variant Curation Hub
var VariantCurationHub = React.createClass({
    mixins: [RestMixin],

    getInitialState: function() {
        return {
            variantUuid: queryKeyValue('variant', this.props.href),
            interpretationUuid: queryKeyValue('interpretation', this.props.href),
            interpretation: null,
            editKey: queryKeyValue('edit', this.props.href),
            variantObj: null,
            isLoadingComplete: false,
            ext_myVariantInfo: null,
            ext_ensemblHgvsVEP: null,
            ext_ensemblVEP: null,
            ext_ensemblVariation: null,
            ext_clinvarEutils: null,
            ext_clinVarEsearch: null,
            ext_bustamante: null
        };
    },

    componentDidMount: function() {
        this.getClinVarData(this.state.variantUuid);
        if (this.state.interpretationUuid) {
            this.getRestData('/interpretation/' + this.state.interpretationUuid).then(interpretation => {
                this.setState({interpretation: interpretation});
            });
        }
    },

    // Retrieve the variant object from db with the given uuid
    getClinVarData: function(uuid) {
        return this.getRestData('/variants/' + uuid, null, true).then(response => {
            // The variant object successfully retrieved
            this.setState({variantObj: response});
            this.setState({isLoadingComplete: true});
            // ping out external resources (all async)
            this.fetchMyVariantInfoAndBustamante();
            this.fetchEnsemblVEP();
            this.fetchEnsemblVariation();
            this.fetchEnsemblHGVSVEP();
            this.fetchRefseqData();
            this.fetchClinvarESearch();
        }).catch(function(e) {
            console.log('FETCH CLINVAR ERROR=: %o', e);
        });
    },

    // Retrieve data from MyVariantInfo and Bustamante data
    fetchMyVariantInfoAndBustamante: function() {
        var variant = this.state.variantObj;
        var url = this.props.href_url.protocol + external_url_map['MyVariantInfo'];
        if (variant) {
            // Extract genomic substring from HGVS name whose assembly is GRCh37
            // Both of "GRCh37" and "gRCh37" instances are possibly present in the variant object
            var hgvs_GRCh37 = (variant.hgvsNames.GRCh37) ? variant.hgvsNames.GRCh37 : variant.hgvsNames.gRCh37;
            var NC_genomic = hgvs_GRCh37 ? hgvs_GRCh37.substr(0, hgvs_GRCh37.indexOf(':')) : null;
            // 'genomic_chr_mapping' is defined via requiring external mapping file
            var found = genomic_chr_mapping.GRCh37.find((entry) => entry.GenomicRefSeq === NC_genomic);
            // Format variant_id for use of myvariant.info REST API
            var variant_id = (hgvs_GRCh37 && found) ? found.ChrFormat + hgvs_GRCh37.slice(hgvs_GRCh37.indexOf(':')) : null;
            if (variant_id && variant_id.indexOf('del') > 0) {
                variant_id = variant_id.substring(0, variant_id.indexOf('del') + 3);
            }
            if (variant_id) {
                this.getRestData(url + variant_id).then(response => {
                    this.setState({ext_myVariantInfo: response});
                    // check dbsnfp data for bustamante query
                    var hgvsObj = {};
                    if (response.dbnsfp) {
                        hgvsObj.chrom = (response.dbnsfp.chrom) ? response.dbnsfp.chrom : null;
                        hgvsObj.pos = (response.dbnsfp.hg19.start) ? response.dbnsfp.hg19.start : null;
                        hgvsObj.alt = (response.dbnsfp.alt) ? response.dbnsfp.alt : null;
                        return Promise.resolve(hgvsObj);
                    } else if (response.clinvar) {
                        hgvsObj.chrom = (response.clinvar.chrom) ? response.clinvar.chrom : null;
                        hgvsObj.pos = (response.clinvar.hg19.start) ? response.clinvar.hg19.start : null;
                        hgvsObj.alt = (response.clinvar.alt) ? response.clinvar.alt : null;
                        return Promise.resolve(hgvsObj);
                    }
                }).then(data => {
                    this.getRestData('https:' + external_url_map['Bustamante'] + data.chrom + '/' + data.pos + '/' + data.alt + '/').then(result => {
                        this.setState({ext_bustamante: result});
                    });
                }).catch(function(e) {
                    console.log('MyVariant Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from Ensembl VEP
    fetchEnsemblVEP: function() {
        var variant = this.state.variantObj;
        if (variant) {
            // Extract only the number portion of the dbSNP id
            var numberPattern = /\d+/g;
            var rsid = (variant.dbSNPIds && variant.dbSNPIds.length > 0) ? variant.dbSNPIds[0].match(numberPattern) : null;
            if (rsid) {
                this.getRestData(this.props.href_url.protocol + external_url_map['EnsemblVEP'] + 'rs' + rsid + '?content-type=application/json').then(response => {
                    this.setState({ext_ensemblVEP: response});
                }).catch(function(e) {
                    console.log('VEP Allele Frequency Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from Ensembl Variation
    fetchEnsemblVariation: function() {
        var variant = this.state.variantObj;
        if (variant) {
            // Extract only the number portion of the dbSNP id
            var numberPattern = /\d+/g;
            var rsid = (variant.dbSNPIds && variant.dbSNPIds.length > 0) ? variant.dbSNPIds[0].match(numberPattern) : null;
            if (rsid) {
                this.getRestData(this.props.href_url.protocol + external_url_map['EnsemblVariation'] + 'rs' + rsid + '?content-type=application/json;pops=1;population_genotypes=1').then(response => {
                    this.setState({ext_ensemblVariation: response});
                    //this.parseTGenomesData(response);
                    //this.calculateHighestMAF();
                }).catch(function(e) {
                    console.log('Ensembl Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from Ensembl HGVS VEP
    fetchEnsemblHGVSVEP: function() {
        var variant = this.state.variantObj;
        if (variant) {
            // Due to GRCh38 HGVS notations being used at Ensembl for their VEP API
            // We are extracting genomic substring from HGVS name whose assembly is GRCh38
            // Both of "GRCh38" and "gRCh38" instances are possibly present in the variant object
            var hgvs_GRCh38 = (variant.hgvsNames.GRCh38) ? variant.hgvsNames.GRCh38 : variant.hgvsNames.gRCh38;
            if (hgvs_GRCh38) {
                var NC_genomic = hgvs_GRCh38.substr(0, hgvs_GRCh38.indexOf(':'));
                // 'genomic_chr_mapping' is defined via requiring external mapping file
                var found = genomic_chr_mapping.GRCh38.find((entry) => entry.GenomicRefSeq === NC_genomic);
                // Can't simply filter alpha letters due to the presence of 'chrX' and 'chrY'
                var chrosome = (found.ChrFormat) ? found.ChrFormat.substr(3) : '';
                // Format hgvs_notation for vep/:species/hgvs/:hgvs_notation api
                var hgvs_notation = chrosome + hgvs_GRCh38.slice(hgvs_GRCh38.indexOf(':'));
                if (hgvs_notation) {
                    if (hgvs_notation.indexOf('del') > 0) {
                        hgvs_notation = hgvs_notation.substring(0, hgvs_notation.indexOf('del') + 3);
                    }
                    this.getRestData(this.props.href_url.protocol + external_url_map['EnsemblHgvsVEP'] + hgvs_notation + '?content-type=application/json&hgvs=1&protein=1&xref_refseq=1&domains=1').then(response => {
                        this.setState({ext_ensemblHgvsVEP: response});
                    }).catch(function(e) {
                        console.log('Ensembl Fetch Error=: %o', e);
                    });
                }
            }
        }
    },

    // Retrieve data from Refseq
    fetchRefseqData: function() {
        var variant = this.state.variantObj;
        var url = this.props.href_url.protocol + external_url_map['ClinVarEutils'];
        if (variant) {
            if (variant.clinvarVariantId) {
                this.setState({clinvar_id: variant.clinvarVariantId});
                // Get ClinVar data via the parseClinvar method defined in parse-resources.js
                this.getRestDataXml(url + variant.clinvarVariantId).then(xml => {
                    // Passing 'true' option to invoke 'mixin' function
                    // To extract more ClinVar data for 'Basic Information' tab
                    var variantData = parseClinvar(xml, true);
                    this.setState({ext_clinvarEutils: variantData});
                }).catch(function(e) {
                    console.log('RefSeq Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from ClinVar Eutils
    fetchClinvarESearch: function() {
        var variant = this.state.variantObj;
        if (variant) {
            if (variant.clinvarVariantId) {
                // Get ClinVar data via the parseClinvar method defined in parse-resources.js
                this.getRestDataXml(this.props.href_url.protocol + external_url_map['ClinVarEutils'] + variant.clinvarVariantId).then(xml => {
                    // Passing 'true' option to invoke 'mixin' function
                    // To extract more ClinVar data for codon data
                    var variantData = parseClinvar(xml, true);
                    var clinVarObj = {};
                    clinVarObj.protein_change = variantData.allele.ProteinChange;
                    clinVarObj.gene_symbol = variantData.gene.symbol;
                    if (clinVarObj) {
                        return Promise.resolve(clinVarObj);
                    }
                }).then(clinvar => {
                    var term = clinvar.protein_change.substr(0, clinvar.protein_change.length-1);
                    var symbol = clinvar.gene_symbol;
                    this.getRestData(this.props.href_url.protocol + external_url_map['ClinVarEsearch'] + 'db=clinvar&term=' + term + '*+%5Bvariant+name%5D+and+' + symbol + '&retmode=json').then(result => {
                        this.setState({ext_clinVarEsearch: result});
                    });
                }).catch(function(e) {
                    console.log('ClinVar Fetch Error=: %o', e);
                });
            }
        }
    },

    // method to update the interpretation object and send it down to child components on demand
    updateInterpretationObj: function() {
        this.getRestData('/interpretation/' + this.state.interpretationUuid).then(interpretation => {
            this.setState({interpretation: interpretation});
        });
    },

    render: function() {
        var variantData = this.state.variantObj;
        var interpretation = (this.state.interpretation) ? this.state.interpretation : null;
        var interpretationUuid = (this.state.interpretationUuid) ? this.state.interpretationUuid : null;
        var editKey = this.state.editKey;
        var isLoadingComplete = this.state.isLoadingComplete;
        var session = (this.props.session && Object.keys(this.props.session).length) ? this.props.session : null;

        return (
            <div>
                <VariantCurationHeader variantData={variantData} interpretationUuid={interpretationUuid} session={session} interpretation={interpretation} />
                <VariantCurationActions variantData={variantData} interpretation={interpretation} editKey={editKey} session={session}
                    href_url={this.props.href} updateInterpretationObj={this.updateInterpretationObj} />
                <VariantCurationInterpretation variantData={variantData} interpretation={interpretation} editKey={editKey} session={session}
                    ext_myVariantInfo={this.state.ext_myVariantInfo}
                    ext_ensemblHgvsVEP={this.state.ext_ensemblHgvsVEP}
                    ext_ensemblVEP={this.state.ext_ensemblVEP}
                    ext_ensemblVariation={this.state.ext_ensemblVariation} ext_clinvarEutils={this.state.ext_clinvarEutils}
                    ext_clinVarEsearch={this.state.ext_clinVarEsearch}
                    ext_bustamante={this.state.ext_bustamante}
                    href_url={this.props.href_url} updateInterpretationObj={this.updateInterpretationObj} />
            </div>
        );
    }
});

globals.curator_page.register(VariantCurationHub, 'curator_page', 'variant-central');
<commit_msg>update error console log<commit_after>'use strict';
var React = require('react');
var _ = require('underscore');
var globals = require('../globals');
var RestMixin = require('../rest').RestMixin;

var VariantCurationHeader = require('./header').VariantCurationHeader;
var VariantCurationActions = require('./actions').VariantCurationActions;
var VariantCurationInterpretation = require('./interpretation').VariantCurationInterpretation;
var SO_terms = require('./interpretation/mapping/SO_term.json');
var genomic_chr_mapping = require('./interpretation/mapping/NC_genomic_chr_format.json');
var external_url_map = globals.external_url_map;
var dbxref_prefix_map = globals.dbxref_prefix_map;
var queryKeyValue = globals.queryKeyValue;
var parseClinvar = require('../../libs/parse-resources').parseClinvar;

// Variant Curation Hub
var VariantCurationHub = React.createClass({
    mixins: [RestMixin],

    getInitialState: function() {
        return {
            variantUuid: queryKeyValue('variant', this.props.href),
            interpretationUuid: queryKeyValue('interpretation', this.props.href),
            interpretation: null,
            editKey: queryKeyValue('edit', this.props.href),
            variantObj: null,
            isLoadingComplete: false,
            ext_myVariantInfo: null,
            ext_ensemblHgvsVEP: null,
            ext_ensemblVEP: null,
            ext_ensemblVariation: null,
            ext_clinvarEutils: null,
            ext_clinVarEsearch: null,
            ext_bustamante: null
        };
    },

    componentDidMount: function() {
        this.getClinVarData(this.state.variantUuid);
        if (this.state.interpretationUuid) {
            this.getRestData('/interpretation/' + this.state.interpretationUuid).then(interpretation => {
                this.setState({interpretation: interpretation});
            });
        }
    },

    // Retrieve the variant object from db with the given uuid
    getClinVarData: function(uuid) {
        return this.getRestData('/variants/' + uuid, null, true).then(response => {
            // The variant object successfully retrieved
            this.setState({variantObj: response});
            this.setState({isLoadingComplete: true});
            // ping out external resources (all async)
            this.fetchMyVariantInfoAndBustamante();
            this.fetchEnsemblVEP();
            this.fetchEnsemblVariation();
            this.fetchEnsemblHGVSVEP();
            this.fetchRefseqData();
            this.fetchClinvarESearch();
        }).catch(function(e) {
            console.log('FETCH CLINVAR ERROR=: %o', e);
        });
    },

    // Retrieve data from MyVariantInfo and Bustamante data
    fetchMyVariantInfoAndBustamante: function() {
        var variant = this.state.variantObj;
        var url = this.props.href_url.protocol + external_url_map['MyVariantInfo'];
        if (variant) {
            // Extract genomic substring from HGVS name whose assembly is GRCh37
            // Both of "GRCh37" and "gRCh37" instances are possibly present in the variant object
            var hgvs_GRCh37 = (variant.hgvsNames.GRCh37) ? variant.hgvsNames.GRCh37 : variant.hgvsNames.gRCh37;
            var NC_genomic = hgvs_GRCh37 ? hgvs_GRCh37.substr(0, hgvs_GRCh37.indexOf(':')) : null;
            // 'genomic_chr_mapping' is defined via requiring external mapping file
            var found = genomic_chr_mapping.GRCh37.find((entry) => entry.GenomicRefSeq === NC_genomic);
            // Format variant_id for use of myvariant.info REST API
            var variant_id = (hgvs_GRCh37 && found) ? found.ChrFormat + hgvs_GRCh37.slice(hgvs_GRCh37.indexOf(':')) : null;
            if (variant_id && variant_id.indexOf('del') > 0) {
                variant_id = variant_id.substring(0, variant_id.indexOf('del') + 3);
            }
            if (variant_id) {
                this.getRestData(url + variant_id).then(response => {
                    this.setState({ext_myVariantInfo: response});
                    // check dbsnfp data for bustamante query
                    var hgvsObj = {};
                    if (response.dbnsfp) {
                        hgvsObj.chrom = (response.dbnsfp.chrom) ? response.dbnsfp.chrom : null;
                        hgvsObj.pos = (response.dbnsfp.hg19.start) ? response.dbnsfp.hg19.start : null;
                        hgvsObj.alt = (response.dbnsfp.alt) ? response.dbnsfp.alt : null;
                        return Promise.resolve(hgvsObj);
                    } else if (response.clinvar) {
                        hgvsObj.chrom = (response.clinvar.chrom) ? response.clinvar.chrom : null;
                        hgvsObj.pos = (response.clinvar.hg19.start) ? response.clinvar.hg19.start : null;
                        hgvsObj.alt = (response.clinvar.alt) ? response.clinvar.alt : null;
                        return Promise.resolve(hgvsObj);
                    }
                }).then(data => {
                    this.getRestData('https:' + external_url_map['Bustamante'] + data.chrom + '/' + data.pos + '/' + data.alt + '/').then(result => {
                        this.setState({ext_bustamante: result});
                    });
                }).catch(function(e) {
                    console.log('MyVariant or Bustamante Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from Ensembl VEP
    fetchEnsemblVEP: function() {
        var variant = this.state.variantObj;
        if (variant) {
            // Extract only the number portion of the dbSNP id
            var numberPattern = /\d+/g;
            var rsid = (variant.dbSNPIds && variant.dbSNPIds.length > 0) ? variant.dbSNPIds[0].match(numberPattern) : null;
            if (rsid) {
                this.getRestData(this.props.href_url.protocol + external_url_map['EnsemblVEP'] + 'rs' + rsid + '?content-type=application/json').then(response => {
                    this.setState({ext_ensemblVEP: response});
                }).catch(function(e) {
                    console.log('VEP Allele Frequency Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from Ensembl Variation
    fetchEnsemblVariation: function() {
        var variant = this.state.variantObj;
        if (variant) {
            // Extract only the number portion of the dbSNP id
            var numberPattern = /\d+/g;
            var rsid = (variant.dbSNPIds && variant.dbSNPIds.length > 0) ? variant.dbSNPIds[0].match(numberPattern) : null;
            if (rsid) {
                this.getRestData(this.props.href_url.protocol + external_url_map['EnsemblVariation'] + 'rs' + rsid + '?content-type=application/json;pops=1;population_genotypes=1').then(response => {
                    this.setState({ext_ensemblVariation: response});
                    //this.parseTGenomesData(response);
                    //this.calculateHighestMAF();
                }).catch(function(e) {
                    console.log('Ensembl Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from Ensembl HGVS VEP
    fetchEnsemblHGVSVEP: function() {
        var variant = this.state.variantObj;
        if (variant) {
            // Due to GRCh38 HGVS notations being used at Ensembl for their VEP API
            // We are extracting genomic substring from HGVS name whose assembly is GRCh38
            // Both of "GRCh38" and "gRCh38" instances are possibly present in the variant object
            var hgvs_GRCh38 = (variant.hgvsNames.GRCh38) ? variant.hgvsNames.GRCh38 : variant.hgvsNames.gRCh38;
            if (hgvs_GRCh38) {
                var NC_genomic = hgvs_GRCh38.substr(0, hgvs_GRCh38.indexOf(':'));
                // 'genomic_chr_mapping' is defined via requiring external mapping file
                var found = genomic_chr_mapping.GRCh38.find((entry) => entry.GenomicRefSeq === NC_genomic);
                // Can't simply filter alpha letters due to the presence of 'chrX' and 'chrY'
                var chrosome = (found.ChrFormat) ? found.ChrFormat.substr(3) : '';
                // Format hgvs_notation for vep/:species/hgvs/:hgvs_notation api
                var hgvs_notation = chrosome + hgvs_GRCh38.slice(hgvs_GRCh38.indexOf(':'));
                if (hgvs_notation) {
                    if (hgvs_notation.indexOf('del') > 0) {
                        hgvs_notation = hgvs_notation.substring(0, hgvs_notation.indexOf('del') + 3);
                    }
                    this.getRestData(this.props.href_url.protocol + external_url_map['EnsemblHgvsVEP'] + hgvs_notation + '?content-type=application/json&hgvs=1&protein=1&xref_refseq=1&domains=1').then(response => {
                        this.setState({ext_ensemblHgvsVEP: response});
                    }).catch(function(e) {
                        console.log('Ensembl Fetch Error=: %o', e);
                    });
                }
            }
        }
    },

    // Retrieve data from Refseq
    fetchRefseqData: function() {
        var variant = this.state.variantObj;
        var url = this.props.href_url.protocol + external_url_map['ClinVarEutils'];
        if (variant) {
            if (variant.clinvarVariantId) {
                this.setState({clinvar_id: variant.clinvarVariantId});
                // Get ClinVar data via the parseClinvar method defined in parse-resources.js
                this.getRestDataXml(url + variant.clinvarVariantId).then(xml => {
                    // Passing 'true' option to invoke 'mixin' function
                    // To extract more ClinVar data for 'Basic Information' tab
                    var variantData = parseClinvar(xml, true);
                    this.setState({ext_clinvarEutils: variantData});
                }).catch(function(e) {
                    console.log('RefSeq Fetch Error=: %o', e);
                });
            }
        }
    },

    // Retrieve data from ClinVar Eutils
    fetchClinvarESearch: function() {
        var variant = this.state.variantObj;
        if (variant) {
            if (variant.clinvarVariantId) {
                // Get ClinVar data via the parseClinvar method defined in parse-resources.js
                this.getRestDataXml(this.props.href_url.protocol + external_url_map['ClinVarEutils'] + variant.clinvarVariantId).then(xml => {
                    // Passing 'true' option to invoke 'mixin' function
                    // To extract more ClinVar data for codon data
                    var variantData = parseClinvar(xml, true);
                    var clinVarObj = {};
                    clinVarObj.protein_change = variantData.allele.ProteinChange;
                    clinVarObj.gene_symbol = variantData.gene.symbol;
                    if (clinVarObj) {
                        return Promise.resolve(clinVarObj);
                    }
                }).then(clinvar => {
                    var term = clinvar.protein_change.substr(0, clinvar.protein_change.length-1);
                    var symbol = clinvar.gene_symbol;
                    this.getRestData(this.props.href_url.protocol + external_url_map['ClinVarEsearch'] + 'db=clinvar&term=' + term + '*+%5Bvariant+name%5D+and+' + symbol + '&retmode=json').then(result => {
                        this.setState({ext_clinVarEsearch: result});
                    });
                }).catch(function(e) {
                    console.log('ClinVar Fetch Error=: %o', e);
                });
            }
        }
    },

    // method to update the interpretation object and send it down to child components on demand
    updateInterpretationObj: function() {
        this.getRestData('/interpretation/' + this.state.interpretationUuid).then(interpretation => {
            this.setState({interpretation: interpretation});
        });
    },

    render: function() {
        var variantData = this.state.variantObj;
        var interpretation = (this.state.interpretation) ? this.state.interpretation : null;
        var interpretationUuid = (this.state.interpretationUuid) ? this.state.interpretationUuid : null;
        var editKey = this.state.editKey;
        var isLoadingComplete = this.state.isLoadingComplete;
        var session = (this.props.session && Object.keys(this.props.session).length) ? this.props.session : null;

        return (
            <div>
                <VariantCurationHeader variantData={variantData} interpretationUuid={interpretationUuid} session={session} interpretation={interpretation} />
                <VariantCurationActions variantData={variantData} interpretation={interpretation} editKey={editKey} session={session}
                    href_url={this.props.href} updateInterpretationObj={this.updateInterpretationObj} />
                <VariantCurationInterpretation variantData={variantData} interpretation={interpretation} editKey={editKey} session={session}
                    ext_myVariantInfo={this.state.ext_myVariantInfo}
                    ext_ensemblHgvsVEP={this.state.ext_ensemblHgvsVEP}
                    ext_ensemblVEP={this.state.ext_ensemblVEP}
                    ext_ensemblVariation={this.state.ext_ensemblVariation} ext_clinvarEutils={this.state.ext_clinvarEutils}
                    ext_clinVarEsearch={this.state.ext_clinVarEsearch}
                    ext_bustamante={this.state.ext_bustamante}
                    href_url={this.props.href_url} updateInterpretationObj={this.updateInterpretationObj} />
            </div>
        );
    }
});

globals.curator_page.register(VariantCurationHub, 'curator_page', 'variant-central');
<|endoftext|>


<commit_before>var nsGmx = nsGmx || {};
nsGmx.Utils = nsGmx.Utils || {};

nsGmx.Utils.getMirrorExtension = function(mirrors) {
    for (var mirror in mirrors) {
        if (
            mirrors.hasOwnProperty(mirror) &&
            window.location.host.indexOf(mirror) !== -1
        ) {
            return mirrors[mirror];
        }
    }
    return {};
}
<commit_msg>fix type error<commit_after>var nsGmx = nsGmx || {};
nsGmx.Utils = nsGmx.Utils || {};

nsGmx.Utils.getMirrorExtension = function(mirrors) {
    for (var mirror in mirrors) {
        if (
            mirrors.hasOwnProperty(mirror) &&
            window.location.host.indexOf(mirror) !== -1
        ) {
            return mirrors[mirror];
        }
    }
    return {};
};
<|endoftext|>


<commit_before>'use strict';

angular.module('Frontend.Venta', ['ngRoute','angular-jwt','angular-storage','html2canvas','pdfmake'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/venta', {
    templateUrl: 'venta/venta.html',
    controller: 'VentaController'
  });
}])

.controller('VentaController', function($scope, store, jwtHelper, $http, backendAPIservice, $location) {
    $scope.terminado=false;
    $scope.contado=true;
    $scope.cliente=1;
    $scope.base21=0.00;
    $scope.iva21=0.00;
    $scope.base10=0.00;
    $scope.iva10=0.00;
    $scope.base4=0.00;
    $scope.iva4=0.00;
    $scope.total=0.00;
    $scope.articulopr;
    $scope.respuesta;
    $scope.error;
    $scope.codigo;
    $scope.cero=0;
    $scope.prueba;
    $scope.activo;
    $scope.numventa;

    $scope.listaVenta = [];
    $scope.listaProducto = [];
    $scope.listaSocio = [];
    $scope.listaTipo = [];

    if(store.get('token')){
      var token = store.get('token');
      if(!jwtHelper.isTokenExpired(token))
      {
        backendAPIservice.getProductos().success(function (recibe) {
          var productosArray = recibe.response.productos;
          console.log(JSON.stringify(productosArray));
          $scope.listaProducto = productosArray;
          store.set('token',recibe.response.token);

        });

        backendAPIservice.getClientes().success(function (recibe) {
          var sociosArray = recibe.response.socios;
          console.log(JSON.stringify(sociosArray));
          $scope.listaSocio = sociosArray;
          store.set('token',recibe.response.token);
        });

        backendAPIservice.getTipos().success(function (recibe) {
          var tiposArray = recibe.response.tipos;
          console.log(JSON.stringify(tiposArray));
          $scope.listaTipo = tiposArray;
          store.set('token',recibe.response.token);
        });
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    }
    else
    {
      store.remove('token');
      store.set('nombre', "Sin conexion");
      $location.path("/login");
    }

    $scope.Aniadir=function(pid, pnombre, pprecio, piva)
    {
      var elemento;
      var anadido=false;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].id == pid) {
          $scope.listaVenta[elemento].cantidad = $scope.listaVenta[elemento].cantidad+1;
          anadido=true;
        }
      }
      if(anadido==false)
      {
        $scope.listaVenta.push({id:pid, nombre:pnombre, precio:pprecio, iva:piva, cantidad:1 });
      }
      $scope.Totales();
    };

    $scope.clienteElegido=function(value) {
      if($scope.cliente==1){ $scope.contado=true; }
      if (value.id==$scope.cliente){
        return true;
      } else {
        return false;
      }
    };

    $scope.Borrar=function(index) {
      $scope.listaVenta.splice(index, 1);
      $scope.Totales();
    };

    $scope.Totales=function() {
      var elemento;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].iva=="21") {
         $scope.base21 += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva21 = ($scope.base21 * 21.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==10) {
         $scope.base10  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva10 = ($scope.base10 * 10.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==4) {
         $scope.base4  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva4 = ($scope.base4 * 4.00 )/100.00;
        };
      }
      $scope.total = $scope.base21 + $scope.iva21 + $scope.base10 + $scope.iva10 + $scope.base4 + $scope.iva4;
    };

    $scope.Finalizar=function() {
      backendAPIservice.postVenta($scope.cliente, $scope.contado, $scope.listaVenta).success(function(recibe){
        var respuesta1 = recibe.response.respuesta;
        var numventa = recibe.response.venta;
        console.log(JSON.stringify(respuesta1));
        console.log(JSON.stringify(numventa));
        $scope.respuesta = respuesta1;
        $scope.numventa = numventa;
        if(recibe.code==0) store.set('token',recibe.response.token);
        $scope.terminado=true;
      });
    };

    $scope.Continuar=function() {
      html2canvas(document.getElementById('imprimeesto'), {
        onrendered: function (canvas) {
          var data = canvas.toDataURL();
          var docDefinition = {
            content: [{
              image: data,
              width: 500,
            }]
          };
          pdfMake.createPdf(docDefinition).download("Score_Details.pdf");
        }
      })
      $scope.terminado=false;
      $scope.contado=true;
      $scope.cliente=1;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      $scope.total=0.00;
      $scope.articulopr;
      $scope.respuesta;
      $scope.error;
      $scope.codigo;
      $scope.cero=0;
      $scope.prueba;
      $scope.activo;

      $scope.listaVenta = [];
      $scope.listaProducto = [];
      $scope.listaSocio = [];
      $scope.listaTipo = [];

      if(store.get('token')){
        var token = store.get('token');
        if(!jwtHelper.isTokenExpired(token))
        {
          backendAPIservice.getProductos().success(function (recibe) {
            var productosArray = recibe.response.productos;
            console.log(JSON.stringify(productosArray));
            $scope.listaProducto = productosArray;
            store.set('token',recibe.response.token);

          });

          backendAPIservice.getClientes().success(function (recibe) {
            var sociosArray = recibe.response.socios;
            console.log(JSON.stringify(sociosArray));
            $scope.listaSocio = sociosArray;
            store.set('token',recibe.response.token);
          });

          backendAPIservice.getTipos().success(function (recibe) {
            var tiposArray = recibe.response.tipos;
            console.log(JSON.stringify(tiposArray));
            $scope.listaTipo = tiposArray;
            store.set('token',recibe.response.token);
          });
        }
        else
        {
          store.remove('token');
          store.set('nombre', "Sin conexion");
          $location.path("/login");
        }
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    };
});
<commit_msg>20160904-1949<commit_after>'use strict';

angular.module('Frontend.Venta', ['ngRoute','angular-jwt','angular-storage','html2canvas','pdfmake'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/venta', {
    templateUrl: 'venta/venta.html',
    controller: 'VentaController'
  });
}])

.controller('VentaController', function($scope, store, jwtHelper, $http, backendAPIservice, $location) {
    $scope.terminado=false;
    $scope.contado=true;
    $scope.cliente=1;
    $scope.base21=0.00;
    $scope.iva21=0.00;
    $scope.base10=0.00;
    $scope.iva10=0.00;
    $scope.base4=0.00;
    $scope.iva4=0.00;
    $scope.total=0.00;
    $scope.articulopr;
    $scope.respuesta;
    $scope.error;
    $scope.codigo;
    $scope.cero=0;
    $scope.prueba;
    $scope.activo;
    $scope.numventa;

    $scope.listaVenta = [];
    $scope.listaProducto = [];
    $scope.listaSocio = [];
    $scope.listaTipo = [];

    if(store.get('token')){
      var token = store.get('token');
      if(!jwtHelper.isTokenExpired(token))
      {
        backendAPIservice.getProductos().success(function (recibe) {
          var productosArray = recibe.response.productos;
          console.log(JSON.stringify(productosArray));
          $scope.listaProducto = productosArray;
          store.set('token',recibe.response.token);

        });

        backendAPIservice.getClientes().success(function (recibe) {
          var sociosArray = recibe.response.socios;
          console.log(JSON.stringify(sociosArray));
          $scope.listaSocio = sociosArray;
          store.set('token',recibe.response.token);
        });

        backendAPIservice.getTipos().success(function (recibe) {
          var tiposArray = recibe.response.tipos;
          console.log(JSON.stringify(tiposArray));
          $scope.listaTipo = tiposArray;
          store.set('token',recibe.response.token);
        });
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    }
    else
    {
      store.remove('token');
      store.set('nombre', "Sin conexion");
      $location.path("/login");
    }

    $scope.Aniadir=function(pid, pnombre, pprecio, piva)
    {
      var elemento;
      var anadido=false;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].id == pid) {
          $scope.listaVenta[elemento].cantidad = $scope.listaVenta[elemento].cantidad+1;
          anadido=true;
        }
      }
      if(anadido==false)
      {
        $scope.listaVenta.push({id:pid, nombre:pnombre, precio:pprecio, iva:piva, cantidad:1 });
      }
      $scope.Totales();
    };

    $scope.clienteElegido=function(value) {
      if($scope.cliente==1){ $scope.contado=true; }
      if (value.id==$scope.cliente){
        return true;
      } else {
        return false;
      }
    };

    $scope.Borrar=function(index) {
      $scope.listaVenta.splice(index, 1);
      $scope.Totales();
    };

    $scope.Totales=function() {
      var elemento;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      for(elemento in $scope.listaVenta) {
        if($scope.listaVenta[elemento].iva=="21") {
         $scope.base21 += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva21 = ($scope.base21 * 21.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==10) {
         $scope.base10  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva10 = ($scope.base10 * 10.00 )/100.00;
        };
        if($scope.listaVenta[elemento].iva==4) {
         $scope.base4  += ($scope.listaVenta[elemento].precio * $scope.listaVenta[elemento].cantidad);
         $scope.iva4 = ($scope.base4 * 4.00 )/100.00;
        };
      }
      $scope.total = $scope.base21 + $scope.iva21 + $scope.base10 + $scope.iva10 + $scope.base4 + $scope.iva4;
    };

    $scope.Finalizar=function() {
      backendAPIservice.postVenta($scope.cliente, $scope.contado, $scope.listaVenta).success(function(recibe){
        var respuesta1 = recibe.response.respuesta;
        var numventa = recibe.response.venta;
        console.log(JSON.stringify(respuesta1));
        console.log(JSON.stringify(numventa));
        $scope.respuesta = respuesta1;
        $scope.numventa = numventa;
        if(recibe.code==0) store.set('token',recibe.response.token);
        $scope.terminado=true;
      });
    };

    $scope.Continuar=function() {
      /*html2canvas(document.getElementById('imprimeesto'), {
        onrendered: function (canvas) {
          var data = canvas.toDataURL();
          var docDefinition = {
            content: [{
              image: data,
              width: 500,
            }]
          };
          pdfMake.createPdf(docDefinition).download("Score_Details.pdf");
        }
      })*/
      $scope.terminado=false;
      $scope.contado=true;
      $scope.cliente=1;
      $scope.base21=0.00;
      $scope.iva21=0.00;
      $scope.base10=0.00;
      $scope.iva10=0.00;
      $scope.base4=0.00;
      $scope.iva4=0.00;
      $scope.total=0.00;
      $scope.articulopr;
      $scope.respuesta;
      $scope.error;
      $scope.codigo;
      $scope.cero=0;
      $scope.prueba;
      $scope.activo;

      $scope.listaVenta = [];
      $scope.listaProducto = [];
      $scope.listaSocio = [];
      $scope.listaTipo = [];

      if(store.get('token')){
        var token = store.get('token');
        if(!jwtHelper.isTokenExpired(token))
        {
          backendAPIservice.getProductos().success(function (recibe) {
            var productosArray = recibe.response.productos;
            console.log(JSON.stringify(productosArray));
            $scope.listaProducto = productosArray;
            store.set('token',recibe.response.token);

          });

          backendAPIservice.getClientes().success(function (recibe) {
            var sociosArray = recibe.response.socios;
            console.log(JSON.stringify(sociosArray));
            $scope.listaSocio = sociosArray;
            store.set('token',recibe.response.token);
          });

          backendAPIservice.getTipos().success(function (recibe) {
            var tiposArray = recibe.response.tipos;
            console.log(JSON.stringify(tiposArray));
            $scope.listaTipo = tiposArray;
            store.set('token',recibe.response.token);
          });
        }
        else
        {
          store.remove('token');
          store.set('nombre', "Sin conexion");
          $location.path("/login");
        }
      }
      else
      {
        store.remove('token');
        store.set('nombre', "Sin conexion");
        $location.path("/login");
      }
    };
});
<|endoftext|>