<commit_before>/* jquery.focus.js start */
(function(root, factory) {

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports)
      module.exports = factory(global.$);
    exports = factory(global.$);
  } else {
    factory(root.$);
  }

}(this, function($) {

  $.fn.focusBegin = function() {
    return this.each(function() {
      var element = $(this)[0];

      if ($(this).is('textarea')) {
        element.focus();
        element.setSelectionRange(0, 0);
      } else if ($(this).is('input')) {
        element.selectionStart = 0;
        element.selectionEnd = 0;
        element.focus()
      } else {
        var range = document.createRange();
        var selection = window.getSelection();
        range.selectNodeContents(element);
        range.collapse(true);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    });
  };

  $.fn.focusEnd = function() {
    return this.each(function() {
      var element = $(this)[0];

      if ($(this).is('textarea')) {
        element.focus();
        element.setSelectionRange($(this).val().length, $(this).val().length);
      } else if ($(this).is('input')) {
        element.selectionStart = element.value.length;
        element.selectionEnd = element.value.length;
        element.focus();
      } else {
        var range = document.createRange();
        var selection = window.getSelection();
        range.selectNodeContents(element);
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    });
  };

}));
/* jquery.focus.js end */

var replyTo = function(username) {
    var atString = '@' + username + "\u00a0", editorName, comment, oldContent, newContent;
    if($('.wysibb-body').length>0) {
        editorName = 'wysibb';
        comment = $('.wysibb-body');
        oldContent = comment.text();
        if(oldContent.length == 0) {
            $('#editor').insertAtCursor(atString);
        } else if ( oldContent.length>0 && oldContent != atString ) {
            $('#editor').insertAtCursor('
'+atString);
        }
        scrollToAnchor(comment);
        return;
    } else if($('.simditor-body').length>0) {
        editorName = 'simditor';
        comment = $('.simditor-body');
        oldContent = comment.html();
        oldText = comment.text();
    } else {
        editorName = 'smd';
        comment = $('#editor');
        oldContent = comment.val();
    }

    newContent = '';
    scrollToAnchor(comment);
    if( editorName == 'smd') {
        if(oldContent.length > 0){
            if (oldContent != atString) {
                newContent = oldContent + "\n" + atString;
            }
        } else {
            newContent = atString;
        }
        comment.val(newContent);
    } else {
        if(oldText.length>0){
            if (oldText != atString) {
                newContent = oldContent + "
" + atString;
            }
        } else {
            newContent = atString;
        }
        comment.html(newContent);
    }
    comment.focusEnd();
}

var insertAtCursor= function(target, text) {
    var postion = target.selection('getPos');
    target.selection('insert',{text: text, mode: 'after'}).selection('setPos', {start: postion.end+text.length, end: postion.end+text.length});
}

var scrollToAnchor = function(anchor) {
    var fixedBar = $('.navbar-fixed-top');
    var fixedBarHeight = 0;
    if (fixedBar.length > 0) {
        fixedBarHeight = fixedBar.height();
    }
    if(anchor.length > 0){
        var t = anchor.offset().top - fixedBarHeight;
        $("html,body").animate({scrollTop : t}, {queue : false});
    }
}

var chooseNode = function(node) {
    $(".nodes-select2").val(node).trigger("change");
}

$(function(){
    var anchor = window.location.hash;
    if (anchor) {
        scrollToAnchor($(anchor));
    }
});

$(function(){
    $('.link-external a[href^="http"]')
        .not('[href*="'+location.hostname+'"]')
        .attr({target:"_blank"})
        .addClass("external");
});

$(function(){
    $('img.lazy').lazyload();
});

$(function(){

    if ($('.content').length>0) {
        var min=12, max=18;
        var elm = $('.content');
        var size = elm.css('fontSize').replace('px', '');

        $('.fontsize-plus').click(function() {
            if (size<max) {
                size++;
                elm.css({'fontSize' : size});
            }
            return false;
        });

        $('.fontsize-minus').click(function() {
            if (size>min) {
                size--;
                elm.css({'fontSize' : size});
            }
            return false;
        });
    }
});

$(function(){
    $('input#q').focus(function(){
        $(this).animate({width: "250"}, 'fast');
    })
    $('input#q').blur(function(){
        $(this).animate({width: "180"}, 'fast');
    })
});

$(function(){
    $('.navi-nodes-add').click(function(e) {
        e.preventDefault();
        if($(".navi-nodes tr").length == 1) {
            $(".navi-nodes tr .navi-nodes-del").show();
        }
        var last = $('.navi-nodes tr:last-child');
        var id = parseInt(last.attr('id').replace('node_', ''))+1;
        var newNode = last.clone(true).attr('id', 'node_'+id);
        newNode.find('.node-id').val('').attr('id', 'navinode-'+id+'-node_id').attr('name', 'NaviNode['+id+'][node_id]');
        newNode.find('.visible').prop('checked', false).attr('id', 'navinode-'+id+'-visible').siblings('input').addBack().attr('name', 'NaviNode['+id+'][visible]');
        newNode.find('.sortid').val('').attr('id', 'navinode-'+id+'-sortid').attr('name', 'NaviNode['+id+'][sortid]');
        $('.navi-nodes').append(newNode);
    });
    $('.navi-nodes-del').on("click", function () {
        $(this).closest('tr').remove();
        if($(".navi-nodes tr").length == 1) {
            $(".navi-nodes tr .navi-nodes-del").hide();
        }
    });
});

$(function(){
    var authInfo = {
        clientId: {qq:'appid', weibo:'App Key'},
        clientSecret: {qq:'appkey', weibo:'App Secret'},
    };

    if($(".auth-items div.auth-item").length == 1) {
        $(".auth-items div.auth-item .auth-item-del").hide();
    }

    $('.auth-item-add').click(function(e) {
        e.preventDefault();
        if($(".auth-items div.auth-item").length == 1) {
            $(".auth-items div.auth-item .auth-item-del").show();
        }
        var last = $('.auth-items div.auth-item').last();
        var id = parseInt(last.attr('id').replace('auth_', ''))+1;
        var newNode = last.clone(true).attr('id', 'auth_'+id);
        newNode.find('.auth-item-id').text('Account'+id);
        newNode.find('.auth-key').each(function(index, el){
            $(el).attr('id', 'setting-'+id+'-'+index+'-key').attr('name', 'Setting['+id+']'+'['+index+'][key]');
        });
        newNode.find('.auth-value').each(function(index, el){
            $(el).val('').attr('id', 'setting-'+id+'-'+index+'-value').attr('name', 'Setting['+id+']'+'['+index+'][value]');
        });
        newNode.find('.auth-index').val(0);
        newNode.find('.auth-sortid').val( parseInt($('.auth-sortid', last).val())+1 );
        $('.auth-items').append(newNode);
    });
    $('.auth-item-del').on("click", function () {
        $(this).closest('div.auth-item').remove();
        if($(".auth-items div.auth-item").length == 1) {
            $(".auth-items div.auth-item .auth-item-del").hide();
        }
    });
    $('.auth-type').on('change', function(){
        type = $(this).val();
        authItem = $(this).closest('.auth-item');

        $('.auth-item-id', authItem).text(type);
        $('.auth-title', authItem).val( authInfo['title'][type]===undefined?'Login with '+type:authInfo['title'][type] );
        $('.auth-clientId', authItem).closest('div').siblings('label').text( authInfo['clientId'][type]===undefined?'clientId':authInfo['clientId'][type] );
        $('.auth-clientSecret', authItem).closest('div').siblings('label').text( authInfo['clientSecret'][type]===undefined?'clientSecret':authInfo['clientSecret'][type] );
    });
});

$(function(){
    $('#exampleModal').on('show.bs.modal', function (event) {
      var button = $(event.relatedTarget);
      var modal = $(this);
      modal.find('.thanks-to').text(button.data('author'));
      modal.find('.good').attr('id', button.attr('id'));
    });
    $('body').on('click', '.good', function(e) {
        self = $(this);
        params = self.attr('id').split('-');
        thanks = $('input.thanks-author:checked').prop("checked")===true?1:0;
        $.ajax({
            url: baseUrl+'/service/good',
            type: "POST",
            data: { type:params[1], id:params[2], thanks:thanks },
            success: function (data) {
                if(data.result == 1) {
                    $('#'+self.attr('id')+' .good-num').text(data.count);
                } else {
                    alert(data.msg);
                }
                $('#exampleModal').modal('hide');
            }
        });
    });
});

$(function(){
    $('body').on('click', '.favorite', function(e) {
        var title = {
            'favorite':{'user':'Unfollow', 'topic':'Cancel Favorite', 'node':'Cancel Favorite'},
            'unfavorite':{user:'Follow', topic:'Favorite', node:'Favorite'}
        };
        self = $(this);
        params = self.attr('params').split(' ');
        action = params[0];
        type = params[1];
        id = params[2];
        $.ajax({
            url: baseUrl+'/service/'+action,
            type: "POST",
            data: { type:type, id:id },
            success: function (data) {
                if(data.result == 1) {
                    count = $(".favorite-num", self).text();
                    if (action == 'favorite') {
                        count = count == ''?1:(parseInt(count) + 1);
                        $(".far", self).removeClass('far').addClass('fas');
                        $(self).attr({'title':title[action][type], 'params':'unfavorite '+type+' '+id});
                    } else {
                        count = (count == '' || count=='1')?'':(parseInt(count) - 1);
                        $(".fas", self).removeClass('fas').addClass('far');
                        $(self).attr({'title':title[action][type], 'params':'favorite '+type+' '+id});
                    }
                    $(".favorite-num", self).text(count);
                    $(".favorite-name", self).text(title[action][type]);
                } else {
                    alert(data.msg);
                }
            }
        });
    });
});
$(function(){
    $('.img-zoom img.lazy').each(function( index ) {
        if ( $(this).parents('a').length == 0 ) {
            href = $(this).attr('data-original')?$(this).attr('data-original'):$(this).attr('src');
            $(this).wrap('');
        }
    });
});

$(function(){
    var pocounter;
    $("*[data-poload]").on("mouseenter", function () {
            var _this = this;
            $.get($(_this).data('poload'),function(d) {
                $(_this).popover({container: 'body', trigger: "manual" , html: true, animation:false, content: d}).popover('show');
            });

            // clear the counter
            clearTimeout(pocounter);

            // start new timeout to show popover
            pocounter = setTimeout(function(){
                if($(_this).is(':hover'))
                {
                    $(_this).popover("show");
                }
                $(".popover").on("mouseleave", function () {
                    $(_this).popover('destroy');
                });
            }, 400);

        }).on("mouseleave", function () {
            var _this = this;
            setTimeout(function () {
                if (!$(".popover:hover").length) {
                    $(_this).popover("destroy");
                }
            }, 300);
    });
});

$(function(){
    $("#weixinmp").popover({
        html: true,
        placement: 'left',
        trigger: 'manual',
        content: '

',
        title : '微信扫一扫 <button type="button" id="weixinmp-close" class="popover-close close">×</button>'
    }).on('shown.bs.popover', function(e){
        var popover = $(this);
        $(this).parent().find('div.popover .popover-close').on('click', function(e){
          popover.popover('hide');
        });
    });

    $("#weixinmp").click(function () {
        $(this).popover('show');
        $("#weixin-qrcode").qrcode({width: 128,height: 128,text: $(this).attr('link')});
    });
});
<commit_msg>bug fix<commit_after>/* jquery.focus.js start */
(function(root, factory) {

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports)
      module.exports = factory(global.$);
    exports = factory(global.$);
  } else {
    factory(root.$);
  }

}(this, function($) {

  $.fn.focusBegin = function() {
    return this.each(function() {
      var element = $(this)[0];

      if ($(this).is('textarea')) {
        element.focus();
        element.setSelectionRange(0, 0);
      } else if ($(this).is('input')) {
        element.selectionStart = 0;
        element.selectionEnd = 0;
        element.focus()
      } else {
        var range = document.createRange();
        var selection = window.getSelection();
        range.selectNodeContents(element);
        range.collapse(true);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    });
  };

  $.fn.focusEnd = function() {
    return this.each(function() {
      var element = $(this)[0];

      if ($(this).is('textarea')) {
        element.focus();
        element.setSelectionRange($(this).val().length, $(this).val().length);
      } else if ($(this).is('input')) {
        element.selectionStart = element.value.length;
        element.selectionEnd = element.value.length;
        element.focus();
      } else {
        var range = document.createRange();
        var selection = window.getSelection();
        range.selectNodeContents(element);
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    });
  };

}));
/* jquery.focus.js end */

var replyTo = function(username) {
    var atString = '@' + username + "\u00a0", editorName, comment, oldContent, newContent;
    if($('.wysibb-body').length>0) {
        editorName = 'wysibb';
        comment = $('.wysibb-body');
        oldContent = comment.text();
        if(oldContent.length == 0) {
            $('#editor').insertAtCursor(atString);
        } else if ( oldContent.length>0 && oldContent != atString ) {
            $('#editor').insertAtCursor('
'+atString);
        }
        scrollToAnchor(comment);
        return;
    } else if($('.simditor-body').length>0) {
        editorName = 'simditor';
        comment = $('.simditor-body');
        oldContent = comment.html();
        oldText = comment.text();
    } else {
        editorName = 'smd';
        comment = $('#editor');
        oldContent = comment.val();
    }

    newContent = '';
    scrollToAnchor(comment);
    if( editorName == 'smd') {
        if(oldContent.length > 0){
            if (oldContent != atString) {
                newContent = oldContent + "\n" + atString;
            }
        } else {
            newContent = atString;
        }
        comment.val(newContent);
    } else {
        if(oldText.length>0){
            if (oldText != atString) {
                newContent = oldContent + "
" + atString;
            }
        } else {
            newContent = atString;
        }
        comment.html(newContent);
    }
    comment.focusEnd();
}

var insertAtCursor= function(target, text) {
    var postion = target.selection('getPos');
    target.selection('insert',{text: text, mode: 'after'}).selection('setPos', {start: postion.end+text.length, end: postion.end+text.length});
}

var scrollToAnchor = function(anchor) {
    var fixedBar = $('.navbar-fixed-top');
    var fixedBarHeight = 0;
    if (fixedBar.length > 0) {
        fixedBarHeight = fixedBar.height();
    }
    if(anchor.length > 0){
        var t = anchor.offset().top - fixedBarHeight;
        $("html,body").animate({scrollTop : t}, {queue : false});
    }
}

var chooseNode = function(node) {
    $(".nodes-select2").val(node).trigger("change");
}

$(function(){
    var anchor = window.location.hash;
    if (anchor) {
        scrollToAnchor($(anchor));
    }
});

$(function(){
    $('.link-external a[href^="http"]')
        .not('[href*="'+location.hostname+'"]')
        .attr({target:"_blank"})
        .addClass("external");
});

$(function(){
    $('img.lazy').lazyload();
});

$(function(){

    if ($('.sf-topic-content').length>0) {
        var min=12, max=18;
        var elm = $('.sf-topic-content');
        var size = elm.css('fontSize').replace('px', '');

        $('.fontsize-plus').click(function() {
            if (size<max) {
                size++;
                elm.css({'fontSize' : size});
            }
            return false;
        });

        $('.fontsize-minus').click(function() {
            if (size>min) {
                size--;
                elm.css({'fontSize' : size});
            }
            return false;
        });
    }
});

$(function(){
    $('input#q').focus(function(){
        $(this).animate({width: "250"}, 'fast');
    })
    $('input#q').blur(function(){
        $(this).animate({width: "180"}, 'fast');
    })
});

$(function(){
    $('.navi-nodes-add').click(function(e) {
        e.preventDefault();
        if($(".navi-nodes tr").length == 1) {
            $(".navi-nodes tr .navi-nodes-del").show();
        }
        var last = $('.navi-nodes tr:last-child');
        var id = parseInt(last.attr('id').replace('node_', ''))+1;
        var newNode = last.clone(true).attr('id', 'node_'+id);
        newNode.find('.node-id').val('').attr('id', 'navinode-'+id+'-node_id').attr('name', 'NaviNode['+id+'][node_id]');
        newNode.find('.visible').prop('checked', false).attr('id', 'navinode-'+id+'-visible').siblings('input').addBack().attr('name', 'NaviNode['+id+'][visible]');
        newNode.find('.sortid').val('').attr('id', 'navinode-'+id+'-sortid').attr('name', 'NaviNode['+id+'][sortid]');
        $('.navi-nodes').append(newNode);
    });
    $('.navi-nodes-del').on("click", function () {
        $(this).closest('tr').remove();
        if($(".navi-nodes tr").length == 1) {
            $(".navi-nodes tr .navi-nodes-del").hide();
        }
    });
});

$(function(){
    var authInfo = {
        clientId: {qq:'appid', weibo:'App Key'},
        clientSecret: {qq:'appkey', weibo:'App Secret'},
    };

    if($(".auth-items div.auth-item").length == 1) {
        $(".auth-items div.auth-item .auth-item-del").hide();
    }

    $('.auth-item-add').click(function(e) {
        e.preventDefault();
        if($(".auth-items div.auth-item").length == 1) {
            $(".auth-items div.auth-item .auth-item-del").show();
        }
        var last = $('.auth-items div.auth-item').last();
        var id = parseInt(last.attr('id').replace('auth_', ''))+1;
        var newNode = last.clone(true).attr('id', 'auth_'+id);
        newNode.find('.auth-item-id').text('Account'+id);
        newNode.find('.auth-key').each(function(index, el){
            $(el).attr('id', 'setting-'+id+'-'+index+'-key').attr('name', 'Setting['+id+']'+'['+index+'][key]');
        });
        newNode.find('.auth-value').each(function(index, el){
            $(el).val('').attr('id', 'setting-'+id+'-'+index+'-value').attr('name', 'Setting['+id+']'+'['+index+'][value]');
        });
        newNode.find('.auth-index').val(0);
        newNode.find('.auth-sortid').val( parseInt($('.auth-sortid', last).val())+1 );
        $('.auth-items').append(newNode);
    });
    $('.auth-item-del').on("click", function () {
        $(this).closest('div.auth-item').remove();
        if($(".auth-items div.auth-item").length == 1) {
            $(".auth-items div.auth-item .auth-item-del").hide();
        }
    });
    $('.auth-type').on('change', function(){
        type = $(this).val();
        authItem = $(this).closest('.auth-item');

        $('.auth-item-id', authItem).text(type);
        $('.auth-title', authItem).val( authInfo['title'][type]===undefined?'Login with '+type:authInfo['title'][type] );
        $('.auth-clientId', authItem).closest('div').siblings('label').text( authInfo['clientId'][type]===undefined?'clientId':authInfo['clientId'][type] );
        $('.auth-clientSecret', authItem).closest('div').siblings('label').text( authInfo['clientSecret'][type]===undefined?'clientSecret':authInfo['clientSecret'][type] );
    });
});

$(function(){
    $('#exampleModal').on('show.bs.modal', function (event) {
      var button = $(event.relatedTarget);
      var modal = $(this);
      modal.find('.thanks-to').text(button.data('author'));
      modal.find('.good').attr('id', button.attr('id'));
    });
    $('body').on('click', '.good', function(e) {
        self = $(this);
        params = self.attr('id').split('-');
        thanks = $('input.thanks-author:checked').prop("checked")===true?1:0;
        $.ajax({
            url: baseUrl+'/service/good',
            type: "POST",
            data: { type:params[1], id:params[2], thanks:thanks },
            success: function (data) {
                if(data.result == 1) {
                    $('#'+self.attr('id')+' .good-num').text(data.count);
                } else {
                    alert(data.msg);
                }
                $('#exampleModal').modal('hide');
            }
        });
    });
});

$(function(){
    $('body').on('click', '.favorite', function(e) {
        var title = {
            'favorite':{'user':'Unfollow', 'topic':'Cancel Favorite', 'node':'Cancel Favorite'},
            'unfavorite':{user:'Follow', topic:'Favorite', node:'Favorite'}
        };
        self = $(this);
        params = self.attr('params').split(' ');
        action = params[0];
        type = params[1];
        id = params[2];
        $.ajax({
            url: baseUrl+'/service/'+action,
            type: "POST",
            data: { type:type, id:id },
            success: function (data) {
                if(data.result == 1) {
                    count = $(".favorite-num", self).text();
                    if (action == 'favorite') {
                        count = count == ''?1:(parseInt(count) + 1);
                        $(".far", self).removeClass('far').addClass('fas');
                        $(self).attr({'title':title[action][type], 'params':'unfavorite '+type+' '+id});
                    } else {
                        count = (count == '' || count=='1')?'':(parseInt(count) - 1);
                        $(".fas", self).removeClass('fas').addClass('far');
                        $(self).attr({'title':title[action][type], 'params':'favorite '+type+' '+id});
                    }
                    $(".favorite-num", self).text(count);
                    $(".favorite-name", self).text(title[action][type]);
                } else {
                    alert(data.msg);
                }
            }
        });
    });
});
$(function(){
    $('.img-zoom img.lazy').each(function( index ) {
        if ( $(this).parents('a').length == 0 ) {
            href = $(this).attr('data-original')?$(this).attr('data-original'):$(this).attr('src');
            $(this).wrap('');
        }
    });
});

$(function(){
    var pocounter;
    $("*[data-poload]").on("mouseenter", function () {
            var _this = this;
            $.get($(_this).data('poload'),function(d) {
                $(_this).popover({container: 'body', trigger: "manual" , html: true, animation:false, content: d}).popover('show');
            });

            // clear the counter
            clearTimeout(pocounter);

            // start new timeout to show popover
            pocounter = setTimeout(function(){
                if($(_this).is(':hover'))
                {
                    $(_this).popover("show");
                }
                $(".popover").on("mouseleave", function () {
                    $(_this).popover('destroy');
                });
            }, 400);

        }).on("mouseleave", function () {
            var _this = this;
            setTimeout(function () {
                if (!$(".popover:hover").length) {
                    $(_this).popover("destroy");
                }
            }, 300);
    });
});

$(function(){
    $("#weixinmp").popover({
        html: true,
        placement: 'left',
        trigger: 'manual',
        content: '

',
        title : '微信扫一扫 <button type="button" id="weixinmp-close" class="popover-close close">×</button>'
    }).on('shown.bs.popover', function(e){
        var popover = $(this);
        $(this).parent().find('div.popover .popover-close').on('click', function(e){
          popover.popover('hide');
        });
    });

    $("#weixinmp").click(function () {
        $(this).popover('show');
        $("#weixin-qrcode").qrcode({width: 128,height: 128,text: $(this).attr('link')});
    });
});
<|endoftext|>


<commit_before>/*global $*/
/*global PlayField*/
/*global Tetromino*/
/*global TetrisControl*/
/*global Square*/
/*global drawCurrentGame*/

function initializeTetrisCard(card) {
    var canvas = $(card).find('canvas')[0];
    var container = $(canvas).parent();

    var ctx = canvas.getContext("2d");
    var tetrisControl = new TetrisControl(canvas);
    var playField = new PlayField(20, 10, Tetromino.prototype.TETROMINOS, //
        function(currentGame) {
            drawCurrentGame(currentGame, ctx);
        }, //
        function(gameControl, status, playFieldId) {

            var instructionBtn = $(card).find('.tetris-instruction-btn');
            instructionBtn.on('click', function() {
                $(card).find('.tetris-flip-card').toggleClass('flipped');
                $(this).toggleClass('mdl-button--colored');
            });

            $(card).find('.tetris-flip-back').on('click', function() {
                $(card).find('.tetris-flip-card').removeClass('flipped');
                instructionBtn.removeClass('mdl-button--colored');
            });

            var nextControl = undefined;
            var nextCrtlText = undefined;

            switch (status) {
                case PlayField.prototype.Status.NEW:
                    nextCrtlText = 'Start';
                    nextControl = gameControl.startGame;
                    instructionBtn.prop('disabled', false);
                    break;
                case PlayField.prototype.Status.GAMEOVER:
                    nextCrtlText = 'Re:start';
                    nextControl = gameControl.restartGame;
                    instructionBtn.prop('disabled', false);
                    break;
                case PlayField.prototype.Status.PAUSED:
                    nextCrtlText = 'Resume';
                    nextControl = gameControl.resumeGame;
                    instructionBtn.prop('disabled', false);
                    break;
                default:
                    nextCrtlText = 'Pause';
                    nextControl = gameControl.pauseGame;
                    instructionBtn.prop('disabled', true);
                    break;
            }

            if (status == PlayField.prototype.Status.IN_PROGRESS) {
                tetrisControl.enableInputControl(gameControl.inputControl, playFieldId);
            }
            else {
                tetrisControl.disableInputControl(gameControl.inputControl, playFieldId);
            }

            tetrisControl.refreshNextControl(nextControl, playFieldId);

            var controlBtn = $(card).find('.tetris-control-btn');
            if (nextControl) {
                controlBtn.html(nextCrtlText);
                controlBtn.unbind('click.tetris_control');
                controlBtn.bind('click.tetris_control', nextControl);
            }
        }
    );

    function resizeCanvas(playField) {
        var pfHeight = window.innerHeight - $(card).find('.mdl-card__title').outerHeight() - $(card).find('.mdl-card__actions').outerHeight();
        var pfWidth = container.width();
        var squareWidth = Math.floor(Math.min(pfWidth / (playField.grid[0].length + 7), pfHeight / (playField.grid.length + 2)));

        canvas.height = pfHeight;
        canvas.width = pfWidth;
        $(canvas).closest('.mdl-card__media').height(pfHeight);
        Square.prototype.width = squareWidth;

        drawCurrentGame(playField.getGameDisplay(), ctx);
    }
    $(window).on('resize', function() {
        resizeCanvas(playField);
    });
    resizeCanvas(playField);
}<commit_msg>Minor<commit_after>/*global $*/
/*global PlayField*/
/*global Tetromino*/
/*global TetrisControl*/
/*global Square*/
/*global drawCurrentGame*/

function initializeTetrisCard(card) {
    var canvas = $(card).find('canvas')[0];
    var container = $(canvas).parent();

    var ctx = canvas.getContext("2d");
    var tetrisControl = new TetrisControl(canvas);

    var instructionBtn = $(card).find('.tetris-instruction-btn');
    instructionBtn.on('click', function() {
        $(card).find('.tetris-flip-card').toggleClass('flipped');
        $(this).toggleClass('mdl-button--colored');
    });

    $(card).find('.tetris-flip-back').on('click', function() {
        $(card).find('.tetris-flip-card').removeClass('flipped');
        instructionBtn.removeClass('mdl-button--colored');
    });

    var playField = new PlayField(20, 10, Tetromino.prototype.TETROMINOS, //
        function(currentGame) {
            drawCurrentGame(currentGame, ctx);
        }, //
        function(gameControl, status, playFieldId) {

            var nextControl = undefined;
            var nextCrtlText = undefined;

            switch (status) {
                case PlayField.prototype.Status.NEW:
                    nextCrtlText = 'Start';
                    nextControl = gameControl.startGame;
                    instructionBtn.prop('disabled', false);
                    break;
                case PlayField.prototype.Status.GAMEOVER:
                    nextCrtlText = 'Re:start';
                    nextControl = gameControl.restartGame;
                    instructionBtn.prop('disabled', false);
                    break;
                case PlayField.prototype.Status.PAUSED:
                    nextCrtlText = 'Resume';
                    nextControl = gameControl.resumeGame;
                    instructionBtn.prop('disabled', false);
                    break;
                default:
                    nextCrtlText = 'Pause';
                    nextControl = gameControl.pauseGame;
                    instructionBtn.prop('disabled', true);
                    break;
            }

            if (status == PlayField.prototype.Status.IN_PROGRESS) {
                tetrisControl.enableInputControl(gameControl.inputControl, playFieldId);
            }
            else {
                tetrisControl.disableInputControl(gameControl.inputControl, playFieldId);
            }

            tetrisControl.refreshNextControl(nextControl, playFieldId);

            var controlBtn = $(card).find('.tetris-control-btn');
            if (nextControl) {
                controlBtn.html(nextCrtlText);
                controlBtn.unbind('click.tetris_control');
                controlBtn.bind('click.tetris_control', nextControl);
            }
        }
    );

    function resizeCanvas(playField) {
        var pfHeight = window.innerHeight - $(card).find('.mdl-card__title').outerHeight() - $(card).find('.mdl-card__actions').outerHeight();
        var pfWidth = container.width();
        var squareWidth = Math.floor(Math.min(pfWidth / (playField.grid[0].length + 7), pfHeight / (playField.grid.length + 2)));

        canvas.height = pfHeight;
        canvas.width = pfWidth;
        $(canvas).closest('.mdl-card__media').height(pfHeight);
        Square.prototype.width = squareWidth;

        drawCurrentGame(playField.getGameDisplay(), ctx);
    }
    $(window).on('resize', function() {
        resizeCanvas(playField);
    });
    resizeCanvas(playField);
}<|endoftext|>


<commit_before>module.exports = (function(undefined){
  "use strict";

  function Game(app) {
    this.appId                    = app.appid;
    this.name                     = app.name ? app.name : undefined;
    this.playtimeTwoWeeks         = app.playtime_2weeks ? this.convertFromMinutes(app.playtime_2weeks) : '0 minutes';
    this.playtimeForever          = app.playtime_forever ? app.playtime_forever : 0;
    this.playtimeForeverReadable  = this.convertFromMinutes(this.playtimeForever);
    this.icon                     = app.img_icon_url ? this.getImageForGame(app.appid, app.img_icon_url) : undefined;
    this.logo                     = app.img_logo_url ? this.getImageForGame(app.appid, app.img_logo_url) : undefined;
    this.header                   = 'http://cdn.steampowered.com/v/gfx/apps/' + this.appId + '/header.jpg';
    this.hasCommunityVisibleStats = app.has_community_visible_stats ? app.has_community_visible_stats : 0;
  }

  Game.prototype.getImageForGame = function getImageForGame(appId, hash) {
    if (hash) {
      return 'http://media.steampowered.com/steamcommunity/public/images/apps/' + appId + '/' + hash + '.jpg';
    }

    return undefined;
  };

  Game.prototype.convertFromMinutes = function convertFromMinutes(minutes) {
    var seconds = minutes * 60,
        secondsInAMinute = 60,
        secondsInAnHour = 60 * secondsInAMinute,
        secondsInADay = 24 * secondsInAnHour,
        days = Math.floor(seconds / secondsInADay),
        hourSeconds = seconds % secondsInADay,
        hours = Math.floor(hourSeconds / secondsInAnHour),
        minuteSeconds = hourSeconds % secondsInAnHour,
        minutes = Math.floor(minuteSeconds / secondsInAMinute),
        remainingSeconds = minuteSeconds % secondsInAMinute,
        seconds = Math.ceil(remainingSeconds),
        output = '';

    if (days > 0) {
      output += days + ' days ';
    }

    if (hours > 0) {
      output += hours + ' hours ';
    }

    output += minutes + ' minutes';

    return output;
  };

  return Game;
})();<commit_msg>Divide playtimeTwoWeeks into numeric and readable<commit_after>module.exports = (function(undefined){
  "use strict";

  function Game(app) {
    this.appId                    = app.appid;
    this.name                     = app.name ? app.name : undefined;
    this.playtimeTwoWeeks         = app.playtime_2weeks ? app.playtime_2weeks : 0;
    this.playtimeTwoWeeksReadable = app.playtime_2weeks ? this.convertFromMinutes(app.playtime_2weeks) : '0 minutes';
    this.playtimeForever          = app.playtime_forever ? app.playtime_forever : 0;
    this.playtimeForeverReadable  = this.convertFromMinutes(this.playtimeForever);
    this.icon                     = app.img_icon_url ? this.getImageForGame(app.appid, app.img_icon_url) : undefined;
    this.logo                     = app.img_logo_url ? this.getImageForGame(app.appid, app.img_logo_url) : undefined;
    this.header                   = 'http://cdn.steampowered.com/v/gfx/apps/' + this.appId + '/header.jpg';
    this.hasCommunityVisibleStats = app.has_community_visible_stats ? app.has_community_visible_stats : 0;
  }

  Game.prototype.getImageForGame = function getImageForGame(appId, hash) {
    if (hash) {
      return 'http://media.steampowered.com/steamcommunity/public/images/apps/' + appId + '/' + hash + '.jpg';
    }

    return undefined;
  };

  Game.prototype.convertFromMinutes = function convertFromMinutes(minutes) {
    var seconds = minutes * 60,
        secondsInAMinute = 60,
        secondsInAnHour = 60 * secondsInAMinute,
        secondsInADay = 24 * secondsInAnHour,
        days = Math.floor(seconds / secondsInADay),
        hourSeconds = seconds % secondsInADay,
        hours = Math.floor(hourSeconds / secondsInAnHour),
        minuteSeconds = hourSeconds % secondsInAnHour,
        minutes = Math.floor(minuteSeconds / secondsInAMinute),
        remainingSeconds = minuteSeconds % secondsInAMinute,
        seconds = Math.ceil(remainingSeconds),
        output = '';

    if (days > 0) {
      output += days + ' days ';
    }

    if (hours > 0) {
      output += hours + ' hours ';
    }

    output += minutes + ' minutes';

    return output;
  };

  return Game;
})();
<|endoftext|>


<commit_before>import {BaseStore} from 'fluxible/addons';

class SlideEditStore extends BaseStore {
    constructor(dispatcher) {
        super(dispatcher);
        this.id = '';
        this.slideId = '';
        this.title = '';
        this.LeftPanelTitleChange = false;
        this.content = '';
        this.markdown = '';
        this.speakernotes = '';
        this.scaleratio = 1; //default no scale ratio
        this.template = '';
        this.embedQuestionsClick = 'false';
        this.embedQuestionsContent = ''; //contains the content for the question embedding
        this.slideSize = '';
        this.slideTransition = '';
        this.slideSizeText = '';
        this.saveSlideClick = 'false';
        this.cancelClick = 'false';
        this.selector = '';
        this.undoClick = 'false';
        this.redoClick = 'false';
        this.addInputBox = 'false';
        this.uploadMediaClick = 'false';
        this.uploadVideoClick = 'false';
        this.tableClick = 'false';
        this.annotateClick = 'false';
        this.mathsClick = 'false';
        this.codeClick = 'false';
        this.removeBackgroundClick = 'false';
        this.embedClick = 'false';
        this.embedWidth = '';
        this.embedHeight = '';
        this.embedURL = '';
        this.embedCode = '';
        this.ltiClick = 'false';
        this.ltiWidth = '';
        this.ltiHeight = '';
        this.ltiURL = '';
        this.ltiKey = '';
        this.ltiResponseURL = '',
        this.ltiResponseHTML = '',
        this.embedTitle = '';
        this.HTMLEditorClick = 'false';
        this.scaleRatio = null;
        this.contentEditorFocus = 'false';
        this.annotations = [];
        /* Whether there are unsaved changes in editor. */
        this.hasChanges = false;
        this.refreshEditor = 'false';
    }
    updateContent(payload) {
        this.id = payload.slide.id;
        this.slideId = payload.selector.sid;
        this.title = payload.slide.title || ' ';
        this.content = payload.slide.content || ' ';
        this.markdown = payload.slide.markdown || ' ';
        this.speakernotes = payload.slide.speakernotes || ' ';
        this.annotations = payload.slide.annotations || [];

        this.hasChanges = false;

        this.emitChange();
    }

    saveSlide() {
        this.emitChange();
    }

    addSlide() {
        this.emitChange();
    }

    changeTemplate(payload){
        this.template = payload.template;
        this.emitChange();
        this.template = '';
        this.emitChange();
    }

    changeSlideSize(payload){
        this.slideSize = payload.slideSize;
        this.emitChange();
        this.slideSize = '';
        this.emitChange();
    }

    changeSlideTransition(payload){
        this.slideTransition = payload.slideTransition;
        this.emitChange();
    }

    changeSlideSizeText(payload){
        this.slideSizeText = payload.slideSizeText;
        this.emitChange();
    }

    handleSaveSlideClick(){
        this.saveSlideClick = 'true';
        this.emitChange();
        this.saveSlideClick = 'false';
        this.emitChange();
    }

    handleCancelClick(payload){
        this.selector = payload.selector;
        this.cancelClick = 'true';
        this.emitChange();
        this.cancelClick = 'false';
        this.emitChange();
    }

    handleUndoClick(){
        this.undoClick = 'true';
        this.emitChange();
        this.undoClick = 'false';
        this.emitChange();
    }

    handleRedoClick(){
        this.redoClick = 'true';
        this.emitChange();
        this.redoClick = 'false';
        this.emitChange();
    }

    handleAddInputBox(){
        this.addInputBox = 'true';
        this.emitChange();
        this.addInputBox = 'false';
        this.emitChange();
    }

    handleUploadMedia(){
        this.uploadMediaClick = 'true';
        this.emitChange();
        this.uploadMediaClick = 'false';
        this.emitChange();
    }

    handleuploadVideoClick(){
        this.uploadVideoClick = 'true';
        this.emitChange();
        this.uploadVideoClick = 'false';
        this.emitChange();
    }

    handleTableClick(){
        this.tableClick = 'true';
        this.emitChange();
        this.tableClick = 'false';
        this.emitChange();
    }

    handleAnnotateClick(){
        this.annotateClick = 'true';
        this.emitChange();
        this.annotateClick = 'false';
        this.emitChange();
    }

    handleMathsClick(){
        this.mathsClick = 'true';
        this.emitChange();
        this.mathsClick = 'false';
        this.emitChange();
    }

    handleCodeClick(){
        this.codeClick = 'true';
        this.emitChange();
        this.codeClick = 'false';
        this.emitChange();
    }

    handleRemoveBackgroundClick(){
        this.removeBackgroundClick = 'true';
        this.emitChange();
        this.removeBackgroundClick = 'false';
        this.emitChange();
    }

    handleEmbedClick(payload){
        this.embedClick = 'true';
        this.embedWidth = payload.embedWidth;
        this.embedHeight = payload.embedHeight;
        this.embedURL = payload.embedURL;
        this.embedCode = payload.embedCode;
        this.embedTitle = payload.embedTitle;
        this.emitChange();
        this.embedClick = 'false';
        this.embedWidth = '';
        this.embedHeight = '';
        this.embedURL = '';
        this.embedCode = '';
        this.embedTitle = '';
        this.emitChange();
    }

    changeTitle(payload){
        this.title = payload.title;
        this.LeftPanelTitleChange = payload.LeftPanelTitleChange;
        this.emitChange();
    }

    handleHTMLEditorClick(){
        this.HTMLEditorClick = 'true';
        this.emitChange();
        this.HTMLEditorClick = 'false';
        this.emitChange();
    }
    handleLTIAddClick(payload){
        this.ltiURL = payload.ltiURL;
        this.ltiKey = payload.ltiKey;
        this.ltiWidth = payload.ltiWidth;
        this.ltiHeight = payload.ltiHeight;
        this.ltiResponseURL = payload.ltiResponseURL;
        this.ltiResponseHTML = payload.ltiResponseHTML;
        this.ltiClick = 'true';
        this.emitChange();
        this.ltiClick = 'false';
        this.emitChange();
    }
    handleEmbedQuestions(payload){
        //embedQuestionsContent - this is the content that will be embedded (questions and options)
        //embedQuestions - this will be the trigger that causes the questions to be embedded.
        //add some form of logic/error handling here?
        this.embedQuestionsContent = payload;
        this.embedQuestionsClick = 'true';
        this.emitChange();

        this.embedQuestionsClick = 'false';
        this.embedQuestionsContent = '';
    }
    handleContentEditorFocus(payload) {
        this.contentEditorFocus = payload.focus;
        this.emitChange();
    }
    updateSlideContentAfterTranslation(payload){
        this.content = payload.translations.translations;
        this.emitChange();
        this.refreshEditor = 'true';
        this.emitChange();
        this.refreshEditor = 'false';
        this.emitChange();
    }
    getState() {
        return {
            id: this.id,
            slideId: this.slideId,
            title: this.title,
            LeftPanelTitleChange: this.LeftPanelTitleChange,
            content: this.content,
            markdown: this.markdown,
            speakernotes: this.speakernotes,
            scaleratio: this.scaleratio,
            saveSlideClick: this.saveSlideClick,
            cancelClick: this.cancelClick,
            selector: this.selector,
            undoClick: this.undoClick,
            redoClick: this.redoClick,
            template: this.template,
            embedQuestionsClick: this.embedQuestionsClick,
            embedQuestionsContent: this.embedQuestionsContent,
            slideSize: this.slideSize,
            slideTransition: this.slideTransition,
            slideSizeText: this.slideSizeText,
            addInputBox: this.addInputBox,
            uploadMediaClick: this.uploadMediaClick,
            uploadVideoClick: this.uploadVideoClick,
            tableClick: this.tableClick,
            annotateClick: this.annotateClick,
            mathsClick: this.mathsClick,
            codeClick: this.codeClick,
            removeBackgroundClick: this.removeBackgroundClick,
            embedClick: this.embedClick,
            embedURL: this.embedURL,
            embedCode: this.embedCode,
            embedTitle: this.embedTitle,
            embedWidth: this.embedWidth,
            embedHeight: this.embedHeight,
            ltiClick: this.ltiClick,
            ltiURL: this.ltiURL,
            ltiKey: this.ltiKey,
            ltiWidth: this.ltiWidth,
            ltiHeight: this.ltiHeight,
            ltiResponseURL: this.ltiResponseURL,
            ltiResponseHTML: this.ltiResponseHTML,
            HTMLEditorClick: this.HTMLEditorClick,
            scaleRatio: this.scaleRatio,
            contentEditorFocus: this.contentEditorFocus,
<<<<<<< HEAD
            annotations: this.annotations,
=======
            hasChanges: this.hasChanges,
>>>>>>> master
            refreshEditor: this.refreshEditor
        };
    }

    dehydrate() {
        return this.getState();
    }

    rehydrate(state) {
        this.id = state.id;
        this.slideId = state.slideId;
        this.title = state.title;
        this.LeftPanelTitleChange = state.LeftPanelTitleChange;
        this.content = state.content;
        this.markdown = state.markdown;
        this.speakernotes = state.speakernotes;
        this.scaleratio = state.scaleratio;
        this.saveSlideClick = state.saveSlideClick;
        this.cancelClick = state.cancelClick;
        this.selector = state.selector;
        this.undoClick = state.undoClick;
        this.redoClick = state.redoClick;
        this.template = state.template;
        this.embedQuestionsClick = state.embedQuestionsClick;
        this.embedQuestionsContent = state.embedQuestionsContent;
        this.slideSize = state.slideSize;
        this.slideTransition = state.slideTransition;
        this.slideSizeText = state.slideSizeText;
        this.addInputBox = state.addInputBox;
        this.uploadMediaClick = state.uploadMediaClick;
        this.uploadVideoClick = state.uploadVideoClick;
        this.tableClick = state.tableClick;
        this.annotateClick = state.annotateClick;
        this.mathsClick = state.mathsClick;
        this.codeClick = state.codeClick;
        this.removeBackgroundClick = state.removeBackgroundClick;
        this.embedClick = state.embedClick;
        this.embedURL = state.embedURL;
        this.embedCode = state.embedCode;
        this.embedTitle = state.embedTitle;
        this.embedWidth = state.embedWidth;
        this.embedHeight = state.embedHeight;
        this.ltiClick = state.ltiClick;
        this.ltiURL = state.ltiURL;
        this.ltiKey = state.ltiKey;
        this.ltiWidth = state.ltiWidth;
        this.ltiHeight = state.ltiHeight;
        this.ltiResponseURL = state.ltiResponseURL;
        this.ltiResponseHTML = state.ltiResponseHTML;
        this.HTMLEditorClick = state.HTMLEditorClick;
        this.scaleRatio = state.scaleRatio = 1;
        this.contentEditorFocus = state.contentEditorFocus;
<<<<<<< HEAD
        this.annotations = state.annotations;
=======
        this.hasChanges = state.hasChanges;
>>>>>>> master
        this.refreshEditor = state.refreshEditor;
    }

    zoomContent(payload) {
        if (!this.scaleRatio) {
            this.scaleRatio = 1;
        }

        if (payload.mode === 'edit') {
            switch (payload.direction) {
                case 'in':
                    this.scaleRatio += 0.25;
                    break;

                case 'out':
                    this.scaleRatio -= 0.25;
                    break;

                case 'reset':
                    this.scaleRatio = 1;
                    break;
            }
        }
        this.emitChange();
    }

    registerChange(payload) {
        this.hasChanges = payload.hasChanges;
        this.emitChange();
    }
}

SlideEditStore.storeName = 'SlideEditStore';
SlideEditStore.handlers = {
    'LOAD_SLIDE_EDIT_SUCCESS': 'updateContent',
    'SAVE_SLIDE_EDIT_SUCCESS': 'saveSlide',
    'ADD_SLIDE_EDIT_SUCCESS': 'addSlide',
    'SAVE_SLIDE_CLICK': 'handleSaveSlideClick',
    'CANCEL_CLICK': 'handleCancelClick',
    'CHANGE_TEMPLATE': 'changeTemplate',
    'CHANGE_SLIDE_SIZE': 'changeSlideSize',
    'CHANGE_SLIDE_TRANSITION': 'changeSlideTransition',
    'CHANGE_SLIDE_SIZE_TEXT': 'changeSlideSizeText',
    'ADD_INPUT_BOX': 'handleAddInputBox',
    'UPLOAD_MEDIA_CLICK': 'handleUploadMedia',
    'UPLOAD_VIDEO_CLICK': 'handleuploadVideoClick',
    'TABLE_CLICK': 'handleTableClick',
    'ANNOTATE_CLICK': 'handleAnnotateClick',
    'MATHS_CLICK': 'handleMathsClick',
    'CODE_CLICK': 'handleCodeClick',
    'REMOVE_BACKGROUND_CLICK': 'handleRemoveBackgroundClick',
    'EMBED_CLICK': 'handleEmbedClick',
    'ADD_LTI_SUCCESS': 'handleLTIAddClick',
    'CHANGE_TITLE': 'changeTitle',
    'HTML_EDITOR_CLICK': 'handleHTMLEditorClick',
    'SLIDE_EMBED_QUESTIONS': 'handleEmbedQuestions',
    'UNDO_CLICK': 'handleUndoClick',
    'REDO_CLICK': 'handleRedoClick',
    'ZOOM': 'zoomContent',
    'CONTENT_EDITOR_FOCUS': 'handleContentEditorFocus',
    'REGISTER_CHANGE': 'registerChange',
    'UPDATE_SLIDE_CONTENT_AFTER_TRANSLATION': 'updateSlideContentAfterTranslation',
};

export default SlideEditStore;
<commit_msg>Fix merge conflict<commit_after>import {BaseStore} from 'fluxible/addons';

class SlideEditStore extends BaseStore {
    constructor(dispatcher) {
        super(dispatcher);
        this.id = '';
        this.slideId = '';
        this.title = '';
        this.LeftPanelTitleChange = false;
        this.content = '';
        this.markdown = '';
        this.speakernotes = '';
        this.scaleratio = 1; //default no scale ratio
        this.template = '';
        this.embedQuestionsClick = 'false';
        this.embedQuestionsContent = ''; //contains the content for the question embedding
        this.slideSize = '';
        this.slideTransition = '';
        this.slideSizeText = '';
        this.saveSlideClick = 'false';
        this.cancelClick = 'false';
        this.selector = '';
        this.undoClick = 'false';
        this.redoClick = 'false';
        this.addInputBox = 'false';
        this.uploadMediaClick = 'false';
        this.uploadVideoClick = 'false';
        this.tableClick = 'false';
        this.annotateClick = 'false';
        this.mathsClick = 'false';
        this.codeClick = 'false';
        this.removeBackgroundClick = 'false';
        this.embedClick = 'false';
        this.embedWidth = '';
        this.embedHeight = '';
        this.embedURL = '';
        this.embedCode = '';
        this.ltiClick = 'false';
        this.ltiWidth = '';
        this.ltiHeight = '';
        this.ltiURL = '';
        this.ltiKey = '';
        this.ltiResponseURL = '',
        this.ltiResponseHTML = '',
        this.embedTitle = '';
        this.HTMLEditorClick = 'false';
        this.scaleRatio = null;
        this.contentEditorFocus = 'false';
        this.annotations = [];
        /* Whether there are unsaved changes in editor. */
        this.hasChanges = false;
        this.refreshEditor = 'false';
    }
    updateContent(payload) {
        this.id = payload.slide.id;
        this.slideId = payload.selector.sid;
        this.title = payload.slide.title || ' ';
        this.content = payload.slide.content || ' ';
        this.markdown = payload.slide.markdown || ' ';
        this.speakernotes = payload.slide.speakernotes || ' ';
        this.annotations = payload.slide.annotations || [];

        this.hasChanges = false;

        this.emitChange();
    }

    saveSlide() {
        this.emitChange();
    }

    addSlide() {
        this.emitChange();
    }

    changeTemplate(payload){
        this.template = payload.template;
        this.emitChange();
        this.template = '';
        this.emitChange();
    }

    changeSlideSize(payload){
        this.slideSize = payload.slideSize;
        this.emitChange();
        this.slideSize = '';
        this.emitChange();
    }

    changeSlideTransition(payload){
        this.slideTransition = payload.slideTransition;
        this.emitChange();
    }

    changeSlideSizeText(payload){
        this.slideSizeText = payload.slideSizeText;
        this.emitChange();
    }

    handleSaveSlideClick(){
        this.saveSlideClick = 'true';
        this.emitChange();
        this.saveSlideClick = 'false';
        this.emitChange();
    }

    handleCancelClick(payload){
        this.selector = payload.selector;
        this.cancelClick = 'true';
        this.emitChange();
        this.cancelClick = 'false';
        this.emitChange();
    }

    handleUndoClick(){
        this.undoClick = 'true';
        this.emitChange();
        this.undoClick = 'false';
        this.emitChange();
    }

    handleRedoClick(){
        this.redoClick = 'true';
        this.emitChange();
        this.redoClick = 'false';
        this.emitChange();
    }

    handleAddInputBox(){
        this.addInputBox = 'true';
        this.emitChange();
        this.addInputBox = 'false';
        this.emitChange();
    }

    handleUploadMedia(){
        this.uploadMediaClick = 'true';
        this.emitChange();
        this.uploadMediaClick = 'false';
        this.emitChange();
    }

    handleuploadVideoClick(){
        this.uploadVideoClick = 'true';
        this.emitChange();
        this.uploadVideoClick = 'false';
        this.emitChange();
    }

    handleTableClick(){
        this.tableClick = 'true';
        this.emitChange();
        this.tableClick = 'false';
        this.emitChange();
    }

    handleAnnotateClick(){
        this.annotateClick = 'true';
        this.emitChange();
        this.annotateClick = 'false';
        this.emitChange();
    }

    handleMathsClick(){
        this.mathsClick = 'true';
        this.emitChange();
        this.mathsClick = 'false';
        this.emitChange();
    }

    handleCodeClick(){
        this.codeClick = 'true';
        this.emitChange();
        this.codeClick = 'false';
        this.emitChange();
    }

    handleRemoveBackgroundClick(){
        this.removeBackgroundClick = 'true';
        this.emitChange();
        this.removeBackgroundClick = 'false';
        this.emitChange();
    }

    handleEmbedClick(payload){
        this.embedClick = 'true';
        this.embedWidth = payload.embedWidth;
        this.embedHeight = payload.embedHeight;
        this.embedURL = payload.embedURL;
        this.embedCode = payload.embedCode;
        this.embedTitle = payload.embedTitle;
        this.emitChange();
        this.embedClick = 'false';
        this.embedWidth = '';
        this.embedHeight = '';
        this.embedURL = '';
        this.embedCode = '';
        this.embedTitle = '';
        this.emitChange();
    }

    changeTitle(payload){
        this.title = payload.title;
        this.LeftPanelTitleChange = payload.LeftPanelTitleChange;
        this.emitChange();
    }

    handleHTMLEditorClick(){
        this.HTMLEditorClick = 'true';
        this.emitChange();
        this.HTMLEditorClick = 'false';
        this.emitChange();
    }
    handleLTIAddClick(payload){
        this.ltiURL = payload.ltiURL;
        this.ltiKey = payload.ltiKey;
        this.ltiWidth = payload.ltiWidth;
        this.ltiHeight = payload.ltiHeight;
        this.ltiResponseURL = payload.ltiResponseURL;
        this.ltiResponseHTML = payload.ltiResponseHTML;
        this.ltiClick = 'true';
        this.emitChange();
        this.ltiClick = 'false';
        this.emitChange();
    }
    handleEmbedQuestions(payload){
        //embedQuestionsContent - this is the content that will be embedded (questions and options)
        //embedQuestions - this will be the trigger that causes the questions to be embedded.
        //add some form of logic/error handling here?
        this.embedQuestionsContent = payload;
        this.embedQuestionsClick = 'true';
        this.emitChange();

        this.embedQuestionsClick = 'false';
        this.embedQuestionsContent = '';
    }
    handleContentEditorFocus(payload) {
        this.contentEditorFocus = payload.focus;
        this.emitChange();
    }
    updateSlideContentAfterTranslation(payload){
        this.content = payload.translations.translations;
        this.emitChange();
        this.refreshEditor = 'true';
        this.emitChange();
        this.refreshEditor = 'false';
        this.emitChange();
    }
    getState() {
        return {
            id: this.id,
            slideId: this.slideId,
            title: this.title,
            LeftPanelTitleChange: this.LeftPanelTitleChange,
            content: this.content,
            markdown: this.markdown,
            speakernotes: this.speakernotes,
            scaleratio: this.scaleratio,
            saveSlideClick: this.saveSlideClick,
            cancelClick: this.cancelClick,
            selector: this.selector,
            undoClick: this.undoClick,
            redoClick: this.redoClick,
            template: this.template,
            embedQuestionsClick: this.embedQuestionsClick,
            embedQuestionsContent: this.embedQuestionsContent,
            slideSize: this.slideSize,
            slideTransition: this.slideTransition,
            slideSizeText: this.slideSizeText,
            addInputBox: this.addInputBox,
            uploadMediaClick: this.uploadMediaClick,
            uploadVideoClick: this.uploadVideoClick,
            tableClick: this.tableClick,
            annotateClick: this.annotateClick,
            mathsClick: this.mathsClick,
            codeClick: this.codeClick,
            removeBackgroundClick: this.removeBackgroundClick,
            embedClick: this.embedClick,
            embedURL: this.embedURL,
            embedCode: this.embedCode,
            embedTitle: this.embedTitle,
            embedWidth: this.embedWidth,
            embedHeight: this.embedHeight,
            ltiClick: this.ltiClick,
            ltiURL: this.ltiURL,
            ltiKey: this.ltiKey,
            ltiWidth: this.ltiWidth,
            ltiHeight: this.ltiHeight,
            ltiResponseURL: this.ltiResponseURL,
            ltiResponseHTML: this.ltiResponseHTML,
            HTMLEditorClick: this.HTMLEditorClick,
            scaleRatio: this.scaleRatio,
            contentEditorFocus: this.contentEditorFocus,
            annotations: this.annotations,
            hasChanges: this.hasChanges,
            refreshEditor: this.refreshEditor
        };
    }

    dehydrate() {
        return this.getState();
    }

    rehydrate(state) {
        this.id = state.id;
        this.slideId = state.slideId;
        this.title = state.title;
        this.LeftPanelTitleChange = state.LeftPanelTitleChange;
        this.content = state.content;
        this.markdown = state.markdown;
        this.speakernotes = state.speakernotes;
        this.scaleratio = state.scaleratio;
        this.saveSlideClick = state.saveSlideClick;
        this.cancelClick = state.cancelClick;
        this.selector = state.selector;
        this.undoClick = state.undoClick;
        this.redoClick = state.redoClick;
        this.template = state.template;
        this.embedQuestionsClick = state.embedQuestionsClick;
        this.embedQuestionsContent = state.embedQuestionsContent;
        this.slideSize = state.slideSize;
        this.slideTransition = state.slideTransition;
        this.slideSizeText = state.slideSizeText;
        this.addInputBox = state.addInputBox;
        this.uploadMediaClick = state.uploadMediaClick;
        this.uploadVideoClick = state.uploadVideoClick;
        this.tableClick = state.tableClick;
        this.annotateClick = state.annotateClick;
        this.mathsClick = state.mathsClick;
        this.codeClick = state.codeClick;
        this.removeBackgroundClick = state.removeBackgroundClick;
        this.embedClick = state.embedClick;
        this.embedURL = state.embedURL;
        this.embedCode = state.embedCode;
        this.embedTitle = state.embedTitle;
        this.embedWidth = state.embedWidth;
        this.embedHeight = state.embedHeight;
        this.ltiClick = state.ltiClick;
        this.ltiURL = state.ltiURL;
        this.ltiKey = state.ltiKey;
        this.ltiWidth = state.ltiWidth;
        this.ltiHeight = state.ltiHeight;
        this.ltiResponseURL = state.ltiResponseURL;
        this.ltiResponseHTML = state.ltiResponseHTML;
        this.HTMLEditorClick = state.HTMLEditorClick;
        this.scaleRatio = state.scaleRatio = 1;
        this.contentEditorFocus = state.contentEditorFocus;
        this.annotations = state.annotations;
        this.hasChanges = state.hasChanges;
        this.refreshEditor = state.refreshEditor;
    }

    zoomContent(payload) {
        if (!this.scaleRatio) {
            this.scaleRatio = 1;
        }

        if (payload.mode === 'edit') {
            switch (payload.direction) {
                case 'in':
                    this.scaleRatio += 0.25;
                    break;

                case 'out':
                    this.scaleRatio -= 0.25;
                    break;

                case 'reset':
                    this.scaleRatio = 1;
                    break;
            }
        }
        this.emitChange();
    }

    registerChange(payload) {
        this.hasChanges = payload.hasChanges;
        this.emitChange();
    }
}

SlideEditStore.storeName = 'SlideEditStore';
SlideEditStore.handlers = {
    'LOAD_SLIDE_EDIT_SUCCESS': 'updateContent',
    'SAVE_SLIDE_EDIT_SUCCESS': 'saveSlide',
    'ADD_SLIDE_EDIT_SUCCESS': 'addSlide',
    'SAVE_SLIDE_CLICK': 'handleSaveSlideClick',
    'CANCEL_CLICK': 'handleCancelClick',
    'CHANGE_TEMPLATE': 'changeTemplate',
    'CHANGE_SLIDE_SIZE': 'changeSlideSize',
    'CHANGE_SLIDE_TRANSITION': 'changeSlideTransition',
    'CHANGE_SLIDE_SIZE_TEXT': 'changeSlideSizeText',
    'ADD_INPUT_BOX': 'handleAddInputBox',
    'UPLOAD_MEDIA_CLICK': 'handleUploadMedia',
    'UPLOAD_VIDEO_CLICK': 'handleuploadVideoClick',
    'TABLE_CLICK': 'handleTableClick',
    'ANNOTATE_CLICK': 'handleAnnotateClick',
    'MATHS_CLICK': 'handleMathsClick',
    'CODE_CLICK': 'handleCodeClick',
    'REMOVE_BACKGROUND_CLICK': 'handleRemoveBackgroundClick',
    'EMBED_CLICK': 'handleEmbedClick',
    'ADD_LTI_SUCCESS': 'handleLTIAddClick',
    'CHANGE_TITLE': 'changeTitle',
    'HTML_EDITOR_CLICK': 'handleHTMLEditorClick',
    'SLIDE_EMBED_QUESTIONS': 'handleEmbedQuestions',
    'UNDO_CLICK': 'handleUndoClick',
    'REDO_CLICK': 'handleRedoClick',
    'ZOOM': 'zoomContent',
    'CONTENT_EDITOR_FOCUS': 'handleContentEditorFocus',
    'REGISTER_CHANGE': 'registerChange',
    'UPDATE_SLIDE_CONTENT_AFTER_TRANSLATION': 'updateSlideContentAfterTranslation',
};

export default SlideEditStore;
<|endoftext|>


<commit_before>/**
 * Representation of "Lists"
 * @module List
 * @author Haris Skiadas <skiadas@hanover.edu>
 * Barb Wahl <wahl@hanover.edu>
 * Bill Altermatt <altermattw@hanover.edu>
 */
(function(define) {'use strict';
define(function(require) {

   var Variable, utils;

   utils = require('./utils');
   Variable = require('./variable');

   /**
    * Lists are essentially objects that can be accessed by array indexing as well.
    * One can remove a "property" from a list, which results in the other properties
    * shifting place.
    *
    * Indexing starts at 1.
    *
    * List Properties:
    * - Array of values.
    * - Object that holds names as keys and array indices as values.
    *
    * To create a list:
    * - object
    * - array of unnamed values
    * - with no argument, create empty list
    */
   function List(values) {
      if (!(this instanceof List)) { return new List(values); }
      if (Array.isArray(values)) {
         this.values = [utils.missing].concat(values);
         this._names = this.values.map(function() { return utils.missing; });
      } else {
         // Given an object. Need to populate array based on it
         this._names = [utils.missing].concat(Object.keys(values || {}));
         this.values = this._names.map(function(key) {
            return utils.isMissing(key) ? key : values[key];
         });
      }
   }

   List.prototype = Object.create({});

   /* eslint-disable complexity */
   /**
    * this.names();
    * this.names(i);
    * this.names(i, newName);  // newName is a string or null (or evals to missing)
    * this.names(newNames);    // Array or Variable of strings/nulls
    */
   List.prototype.names = function names(i, newNames) {
      if (arguments.length === 0) {
         return utils.allMissing(this._names) ? utils.missing
                                              : Variable.string(this._names.slice(1));
      }
      if (arguments.length > 1) {
         this._names[i] = newNames;
      } else { // one argument, `i`
         if (utils.isMissing(i)) {
            this._names = this.values.map(function() { return utils.missing; });
            return this;
         }
         if (i instanceof Variable) { i = i.asString().toArray(); }
         if (!Array.isArray(i)) { return this._names[i]; }
         if (i.length !== this.length()) {
            throw new Error('Incompatible names length');
         }
         this._names = [utils.missing].concat(i);
      }
      return this;
   };
   /* eslint-enable */

   List.prototype.length = function length() {
      return this.values.length - 1;
   };

   /**
    * i can be:
    * - index
    * - string name
    * - null/missing (return the array of values)
    */
   List.prototype.get = function get(i) {
      if (utils.isMissing(i)) { return this.values.slice(1); }
      if (typeof i !== 'number') {
         i = this._names.indexOf(i);
         if (i === -1) { return utils.missing; }
      }
      return this.values[i];
   };

   /**
    * i can be:
    * - index:  If i > length of list, create new item at index i and fill the
    *           gap with missing
    * - string (name):  If i is not already a name in the list, append new item
    *                   with name `i`.  Else, update existing item with new value.
    * - object of name-value pairs (update existing, append new)
    * - array of values (append new)
    * val can be any sort of thing.
    * omit `val` if `i` is an object or array.
    */
   List.prototype.set = function set(i, val) {
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number' || typeof i === 'string') {
         return this._set(i, val);
      }
      if (Array.isArray(i)) {
         i.forEach(function(v) {
            this._set(this.length() + 1, v);
         }.bind(this));
      } else {
         // i is an object
         Object.keys(i).forEach(function(key) {
            this._set(key, i[key]);
         }.bind(this));
      }
      return this;
   };

   // for setting exactly one value
   // `i` is a positive int or a name string
   // val is a thing
   List.prototype._set = function _set(i, val) {
      var name;
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number') {
         i = Math.floor(i);
         if (i < 1) { throw new Error('cannot set at negative index: ' + i); }
         this.values[i] = val;
      } else {
         name = i;
         i = this._names.indexOf(name);
         if (i === -1) { // append
            i = this.length() + 1;
            this._names[i] = name;
         }
         this.values[i] = val;
      }
      return this;
   };

   /**
    * Delete the item in the `i` position (i integer or string)
    */
   List.prototype.delete = function _delete(i) {
    if (utils.isMissing(i)) { return this; }
    if (typeof i !== 'number') { i = this._names.indexOf(i); }
    if (i >= 1) {
      this.values.splice(i, 1);
      this._names.splice(i, 1);
    }
    return this;
   };

   /**
   * Takes a function `f(val, i, name)` and applies it to each value in this
   * list.  For any values with no associated name, `name` will be supplied as
   * `undefined`.
   */
   List.prototype.each = function each(f) {
      var i;
      for (i = 1; i <= this.length(); i += 1) {
         f(this.values[i], i, this._names[i]);
      }
      return this;
   };

   /**
    * Takes a function `f(acc, val, i, name)` and accumulates a return value.
    * For any values with no associated name, `name` will be supplied as
    * `undefined`.
    */
   List.prototype.reduce = function reduce(f, initial) {
      var i, acc;
      acc = initial;
      for (i = 1; i <= this.length(); i += 1) {
         acc = f(acc, this.values[i], i, this._names[i]);
      }
      return acc;
   };

   /**
    * Takes a function `f(val, i, name)` and applies it to each value in this
    * list to create a new list.  For any values with no associated name,
    * `name` will be supplied as `undefined`.
    */
   List.prototype.map = function map(f) {
      var arr;
      arr = [];
      this.each(function(val, i, name) {
         arr.push(f(val, i, name));
      });
      return (new List(arr)).names(this.names().toArray());
   };

 /**
    * Returns a new Variable without changing this List.
    * Works for values which are among the following (mixed ok):
    * - single value
    * - array
    * - Vector
    * - Variable
    * - List
    * Names are generated for the new Variable.  The general idea is
    * to preserve any names in this list and/or in the values of this
    * list in some reasonble way, wherever they exist.
    * - If variable with names, and list entry also named, join the names
    * - If variable with names, and list entry not named, use variable name
    * - If variable without names, and list entry named, provide lname.1, ...
    */
   List.prototype.toVariable = function toVariable() {
      var resolvedEntries;
      resolvedEntries = this.get().map(function(val, i) {
         if (val instanceof List) { return val.toVariable(); }
         if (val instanceof Variable) { return val.clone(); }
         if (val instanceof Variable.Vector ||
             Array.isArray(val)) { return new Variable(val); }
         // Single value. turn into a Variable
         return new Variable([val]);
      });
      resolvedEntries.forEach(function(val, i) {
         val.names(joinNames(this.names(i + 1),
                             val.names(),
                             val.length()));
      }.bind(this));
      return Variable.concat.apply(null, resolvedEntries);
   };

   /**
    * Unnests a number of levels out of a nested list, starting at the
    * top level. This operation changes the list in _in place_.
    * `levels` is the number of levels it will attempt to unnest.
    * Level 0 indicates no change. Default is 1.
    * Level Infinity indicates complete unnesting.
    */
   List.prototype.unnest = function unnest(levels) {
      var i;
      if (arguments.length === 0) { levels = 1; }
      if (levels === 0) { return this; }
      if (levels > 1) {
         this.each(function(e) {
            if (e instanceof List) { e.unnest(levels - 1); }
         });
      }
      for (i = this.length(); i > 0; i -= 1) {
         if (this.values[i] instanceof List) {
            [].splice.apply(this._names,
               [i, 1].concat(
                  joinNames(this._names[i],
                            this.values[i].names(),
                            this.values[i].length()
                  )
               )
            );
            [].splice.apply(this.values,
               [i, 1].concat(this.values[i].get())
            );
         }
      }
      return this;
   };

   /* Helper methods */
   function joinNames(itemName, valueNames, length) {
      if (utils.isMissing(itemName)) {
         return Variable.ensureArray(valueNames);
      }
      if (utils.isMissing(valueNames)) {
         if (length === 1) { return [itemName]; }
         valueNames = Variable.Vector.seq(length);
      }
      return Variable.ensureArray(valueNames)
                     .map(function(s) { return itemName + '.' + s; });
   }

   return List;

});

}(typeof define === 'function' && define.amd ? define : function(factory) {
   'use strict';
   module.exports = factory(require);
}));
<commit_msg>List#map should allow missing names.<commit_after>/**
 * Representation of "Lists"
 * @module List
 * @author Haris Skiadas <skiadas@hanover.edu>
 * Barb Wahl <wahl@hanover.edu>
 * Bill Altermatt <altermattw@hanover.edu>
 */
(function(define) {'use strict';
define(function(require) {

   var Variable, utils;

   utils = require('./utils');
   Variable = require('./variable');

   /**
    * Lists are essentially objects that can be accessed by array indexing as well.
    * One can remove a "property" from a list, which results in the other properties
    * shifting place.
    *
    * Indexing starts at 1.
    *
    * List Properties:
    * - Array of values.
    * - Object that holds names as keys and array indices as values.
    *
    * To create a list:
    * - object
    * - array of unnamed values
    * - with no argument, create empty list
    */
   function List(values) {
      if (!(this instanceof List)) { return new List(values); }
      if (Array.isArray(values)) {
         this.values = [utils.missing].concat(values);
         this._names = this.values.map(function() { return utils.missing; });
      } else {
         // Given an object. Need to populate array based on it
         this._names = [utils.missing].concat(Object.keys(values || {}));
         this.values = this._names.map(function(key) {
            return utils.isMissing(key) ? key : values[key];
         });
      }
   }

   List.prototype = Object.create({});

   /* eslint-disable complexity */
   /**
    * this.names();
    * this.names(i);
    * this.names(i, newName);  // newName is a string or null (or evals to missing)
    * this.names(newNames);    // Array or Variable of strings/nulls
    */
   List.prototype.names = function names(i, newNames) {
      if (arguments.length === 0) {
         return utils.allMissing(this._names) ? utils.missing
                                              : Variable.string(this._names.slice(1));
      }
      if (arguments.length > 1) {
         this._names[i] = newNames;
      } else { // one argument, `i`
         if (utils.isMissing(i)) {
            this._names = this.values.map(function() { return utils.missing; });
            return this;
         }
         if (i instanceof Variable) { i = i.asString().toArray(); }
         if (!Array.isArray(i)) { return this._names[i]; }
         if (i.length !== this.length()) {
            throw new Error('Incompatible names length');
         }
         this._names = [utils.missing].concat(i);
      }
      return this;
   };
   /* eslint-enable */

   List.prototype.length = function length() {
      return this.values.length - 1;
   };

   /**
    * i can be:
    * - index
    * - string name
    * - null/missing (return the array of values)
    */
   List.prototype.get = function get(i) {
      if (utils.isMissing(i)) { return this.values.slice(1); }
      if (typeof i !== 'number') {
         i = this._names.indexOf(i);
         if (i === -1) { return utils.missing; }
      }
      return this.values[i];
   };

   /**
    * i can be:
    * - index:  If i > length of list, create new item at index i and fill the
    *           gap with missing
    * - string (name):  If i is not already a name in the list, append new item
    *                   with name `i`.  Else, update existing item with new value.
    * - object of name-value pairs (update existing, append new)
    * - array of values (append new)
    * val can be any sort of thing.
    * omit `val` if `i` is an object or array.
    */
   List.prototype.set = function set(i, val) {
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number' || typeof i === 'string') {
         return this._set(i, val);
      }
      if (Array.isArray(i)) {
         i.forEach(function(v) {
            this._set(this.length() + 1, v);
         }.bind(this));
      } else {
         // i is an object
         Object.keys(i).forEach(function(key) {
            this._set(key, i[key]);
         }.bind(this));
      }
      return this;
   };

   // for setting exactly one value
   // `i` is a positive int or a name string
   // val is a thing
   List.prototype._set = function _set(i, val) {
      var name;
      if (utils.isMissing(i)) { return this; }
      if (typeof i === 'number') {
         i = Math.floor(i);
         if (i < 1) { throw new Error('cannot set at negative index: ' + i); }
         this.values[i] = val;
      } else {
         name = i;
         i = this._names.indexOf(name);
         if (i === -1) { // append
            i = this.length() + 1;
            this._names[i] = name;
         }
         this.values[i] = val;
      }
      return this;
   };

   /**
    * Delete the item in the `i` position (i integer or string)
    */
   List.prototype.delete = function _delete(i) {
    if (utils.isMissing(i)) { return this; }
    if (typeof i !== 'number') { i = this._names.indexOf(i); }
    if (i >= 1) {
      this.values.splice(i, 1);
      this._names.splice(i, 1);
    }
    return this;
   };

   /**
   * Takes a function `f(val, i, name)` and applies it to each value in this
   * list.  For any values with no associated name, `name` will be supplied as
   * `undefined`.
   */
   List.prototype.each = function each(f) {
      var i;
      for (i = 1; i <= this.length(); i += 1) {
         f(this.values[i], i, this._names[i]);
      }
      return this;
   };

   /**
    * Takes a function `f(acc, val, i, name)` and accumulates a return value.
    * For any values with no associated name, `name` will be supplied as
    * `undefined`.
    */
   List.prototype.reduce = function reduce(f, initial) {
      var i, acc;
      acc = initial;
      for (i = 1; i <= this.length(); i += 1) {
         acc = f(acc, this.values[i], i, this._names[i]);
      }
      return acc;
   };

   /**
    * Takes a function `f(val, i, name)` and applies it to each value in this
    * list to create a new list.  For any values with no associated name,
    * `name` will be supplied as `undefined`.
    */
   List.prototype.map = function map(f) {
      var arr;
      arr = [];
      this.each(function(val, i, name) {
         arr.push(f(val, i, name));
      });
      return (new List(arr)).names(
         utils.isMissing(this.names()) ? utils.missing : this.names().toArray()
      );
   };

 /**
    * Returns a new Variable without changing this List.
    * Works for values which are among the following (mixed ok):
    * - single value
    * - array
    * - Vector
    * - Variable
    * - List
    * Names are generated for the new Variable.  The general idea is
    * to preserve any names in this list and/or in the values of this
    * list in some reasonble way, wherever they exist.
    * - If variable with names, and list entry also named, join the names
    * - If variable with names, and list entry not named, use variable name
    * - If variable without names, and list entry named, provide lname.1, ...
    */
   List.prototype.toVariable = function toVariable() {
      var resolvedEntries;
      resolvedEntries = this.get().map(function(val, i) {
         if (val instanceof List) { return val.toVariable(); }
         if (val instanceof Variable) { return val.clone(); }
         if (val instanceof Variable.Vector ||
             Array.isArray(val)) { return new Variable(val); }
         // Single value. turn into a Variable
         return new Variable([val]);
      });
      resolvedEntries.forEach(function(val, i) {
         val.names(joinNames(this.names(i + 1),
                             val.names(),
                             val.length()));
      }.bind(this));
      return Variable.concat.apply(null, resolvedEntries);
   };

   /**
    * Unnests a number of levels out of a nested list, starting at the
    * top level. This operation changes the list in _in place_.
    * `levels` is the number of levels it will attempt to unnest.
    * Level 0 indicates no change. Default is 1.
    * Level Infinity indicates complete unnesting.
    */
   List.prototype.unnest = function unnest(levels) {
      var i;
      if (arguments.length === 0) { levels = 1; }
      if (levels === 0) { return this; }
      if (levels > 1) {
         this.each(function(e) {
            if (e instanceof List) { e.unnest(levels - 1); }
         });
      }
      for (i = this.length(); i > 0; i -= 1) {
         if (this.values[i] instanceof List) {
            [].splice.apply(this._names,
               [i, 1].concat(
                  joinNames(this._names[i],
                            this.values[i].names(),
                            this.values[i].length()
                  )
               )
            );
            [].splice.apply(this.values,
               [i, 1].concat(this.values[i].get())
            );
         }
      }
      return this;
   };

   /* Helper methods */
   function joinNames(itemName, valueNames, length) {
      if (utils.isMissing(itemName)) {
         return Variable.ensureArray(valueNames);
      }
      if (utils.isMissing(valueNames)) {
         if (length === 1) { return [itemName]; }
         valueNames = Variable.Vector.seq(length);
      }
      return Variable.ensureArray(valueNames)
                     .map(function(s) { return itemName + '.' + s; });
   }

   return List;

});

}(typeof define === 'function' && define.amd ? define : function(factory) {
   'use strict';
   module.exports = factory(require);
}));
<|endoftext|>


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

'use strict';

/*global process */

// Usage: node bin/adhoc.js <serviceName> <port>
// Creates a service on localhost, connected to Autobahn on localhost.

var os = require('os');
var console = require('console');

var TChannel = require('../');
var HyperbahnClient = require('../hyperbahn/');

if (require.main === module) {
    main();
}

function main() {
    if (!process.argv[2]) {
        throw new Error('need serviceName');
    }
    if (!process.argv[3]) {
        throw new Error('need a port');
    }

    /*eslint no-console: 0*/
    var serviceName = process.argv[2];
    var port = +process.argv[3];
    var host = getHost();
    var autobahnPort = 21300;
    var autobahnHost = host;

    var tchannel = new TChannel({});

    var logtron = tchannel.logger;

    tchannel.makeSubChannel({
        serviceName: serviceName
    }).register('echo', function echo(req, res, arg2, arg3) {
        res.sendOk(arg2, arg3);
    });

    var hyperbahnClient = new HyperbahnClient({
        tchannel: tchannel,
        serviceName: serviceName,
        hostPortList: [
            autobahnHost + ':' + autobahnPort
        ],
        forwardRetries: 5,
        checkForwardListInterval: 60000,
        advertisementTimeout: 5000,
        logger: logtron
    });

    console.log('service', serviceName, 'port', port);

    tchannel.listen(port, host, function onListen(err) {
        if (err) {
            throw err;
        }

        console.log('listening', tchannel.address());
        console.log('advertising', autobahnHost, autobahnPort);

        hyperbahnClient.on('advertised', function onAdvertised(err2) {
            if (err2) {
                throw err2;
            }

            console.log('advertised');
        });
        hyperbahnClient.advertise();
    });
}

function getHost() {
    var ifaces = os.networkInterfaces();
    var ifaceNames = Object.keys(ifaces);
    for (var index = 0; index < ifaceNames.length; index++) {
        var ifaceName = ifaceNames[index];
        var ports = ifaces[ifaceName];
        for (var portIndex = 0; portIndex < ports.length; portIndex++) {
            var port = ports[portIndex];
            if (!port.internal && port.family === 'IPv4') {
                return port.address;
            }
        }
    }
}
<commit_msg>fix the adhoc example<commit_after>#!/usr/bin/env node
// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

/*global process */

// Usage: node bin/adhoc.js <serviceName> <port>
// Creates a service on localhost, connected to Autobahn on localhost.

var os = require('os');
var console = require('console');

var TChannel = require('../');
var HyperbahnClient = require('../hyperbahn/');

if (require.main === module) {
    main();
}

function main() {
    if (!process.argv[2]) {
        throw new Error('need serviceName');
    }
    if (!process.argv[3]) {
        throw new Error('need a port');
    }

    /*eslint no-console: 0*/
    var serviceName = process.argv[2];
    var port = +process.argv[3];
    var host = getHost();
    var autobahnPort = 21300;
    var autobahnHost = host;

    var tchannel = new TChannel({});

    var logtron = tchannel.logger;

    tchannel.makeSubChannel({
        serviceName: serviceName
    }).register('echo', function echo(req, res, arg2, arg3) {
        res.headers.as = 'raw';
        res.sendOk(arg2, arg3);
    });

    var hyperbahnClient = new HyperbahnClient({
        tchannel: tchannel,
        serviceName: serviceName,
        hostPortList: [
            autobahnHost + ':' + autobahnPort
        ],
        forwardRetries: 5,
        checkForwardListInterval: 60000,
        advertisementTimeout: 5000,
        logger: logtron
    });

    console.log('service', serviceName, 'port', port);

    tchannel.listen(port, host, function onListen(err) {
        if (err) {
            throw err;
        }

        console.log('listening', tchannel.address());
        console.log('advertising', autobahnHost, autobahnPort);

        hyperbahnClient.on('advertised', function onAdvertised(err2) {
            if (err2) {
                throw err2;
            }

            console.log('advertised');
        });
        hyperbahnClient.advertise();
    });
}

function getHost() {
    var ifaces = os.networkInterfaces();
    var ifaceNames = Object.keys(ifaces);
    for (var index = 0; index < ifaceNames.length; index++) {
        var ifaceName = ifaceNames[index];
        var ports = ifaces[ifaceName];
        for (var portIndex = 0; portIndex < ports.length; portIndex++) {
            var port = ports[portIndex];
            if (!port.internal && port.family === 'IPv4') {
                return port.address;
            }
        }
    }
}
<|endoftext|>


<commit_before>#! /usr/bin/env node
var fs = require('fs');
var program = require('commander');
var uglifyJs = require('uglify-js');
var pkgs = [];
var releaseContent = [];
program
	.option('-o, --output <path>', 'Output file', String)
	.option('-e, --template-engine', 'Include template engine')
	.option('-i, --item', 'Include ItemPaginator')
	.option('-s, --search', 'Include SearchPaginator')
	.option('-t, --template', 'Include TemplatePaginator')
	.option('-a, --all', 'Include all: Template Engine, ItemPaginator, SearchPaginator, TemplatePaginator')
	.parse(process.argv);

if (program.all) {
	pkgs.push('template');
	pkgs.push('item_paginator');
	pkgs.push('search_paginator');
	pkgs.push('template_paginator');
} else {
	if (program.templateEngine) {
		pkgs.push('template');
	}
	if (program.item) {
		pkgs.push('item_paginator');
	}
	if (program.search) {
		pkgs.push('search_paginator');
	}
	if (program.template) {
		pkgs.push('template_paginator');
	}
}

releaseContent.push(fs.readFileSync('./lib/browser.js'));
releaseContent.push(fs.readFileSync('./lib/pagination.js'));
pkgs.forEach(function(m) {
	releaseContent.push(fs.readFileSync('./lib/' + m + '.js'));
	releaseContent.push('exports.module(pagination, pagination.util);');
});
var content = releaseContent.join(";");
console.log(content);
var minified = uglifyJs.minify(content, {fromString: true});

if (program.output) {
	fs.writeFileSync(program.output, minified.code);
} else {
	console.log(minified.code);
}

<commit_msg>run console only when we want to see the code<commit_after>#! /usr/bin/env node
var fs = require('fs');
var program = require('commander');
var uglifyJs = require('uglify-js');
var pkgs = [];
var releaseContent = [];
program
	.option('-o, --output <path>', 'Output file', String)
	.option('-e, --template-engine', 'Include template engine')
	.option('-i, --item', 'Include ItemPaginator')
	.option('-s, --search', 'Include SearchPaginator')
	.option('-t, --template', 'Include TemplatePaginator')
	.option('-a, --all', 'Include all: Template Engine, ItemPaginator, SearchPaginator, TemplatePaginator')
	.parse(process.argv);

if (program.all) {
	pkgs.push('template');
	pkgs.push('item_paginator');
	pkgs.push('search_paginator');
	pkgs.push('template_paginator');
} else {
	if (program.templateEngine) {
		pkgs.push('template');
	}
	if (program.item) {
		pkgs.push('item_paginator');
	}
	if (program.search) {
		pkgs.push('search_paginator');
	}
	if (program.template) {
		pkgs.push('template_paginator');
	}
}

releaseContent.push(fs.readFileSync('./lib/browser.js'));
releaseContent.push(fs.readFileSync('./lib/pagination.js'));
pkgs.forEach(function(m) {
	releaseContent.push(fs.readFileSync('./lib/' + m + '.js'));
	releaseContent.push('exports.module(pagination, pagination.util);');
});
var content = releaseContent.join(";");
var minified = uglifyJs.minify(content, {fromString: true});

if (program.output) {
	fs.writeFileSync(program.output, minified.code);
} else {
	console.log(content);
	console.log(minified.code);
}

<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict'

var argv = require('minimist')(process.argv.slice(2))

var trelloHelperLib = require("../lib")({
  trelloKey: process.env.TRELLO_KEY,
  trelloToken: process.env.TRELLO_TOKEN,
  trelloBoard: process.env.TRELLO_BOARD,
  trelloLabel: process.env.TRELLO_LABEL
})

if (_.intersection(['today', 't'], argv._).length !== 0) {
  trelloHelperLib.createToday()
} else if (_.intersection(['duplicates', 'd', 'dupes', 'dedupe'], argv._).length !== 0) {
  trelloHelperLib.removeDuplicates()
} else {
  console.log('No argument supplied.')
  process.exit(1);
}
<commit_msg>Added lodash<commit_after>#!/usr/bin/env node
'use strict'

var argv = require('minimist')(process.argv.slice(2))
var _ = require('lodash')

var trelloHelperLib = require("../lib")({
  trelloKey: process.env.TRELLO_KEY,
  trelloToken: process.env.TRELLO_TOKEN,
  trelloBoard: process.env.TRELLO_BOARD,
  trelloLabel: process.env.TRELLO_LABEL
})

if (_.intersection(['today', 't'], argv._).length !== 0) {
  trelloHelperLib.createToday()
} else if (_.intersection(['duplicates', 'd', 'dupes', 'dedupe'], argv._).length !== 0) {
  trelloHelperLib.removeDuplicates()
} else {
  console.log('No argument supplied.')
  process.exit(1);
}
<|endoftext|>