<commit_before>(function() {
    function resetCanvas () {
        ctx.canvas.height = window.innerHeight;
        ctx.canvas.width = window.innerWidth;

        ctx.strokeStyle = "gray";
        ctx.textBaseline = "middle";

        blockSize = Math.min(ctx.canvas.height/20, ctx.canvas.width/17);
        blockSize = Math.floor(blockSize);

        ctx.font = (blockSize*0.75)+"px monospace";
    }

    function drawBlock (x, y) {
        ctx.beginPath();
        ctx.rect(x*blockSize, y*blockSize, blockSize, blockSize);
        ctx.fill();
        ctx.stroke();
    }

    function drawGrid (grid, border, drawEmpty) {
        border = border || 0;

        for (var i = 0; i < grid.length - border; i++) {
            for (var j = border; j < grid[i].length - border; j++) {
                if (drawEmpty || grid[i][j]) {
                    ctx.fillStyle = COLOURS[grid[i][j]];
                    drawBlock(j - border, i);
                }
            }
        }
    }

    function draw () {
        if (!game.board) return;
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

        ctx.save();

        if (game.pause) ctx.globalAlpha = 0.5;

        drawGrid(game.board, 2, true);

        ctx.save();
        ctx.translate((game.pieceX-2) * blockSize, (game.pieceY) * blockSize);
        drawGrid(game.currentPiece);
        ctx.restore();

        ctx.save();
        ctx.translate(12 * blockSize, 2 * blockSize);
        drawGrid(game.nextPiece, 0, true);
        ctx.restore();

        if (!game.pause) {
            var ghostDistance = 0;
            while (!checkCollision(game.currentPiece, game.pieceX, game.pieceY+ghostDistance+1)) ghostDistance++;
            if (ghostDistance) {
                ctx.save();
                ctx.globalAlpha *= 0.5;
                ctx.translate((game.pieceX-2) * blockSize, (game.pieceY+ghostDistance) * blockSize);
                drawGrid(game.currentPiece);
                ctx.restore();
            }
        }

        ctx.save();
        ctx.translate(12 * blockSize, (18-game.switchPiece.length) * blockSize);
        drawGrid(game.switchPiece, 0, true);
        ctx.restore();

        ctx.restore();

        ctx.fillStyle = (game.pause && !game.over) ? "#666" : "#000";
        ctx.fillText("Lines: "+game.lines, 12 * blockSize, 10 * blockSize);

        if (game.over) {
            ctx.save();
            ctx.strokeStyle = "#F00";
            ctx.lineWidth = 2;
            ctx.font = "bold "+(blockSize*3)+"px monospace";
            ctx.textAlign = "center";
            ctx.fillText("GAME", 5*blockSize, 7.5*blockSize);
            ctx.strokeText("GAME", 5*blockSize, 7.5*blockSize);
            ctx.fillText("OVER", 5*blockSize, 13*blockSize);
            ctx.strokeText("OVER", 5*blockSize, 13*blockSize);
            ctx.restore();
        }
    }

    function transpose (piece) {
        var newPiece = [];

        for (var i = 0; i < piece[0].length; i++) {
            var newLine = [];

            for (var j = 0; j < piece.length; j++) {
                newLine.push(piece[j][i]);
            }

            newPiece[i] = newLine;
        }
        return newPiece;
    }
    function reverseRows (piece) {
        var newPiece = [];

        for (var i = 0; i < piece.length; i++) {
            newPiece[i] = [];

            for (var j = 0; j < piece[i].length; j++) {
                newPiece[i][j] = piece[i][piece[i].length-j-1];
            }
        }
        return newPiece;
    }
    function rotateCW () {
        var newPiece = reverseRows(transpose(game.currentPiece));
        if (!checkCollision(newPiece, game.pieceX, game.pieceY)) {
            game.currentPiece = newPiece;
            draw();
        }
        else { // Kick it
            if (!checkCollision(newPiece, game.pieceX, game.pieceY+1)) {
                game.currentPiece = newPiece;
                game.pieceY++;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX+1, game.pieceY)) {
                game.currentPiece = newPiece;
                game.pieceX++;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX-1, game.pieceY)) {
                game.currentPiece = newPiece;
                game.pieceX--;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX+1, game.pieceY+1)) {
                game.currentPiece = newPiece;
                game.pieceX++;
                game.pieceY++;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX-1, game.pieceY+1)) {
                game.currentPiece = newPiece;
                game.pieceX--;
                game.pieceY++;
                draw();
            }
        }
    }

    function moveLeft() {
        if (!checkCollision(game.currentPiece, game.pieceX-1, game.pieceY)) {
            game.pieceX--;
            draw();
        }
    }

    function moveRight() {
        if (!checkCollision(game.currentPiece, game.pieceX+1, game.pieceY)) {
            game.pieceX++;
            draw();
        }
    }

    function hardDrop() {
        while (!softDrop());
    }

    function softDrop() {
        game.counter = 0;

        var collisionHappened = checkCollision(game.currentPiece, game.pieceX, game.pieceY+1);

        if (collisionHappened) {
            for (var i = 0; i < game.currentPiece.length; i++) {
                for (var j = 0; j < game.currentPiece[i].length; j++) {
                    if (game.currentPiece[i][j]) game.board[i+game.pieceY][j+game.pieceX] = game.currentPiece[i][j];
                }
            }

            deleteFullLines(game.pieceY, game.currentPiece.length);

            nextPiece();

            if (checkCollision(game.currentPiece, game.pieceX, game.pieceY)) gameOver();
        }
        else {
            game.pieceY++;
        }

        draw();

        return collisionHappened;
    }

    function deleteFullLines(top, length) {
        var end = Math.min(top+length, game.board.length-2);

        var linesDeleted = 0;

        for (var i = top; i < end; i++) {
            var flag = true;

            for (var j = 2; j < 12 && flag; j++) {
                flag = (game.board[i][j] > 0 && game.board[i][j] < 8);
            }

            if (flag) { // delete line
                for (var j = i; j > 0; j--) {
                    game.board[j] = Array.apply(undefined, game.board[j-1]);
                }
                game.board[0] = [8,8,0,0,0,0,0,0,0,0,0,0,8,8];
                game.lines++;
                linesDeleted++;
            }
        }

        switch (linesDeleted) {
            case 0: break;
            case 1:
                game.speed *= 0.95;
                break;
            case 2:
                game.speed *= 0.9;
                break;
            case 3:
                game.speed *= 0.8;
                break;
            case 4:
                game.speed *= 0.7;
                break;
        }
    }

    function checkCollision(piece, x, y) {
        var flag = false;

        for (var i = 0; i < piece.length; i++) {
            for (var j = 0; j < piece[i].length; j++) {
                flag = flag || (piece[i][j] && game.board[i+y][j+x]);
            }
        }

        return flag;
    }

    function switchPiece() {
        if (game.canSwitch && !checkCollision(game.switchPiece, 5, 2)) {
            game.canSwitch = false;
            game.pieceX = 5;
            game.pieceY = 0;

            var swap = game.currentPiece;
            game.currentPiece = game.switchPiece;
            game.switchPiece = swap;

            draw();
        }
    }

    function getNewPiece() {
        if (!game.nextPieces.length) {
            var list = function (array) { // shuffle
                var currentIndex = array.length, temp, randomIndex;

                while (0 !== currentIndex) {
                    randomIndex = Math.floor(Math.random() * currentIndex);
                    currentIndex--;

                    temp = array[currentIndex];
                    array[currentIndex] = array[randomIndex];
                    array[randomIndex] = temp;
                }

                return array;
            }([0,1,2,3,4,5,6]);

            console.log(list);

            for (var i = 0; i < list.length; i++) {
                game.nextPieces[i] = PIECES[list[i]];
            }
        }

        return game.nextPieces.pop();
    }

    function nextPiece() {
        game.pieceX = 5;
        game.pieceY = 0;
        game.canSwitch = true;
        game.currentPiece = game.nextPiece;
        game.nextPiece = getNewPiece();
    }

    function tick () {
        if (game.pause) return;

        if (game.counter < game.speed){
            game.counter++;
        }
        else {
            softDrop();
        }
    }

    function initListeners () {
        window.onkeydown = function(event){
            var keyCode = event.keyCode || event.which || 0;

            switch (keyCode) {
                case 13: // enter
                    if (game.over) startGame();
                    break;
                case 16: // shift
                    if (!game.pause) switchPiece();
                    break;
                case 32: // space
                    if (!game.pause) hardDrop();
                    break;
                case 37: // left
                    if (!game.pause) moveLeft();
                    break;
                case 38: // up
                    if (!game.pause) rotateCW();
                    break;
                case 39: // right
                    if (!game.pause) moveRight();
                    break;
                case 40: // down
                    if (!game.pause) softDrop();
                    break;
                case 80: // p
                    if (!game.over) {
                        game.pause = !game.pause;
                        draw();
                    }
                    break;
                case 81: // q
                    if (game.pause) gameOver();
                    break;
            }
        };

        window.onresize = function(){
            resetCanvas();
            draw();
        };
    }

    function gameOver() {
        game.over = true;
        game.pause = true;
        draw();
    }

    function startGame() {
        game.board = [
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,8,8,8,8,8,8,8,8,8,8,8,8],
            [8,8,8,8,8,8,8,8,8,8,8,8,8,8]];

        game.nextPieces = [];
        game.nextPiece = getNewPiece();
        game.switchPiece = getNewPiece();
        nextPiece();

        game.lines = 0;
        game.speed = 75;
        game.counter = 0;
        game.pause = false;
        game.over = false;

        draw();
    }

    function init () {
        resetCanvas();

        startGame();

        initListeners();

        setInterval(tick, 20);
    }

    var ctx = document.getElementsByTagName("canvas")[0].getContext("2d");
    var blockSize = 0;

    var game = {
        counter: 0,
        board: null,
        currentPiece: null,
        pieceX: 0,
        pieceY: 5,
        nextPiece: null,
        switchPiece: null,
        nextPieces: null,
        canSwitch: false,
        pause: false,
        over: false,
        lines: 0,
        speed: 0
    };

    const COLOURS = ["#111", "#F00", "#00F", "#0F0", "#0FF", "#F0F", "#FF0", "orangered", "#CCC"];

    const PIECES = [
        [ // I
            [0,0,0,0],
            [4,4,4,4],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [ // J
            [2,0,0],
            [2,2,2],
            [0,0,0]
        ],
        [ // L
            [0,0,7],
            [7,7,7],
            [0,0,0]
        ],
        [ // O
            [0,0,0,0],
            [0,6,6,0],
            [0,6,6,0],
            [0,0,0,0]
        ],
        [ // S
            [0,3,3],
            [3,3,0],
            [0,0,0],
        ],
        [ // T
            [0,5,0],
            [5,5,5],
            [0,0,0]
        ],
        [ // Z
            [1,1,0],
            [0,1,1],
            [0,0,0]
        ]
    ];

    init();

}).call();

<commit_msg>Added normalized order of pieces (every 7 pieces is a random permutation of the 7 tetrominoes)<commit_after>(function() {
    function resetCanvas () {
        ctx.canvas.height = window.innerHeight;
        ctx.canvas.width = window.innerWidth;

        ctx.strokeStyle = "gray";
        ctx.textBaseline = "middle";

        blockSize = Math.min(ctx.canvas.height/20, ctx.canvas.width/17);
        blockSize = Math.floor(blockSize);

        ctx.font = (blockSize*0.75)+"px monospace";
    }

    function drawBlock (x, y) {
        ctx.beginPath();
        ctx.rect(x*blockSize, y*blockSize, blockSize, blockSize);
        ctx.fill();
        ctx.stroke();
    }

    function drawGrid (grid, border, drawEmpty) {
        border = border || 0;

        for (var i = 0; i < grid.length - border; i++) {
            for (var j = border; j < grid[i].length - border; j++) {
                if (drawEmpty || grid[i][j]) {
                    ctx.fillStyle = COLOURS[grid[i][j]];
                    drawBlock(j - border, i);
                }
            }
        }
    }

    function draw () {
        if (!game.board) return;
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

        ctx.save();

        if (game.pause) ctx.globalAlpha = 0.5;

        drawGrid(game.board, 2, true);

        ctx.save();
        ctx.translate((game.pieceX-2) * blockSize, (game.pieceY) * blockSize);
        drawGrid(game.currentPiece);
        ctx.restore();

        ctx.save();
        ctx.translate(12 * blockSize, 2 * blockSize);
        drawGrid(game.nextPiece, 0, true);
        ctx.restore();

        if (!game.pause) {
            var ghostDistance = 0;
            while (!checkCollision(game.currentPiece, game.pieceX, game.pieceY+ghostDistance+1)) ghostDistance++;
            if (ghostDistance) {
                ctx.save();
                ctx.globalAlpha *= 0.5;
                ctx.translate((game.pieceX-2) * blockSize, (game.pieceY+ghostDistance) * blockSize);
                drawGrid(game.currentPiece);
                ctx.restore();
            }
        }

        ctx.save();
        ctx.translate(12 * blockSize, (18-game.switchPiece.length) * blockSize);
        drawGrid(game.switchPiece, 0, true);
        ctx.restore();

        ctx.restore();

        ctx.fillStyle = (game.pause && !game.over) ? "#666" : "#000";
        ctx.fillText("Lines: "+game.lines, 12 * blockSize, 10 * blockSize);

        if (game.over) {
            ctx.save();
            ctx.strokeStyle = "#F00";
            ctx.lineWidth = 2;
            ctx.font = "bold "+(blockSize*3)+"px monospace";
            ctx.textAlign = "center";
            ctx.fillText("GAME", 5*blockSize, 7.5*blockSize);
            ctx.strokeText("GAME", 5*blockSize, 7.5*blockSize);
            ctx.fillText("OVER", 5*blockSize, 13*blockSize);
            ctx.strokeText("OVER", 5*blockSize, 13*blockSize);
            ctx.restore();
        }
    }

    function transpose (piece) {
        var newPiece = [];

        for (var i = 0; i < piece[0].length; i++) {
            var newLine = [];

            for (var j = 0; j < piece.length; j++) {
                newLine.push(piece[j][i]);
            }

            newPiece[i] = newLine;
        }
        return newPiece;
    }
    function reverseRows (piece) {
        var newPiece = [];

        for (var i = 0; i < piece.length; i++) {
            newPiece[i] = [];

            for (var j = 0; j < piece[i].length; j++) {
                newPiece[i][j] = piece[i][piece[i].length-j-1];
            }
        }
        return newPiece;
    }
    function rotateCW () {
        var newPiece = reverseRows(transpose(game.currentPiece));
        if (!checkCollision(newPiece, game.pieceX, game.pieceY)) {
            game.currentPiece = newPiece;
            draw();
        }
        else { // Kick it
            if (!checkCollision(newPiece, game.pieceX, game.pieceY+1)) {
                game.currentPiece = newPiece;
                game.pieceY++;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX+1, game.pieceY)) {
                game.currentPiece = newPiece;
                game.pieceX++;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX-1, game.pieceY)) {
                game.currentPiece = newPiece;
                game.pieceX--;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX+1, game.pieceY+1)) {
                game.currentPiece = newPiece;
                game.pieceX++;
                game.pieceY++;
                draw();
            }
            else if (!checkCollision(newPiece, game.pieceX-1, game.pieceY+1)) {
                game.currentPiece = newPiece;
                game.pieceX--;
                game.pieceY++;
                draw();
            }
        }
    }

    function moveLeft() {
        if (!checkCollision(game.currentPiece, game.pieceX-1, game.pieceY)) {
            game.pieceX--;
            draw();
        }
    }

    function moveRight() {
        if (!checkCollision(game.currentPiece, game.pieceX+1, game.pieceY)) {
            game.pieceX++;
            draw();
        }
    }

    function hardDrop() {
        while (!softDrop());
    }

    function softDrop() {
        game.counter = 0;

        var collisionHappened = checkCollision(game.currentPiece, game.pieceX, game.pieceY+1);

        if (collisionHappened) {
            for (var i = 0; i < game.currentPiece.length; i++) {
                for (var j = 0; j < game.currentPiece[i].length; j++) {
                    if (game.currentPiece[i][j]) game.board[i+game.pieceY][j+game.pieceX] = game.currentPiece[i][j];
                }
            }

            deleteFullLines(game.pieceY, game.currentPiece.length);

            nextPiece();

            if (checkCollision(game.currentPiece, game.pieceX, game.pieceY)) gameOver();
        }
        else {
            game.pieceY++;
        }

        draw();

        return collisionHappened;
    }

    function deleteFullLines(top, length) {
        var end = Math.min(top+length, game.board.length-2);

        var linesDeleted = 0;

        for (var i = top; i < end; i++) {
            var flag = true;

            for (var j = 2; j < 12 && flag; j++) {
                flag = (game.board[i][j] > 0 && game.board[i][j] < 8);
            }

            if (flag) { // delete line
                for (var j = i; j > 0; j--) {
                    game.board[j] = Array.apply(undefined, game.board[j-1]);
                }
                game.board[0] = [8,8,0,0,0,0,0,0,0,0,0,0,8,8];
                game.lines++;
                linesDeleted++;
            }
        }

        switch (linesDeleted) {
            case 0: break;
            case 1:
                game.speed *= 0.95;
                break;
            case 2:
                game.speed *= 0.9;
                break;
            case 3:
                game.speed *= 0.8;
                break;
            case 4:
                game.speed *= 0.7;
                break;
        }
    }

    function checkCollision(piece, x, y) {
        var flag = false;

        for (var i = 0; i < piece.length; i++) {
            for (var j = 0; j < piece[i].length; j++) {
                flag = flag || (piece[i][j] && game.board[i+y][j+x]);
            }
        }

        return flag;
    }

    function switchPiece() {
        if (game.canSwitch && !checkCollision(game.switchPiece, 5, 2)) {
            game.canSwitch = false;
            game.pieceX = 5;
            game.pieceY = 0;

            var swap = game.currentPiece;
            game.currentPiece = game.switchPiece;
            game.switchPiece = swap;

            draw();
        }
    }

    function getNewPiece() {
        if (!game.nextPieces.length) {
            var list = function (array) { // shuffle
                var currentIndex = array.length, temp, randomIndex;

                while (0 !== currentIndex) {
                    randomIndex = Math.floor(Math.random() * currentIndex);
                    currentIndex--;

                    temp = array[currentIndex];
                    array[currentIndex] = array[randomIndex];
                    array[randomIndex] = temp;
                }

                return array;
            }([0,1,2,3,4,5,6]);

            for (var i = 0; i < list.length; i++) {
                game.nextPieces[i] = PIECES[list[i]];
            }
        }

        return game.nextPieces.pop();
    }

    function nextPiece() {
        game.pieceX = 5;
        game.pieceY = 0;
        game.canSwitch = true;
        game.currentPiece = game.nextPiece;
        game.nextPiece = getNewPiece();
    }

    function tick () {
        if (game.pause) return;

        if (game.counter < game.speed){
            game.counter++;
        }
        else {
            softDrop();
        }
    }

    function initListeners () {
        window.onkeydown = function(event){
            var keyCode = event.keyCode || event.which || 0;

            switch (keyCode) {
                case 13: // enter
                    if (game.over) startGame();
                    break;
                case 16: // shift
                    if (!game.pause) switchPiece();
                    break;
                case 32: // space
                    if (!game.pause) hardDrop();
                    break;
                case 37: // left
                    if (!game.pause) moveLeft();
                    break;
                case 38: // up
                    if (!game.pause) rotateCW();
                    break;
                case 39: // right
                    if (!game.pause) moveRight();
                    break;
                case 40: // down
                    if (!game.pause) softDrop();
                    break;
                case 80: // p
                    if (!game.over) {
                        game.pause = !game.pause;
                        draw();
                    }
                    break;
                case 81: // q
                    if (game.pause) gameOver();
                    break;
            }
        };

        window.onresize = function(){
            resetCanvas();
            draw();
        };
    }

    function gameOver() {
        game.over = true;
        game.pause = true;
        draw();
    }

    function startGame() {
        game.board = [
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,0,0,0,0,0,0,0,0,0,0,8,8],
            [8,8,8,8,8,8,8,8,8,8,8,8,8,8],
            [8,8,8,8,8,8,8,8,8,8,8,8,8,8]];

        game.nextPieces = [];
        game.nextPiece = getNewPiece();
        game.switchPiece = getNewPiece();
        nextPiece();

        game.lines = 0;
        game.speed = 75;
        game.counter = 0;
        game.pause = false;
        game.over = false;

        draw();
    }

    function init () {
        resetCanvas();

        startGame();

        initListeners();

        setInterval(tick, 20);
    }

    var ctx = document.getElementsByTagName("canvas")[0].getContext("2d");
    var blockSize = 0;

    var game = {
        counter: 0,
        board: null,
        currentPiece: null,
        pieceX: 0,
        pieceY: 5,
        nextPiece: null,
        switchPiece: null,
        nextPieces: null,
        canSwitch: false,
        pause: false,
        over: false,
        lines: 0,
        speed: 0
    };

    const COLOURS = ["#111", "#F00", "#00F", "#0F0", "#0FF", "#F0F", "#FF0", "orangered", "#CCC"];

    const PIECES = [
        [ // I
            [0,0,0,0],
            [4,4,4,4],
            [0,0,0,0],
            [0,0,0,0]
        ],
        [ // J
            [2,0,0],
            [2,2,2],
            [0,0,0]
        ],
        [ // L
            [0,0,7],
            [7,7,7],
            [0,0,0]
        ],
        [ // O
            [0,0,0,0],
            [0,6,6,0],
            [0,6,6,0],
            [0,0,0,0]
        ],
        [ // S
            [0,3,3],
            [3,3,0],
            [0,0,0],
        ],
        [ // T
            [0,5,0],
            [5,5,5],
            [0,0,0]
        ],
        [ // Z
            [1,1,0],
            [0,1,1],
            [0,0,0]
        ]
    ];

    init();

}).call();

<|endoftext|>


<commit_before>// **Github:** https://github.com/teambition/thunks
//
// **License:** MIT

/* global module, define */
;(function (root, factory) {
  'use strict';

  if (typeof module === 'object' && typeof module.exports === 'object') {
    module.exports = factory();
  } else if (typeof define === 'function' && define.amd) {
    define([], factory);
  } else {
    root.thunks = factory();
  }
}(typeof window === 'object' ? window : this, function () {
  'use strict';

  var TRUE = {},
    toString = Object.prototype.toString,
    isArray = Array.isArray || function (obj) {
      return toString.call(obj) === '[object Array]';
    };

  function isFunction(fn) {
    return typeof fn === 'function';
  }

  function isThunk(fn) {
    return isFunction(fn) && fn._isThunk === TRUE;
  }

  // fast slice for `arguments`.
  function slice(args, start) {
    var len = args.length, ret = Array(len);
    start = start || 0;
    while (len-- > start) ret[len - start] = args[len];
    return ret;
  }

  function forEach(obj, iterator, isArray) {
    if (isArray) {
      for (var i = 0, l = obj.length; i < l; i++) iterator(obj[i], i, obj);
    } else {
      for (var key in obj) {
        if (obj.hasOwnProperty(key)) iterator(obj[key], key, obj);
      }
    }
  }

  function tryRun(ctx, fn, args) {
    var result = {error: null, value: null};
    try {
      result.value = fn.apply(ctx, args);
    } catch (error) {
      result.error = error;
    }
    return result;
  }

  function toThunk(obj) {
    if (!obj) return obj;
    if (isFunction(obj)) obj = thunkFactory(obj);
    else if (isFunction(obj.toThunk)) obj = thunkFactory(obj.toThunk());
    else if (isFunction(obj.then)) obj = thunkFactory(promiseToThunk(obj));
    return obj;
  }

  function thunkFactory(thunk) {
    thunk._isThunk = TRUE;
    return thunk;
  }

  function objectToThunk(obj) {
    return function (callback) {
      var result, pending = 1, finished = false, _isArray = isArray(obj);

      if (_isArray) {
        result = Array(obj.length);
      } else if (obj && typeof obj === 'object') {
        result = {};
      }
      if (!result) return callback(new Error('Not array or object'));

      var tryResult = tryRun(null, function (obj, iterator) {
        forEach(obj, iterator, _isArray);
        if (!(--pending || finished)) callback(null, result);
      }, [obj, function (fn, index) {
        if (finished) return;
        pending++;
        fn = toThunk(fn);
        if (!isThunk(fn)) {
          result[index] = fn;
          return --pending || callback(null, result);
        }
        fn(function (error, res) {
          if (finished) return;
          if (error != null) return finished = true, callback(error);
          result[index] = arguments.length > 2 ? slice(arguments, 1) : res;
          return --pending || callback(null, result);
        });
      }]);
      if (tryResult.error) {
        finished = true;
        callback(tryResult.error);
      }
    };
  }

  function promiseToThunk(promise) {
    return function (callback) {
      promise.then(function (res) {
        callback(null, res);
      }, callback);
    };
  }

  function continuation(scope, parent, isStart) {
    var result, args = parent.result, current = parent.next, onerror = scope.onerror || callback;

    function callback() {
      if (current.result === false) return;
      current.result = arguments.length ? arguments: [null];
      if (current.callback) return continuation(scope, current);
    }

    parent.result = false;
    // debug in scope
    if (scope.debug && !isStart) scope.debug.apply(null, args);
    // onerror in scope
    if (args[0] != null) {
      args = [args[0]];
      if (scope.onerror) return onerror(args[0]);
    }

    var tryResult = tryRun(parent.ctx, parent.callback, args);
    if (tryResult.error) return onerror(tryResult.error);
    if (tryResult.value == null) return callback(null);
    result = toThunk(tryResult.value);
    if (!isThunk(result)) return callback(null, result);
    tryResult = tryRun(parent.ctx, result, [callback]);
    return tryResult.error ? onerror(tryResult.error) : null;
  }

  function thunks(options) {
    var scope = {onerror: null, debug: null};

    if (isFunction(options)) scope.onerror = options;
    else if (options) {
      if (isFunction(options.debug)) scope.debug = options.debug;
      if (isFunction(options.onerror)) scope.onerror = options.onerror;
    }

    function childThunk(parent) {
      return thunkFactory(function (callback) {
        return child(parent, callback);
      });
    }

    function child(parent, callback) {
      var current = {ctx: parent.ctx, next: null, result: null, callback: null};
      if (parent.result === false) return;
      parent.callback = callback;
      parent.next = current;
      if (parent.result) continuation(scope, parent);
      return childThunk(current);
    }

    // main function **thunk**
    function Thunk(start) {
      var current = {ctx: this === Thunk ? null : this, next: null, result: null, callback: null};

      start = toThunk(start);
      if (isThunk(start)) {
        continuation(scope, {
          ctx: current.ctx,
          next: current,
          result: [null],
          callback: function () { return start; }
        }, true);
      } else {
        current.result = start == null ? [null] : [null, start];
      }
      return childThunk(current);
    }

    Thunk.all = function (obj) {
      return Thunk.call(this, objectToThunk(obj));
    };

    Thunk.digest = function () {
      var args = arguments;
      return Thunk.call(this, function (callback) {
        callback.apply(null, args);
      });
    };

    Thunk.thunkify = function (fn) {
      var ctx = this === Thunk ? null : this;
      return function () {
        var args = slice(arguments);
        return Thunk.call(ctx || this, function (callback) {
          args.push(callback);
          fn.apply(this, args);
        });
      };
    };

    Thunk.delay = function (delay) {
      return Thunk.call(this, function (callback) {
        setTimeout(callback, delay);
      });
    };

    return Thunk;
  }

  thunks.NAME = 'thunks';
  thunks.VERSION = 'v1.2.1';
  return thunks;
}));
<commit_msg>fix slice function<commit_after>// **Github:** https://github.com/teambition/thunks
//
// **License:** MIT

/* global module, define */
;(function (root, factory) {
  'use strict';

  if (typeof module === 'object' && typeof module.exports === 'object') {
    module.exports = factory();
  } else if (typeof define === 'function' && define.amd) {
    define([], factory);
  } else {
    root.thunks = factory();
  }
}(typeof window === 'object' ? window : this, function () {
  'use strict';

  var TRUE = {},
    toString = Object.prototype.toString,
    isArray = Array.isArray || function (obj) {
      return toString.call(obj) === '[object Array]';
    };

  function isFunction(fn) {
    return typeof fn === 'function';
  }

  function isThunk(fn) {
    return isFunction(fn) && fn._isThunk === TRUE;
  }

  // fast slice for `arguments`.
  function slice(args, start) {
    start = start || 0;
    var len = args.length, ret = Array(len - start);

    while (len-- > start) ret[len - start] = args[len];
    return ret;
  }

  function forEach(obj, iterator, isArray) {
    if (isArray) {
      for (var i = 0, l = obj.length; i < l; i++) iterator(obj[i], i, obj);
    } else {
      for (var key in obj) {
        if (obj.hasOwnProperty(key)) iterator(obj[key], key, obj);
      }
    }
  }

  function tryRun(ctx, fn, args) {
    var result = {error: null, value: null};
    try {
      result.value = fn.apply(ctx, args);
    } catch (error) {
      result.error = error;
    }
    return result;
  }

  function toThunk(obj) {
    if (!obj) return obj;
    if (isFunction(obj)) obj = thunkFactory(obj);
    else if (isFunction(obj.toThunk)) obj = thunkFactory(obj.toThunk());
    else if (isFunction(obj.then)) obj = thunkFactory(promiseToThunk(obj));
    return obj;
  }

  function thunkFactory(thunk) {
    thunk._isThunk = TRUE;
    return thunk;
  }

  function objectToThunk(obj) {
    return function (callback) {
      var result, pending = 1, finished = false, _isArray = isArray(obj);

      if (_isArray) {
        result = Array(obj.length);
      } else if (obj && typeof obj === 'object') {
        result = {};
      }
      if (!result) return callback(new Error('Not array or object'));

      var tryResult = tryRun(null, function (obj, iterator) {
        forEach(obj, iterator, _isArray);
        if (!(--pending || finished)) callback(null, result);
      }, [obj, function (fn, index) {
        if (finished) return;
        pending++;
        fn = toThunk(fn);
        if (!isThunk(fn)) {
          result[index] = fn;
          return --pending || callback(null, result);
        }
        fn(function (error, res) {
          if (finished) return;
          if (error != null) return finished = true, callback(error);
          result[index] = arguments.length > 2 ? slice(arguments, 1) : res;
          return --pending || callback(null, result);
        });
      }]);
      if (tryResult.error) {
        finished = true;
        callback(tryResult.error);
      }
    };
  }

  function promiseToThunk(promise) {
    return function (callback) {
      promise.then(function (res) {
        callback(null, res);
      }, callback);
    };
  }

  function continuation(scope, parent, isStart) {
    var result, args = parent.result, current = parent.next, onerror = scope.onerror || callback;

    function callback() {
      if (current.result === false) return;
      current.result = arguments.length ? arguments: [null];
      if (current.callback) return continuation(scope, current);
    }

    parent.result = false;
    // debug in scope
    if (scope.debug && !isStart) scope.debug.apply(null, args);
    // onerror in scope
    if (args[0] != null) {
      args = [args[0]];
      if (scope.onerror) return onerror(args[0]);
    }

    var tryResult = tryRun(parent.ctx, parent.callback, args);
    if (tryResult.error) return onerror(tryResult.error);
    if (tryResult.value == null) return callback(null);
    result = toThunk(tryResult.value);
    if (!isThunk(result)) return callback(null, result);
    tryResult = tryRun(parent.ctx, result, [callback]);
    return tryResult.error ? onerror(tryResult.error) : null;
  }

  function thunks(options) {
    var scope = {onerror: null, debug: null};

    if (isFunction(options)) scope.onerror = options;
    else if (options) {
      if (isFunction(options.debug)) scope.debug = options.debug;
      if (isFunction(options.onerror)) scope.onerror = options.onerror;
    }

    function childThunk(parent) {
      return thunkFactory(function (callback) {
        return child(parent, callback);
      });
    }

    function child(parent, callback) {
      var current = {ctx: parent.ctx, next: null, result: null, callback: null};
      if (parent.result === false) return;
      parent.callback = callback;
      parent.next = current;
      if (parent.result) continuation(scope, parent);
      return childThunk(current);
    }

    // main function **thunk**
    function Thunk(start) {
      var current = {ctx: this === Thunk ? null : this, next: null, result: null, callback: null};

      start = toThunk(start);
      if (isThunk(start)) {
        continuation(scope, {
          ctx: current.ctx,
          next: current,
          result: [null],
          callback: function () { return start; }
        }, true);
      } else {
        current.result = start == null ? [null] : [null, start];
      }
      return childThunk(current);
    }

    Thunk.all = function (obj) {
      return Thunk.call(this, objectToThunk(obj));
    };

    Thunk.digest = function () {
      var args = arguments;
      return Thunk.call(this, function (callback) {
        callback.apply(null, args);
      });
    };

    Thunk.thunkify = function (fn) {
      var ctx = this === Thunk ? null : this;
      return function () {
        var args = slice(arguments);
        return Thunk.call(ctx || this, function (callback) {
          args.push(callback);
          fn.apply(this, args);
        });
      };
    };

    Thunk.delay = function (delay) {
      return Thunk.call(this, function (callback) {
        setTimeout(callback, delay);
      });
    };

    return Thunk;
  }

  thunks.NAME = 'thunks';
  thunks.VERSION = 'v1.2.1';
  return thunks;
}));
<|endoftext|>


<commit_before>/// <reference path="S:\Delivery\Aspectize.core\AspectizeIntellisenseLibrary.js" />

Global.NewChartBuilder = {

    aasService: 'NewChartBuilder',
    aasPublished: false,

    initCSS: false,

    Build: function (controlInfo) {

        if (!this.initCSS) {
            var style = document.createElement('style');
            style.innerHTML = ".hidden.dhx_chart_legend_item { display: block !important; visibility: visible !important; }";
            document.body.appendChild(style);
        }

        function buildChartAxisInfo(axis, name) {

            return {
                alpha: axis.AlphaTransparency,
                fill: axis.LineColor,
                value: '#' + name + '#',
                label: '#' + name + 'Label#',
                color: axis.LineColor,
                item: { radius: axis.ItemRadius, borderColor: axis.ItemBorderColor, color: axis.ItemColor, borderWidth: axis.ItemBorderWidth },
                line: { color: axis.LineColor, width: axis.LineWidth }
            }
        }

        function buildLegendEntry(axis) {

            return {
                text: axis.Title,
                color: axis.LineColor,
                toggle: true
            };
        }

        function buildDhtmlxChart(control) {

            var cp = control.aasChartProperties;

            var savedData = [];

            if (cp.dxChart && cp.MustRebuildChart) {
                control.innerHTML = '';
                cp.dxChart = null;
                savedData = cp.data;
            }

            if (cp.dxChart === null) {

                if (!window.dhtmlXChart) throw new Error('Missing DHTMLX integration scripts in the app.ashx file ?');

                var chartType = controlInfo.PropertyBag.Type;
                var xAxis = cp.xAxis;
                var yAxis = cp.yAxis;
                var otherYAxis = cp.otherYAxis;

                var info = { view: chartType, container: control.id };

                var cai = buildChartAxisInfo(cp.AllAxis[yAxis], yAxis);
                for (var k in cai) info[k] = cai[k];

                var min = controlInfo.PropertyBag.yStart;
                var max = controlInfo.PropertyBag.yEnd;
                var step = controlInfo.PropertyBag.yStep;

                info.lines = controlInfo.PropertyBag.hLines;
                info.disableItems = !controlInfo.PropertyBag.ShowPoints;

                info.xAxis = {
                    title: cp.AllAxis[xAxis].Title,
                    template: '#' + xAxis + 'Label#',
                    lines: false //controlInfo.PropertyBag.vLines
                };

                info.yAxis = {

                    start: getGraphBegin(min, max, step),
                    end: getGraphEnd(min, max, step),
                    step: getGraphStep(min, max, step)
                };

                if (otherYAxis.length > 0) {

                    var legend = {
                        layout: controlInfo.PropertyBag.Legendlayout,
                        align: controlInfo.PropertyBag.LegendAlign,
                        valign: "middle",
                        //marker: { width: 15, radius: 3 },
                        values: []
                    };

                    info.legend = legend;
                    legend.values.push(buildLegendEntry(cp.AllAxis[yAxis]));
                    for (var k = 0; k < otherYAxis.length; k++) {
                        legend.values.push(buildLegendEntry(cp.AllAxis[otherYAxis[k]]));
                    }
                }

                var chart = new dhtmlXChart(info);

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

                    var axisName = otherYAxis[i];

                    chart.addSeries(buildChartAxisInfo(cp.AllAxis[axisName], axisName));
                }

                if (cp.data.length > 0) {

                    Aspectize.ProtectedCall(chart, chart.parse, cp.data, 'json');

                } else Aspectize.ProtectedCall(chart, chart.refresh);

                cp.dxChart = chart;
                cp.data = savedData;

            } else {

                var dxc = cp.dxChart;

                if (cp.data.length > 0) {

                    Aspectize.ProtectedCall(dxc, dxc.parse, cp.data, 'json');

                } else Aspectize.ProtectedCall(dxc, dxc.refresh);
            }

            cp.MustRebuildChart = false;
        }

        function buildAxisProperties(index, title) {

            var colors = ['#000000', '#D4D4D4', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF'];

            var color = colors[index % colors.length];

            return {
                Title: title, ShowLine: false,
                Start: null, End: null, Step: null,
                AlphaTransparency: 0.2, LineColor: color, LineWidth: 1,
                ItemColor: color, ItemBorderColor: '#000000', ItemRadius: 4, ItemBorderWidth: 1,
                PointWidth: 50
            };
        }

        controlInfo.CreateInstance = function (ownerWindow, id) {

            var chart = Aspectize.createElement('div', ownerWindow);

            chart.aasSubControls = {};

            return chart;
        };

        controlInfo.ChangePropertyValue = function (property, newValue) {

            this.PropertyBag[property] = newValue;
        },

        controlInfo.InitGrid = function (control) {

            //control.style.height = '350px';
            control.style.height = '100%';
            control.style.width = '100%';
            control.style.minHeight = '100%';
            control.style.minWidth = '100%';

            if (control.parentNode.width) {
                control.style.width = control.parentNode.width;
            }

            control.parentNode.style.overflowX = "auto";
            control.parentNode.style.overflowY = "hidden";

            var chartType = this.PropertyBag.Type;

            var columnInfos = controlInfo.columnInfos;

            var axisCount = columnInfos.length;
            var xAxis = (axisCount > 1) ? columnInfos[0].name : null;
            var yAxis = (axisCount > 1) ? columnInfos[1].name : null;

            var otherYAxis = [];

            if (chartType !== 'pie') {
                for (var n = 2; n < axisCount; n++) otherYAxis.push(columnInfos[n].name);
            }

            control.aasChartProperties = {

                dxChart: null,
                MustRebuildChart: false,
                xAxis: xAxis, yAxis: yAxis, otherYAxis: otherYAxis, AllAxis: {},
                data: [],

                SetAxisProperty: function (axis, property, value) {

                    if (property === 'Value') {

                        var xy = (axis === this.xAxis) ? 'x' : 'y';

                        var minField = xy + 'Start';
                        var maxField = xy + 'End';

                        if (value < controlInfo.PropertyBag[minField]) {

                            controlInfo.PropertyBag[minField] = value;

                            this.MustRebuildChart = true;
                        }

                        if (value > controlInfo.PropertyBag[maxField]) {

                            controlInfo.PropertyBag[maxField] = value;

                            this.MustRebuildChart = true;
                        }

                    } else {

                        var a = this.AllAxis[axis];

                        if (a && (property in a) && (a[property] !== value)) {

                            a[property] = value;
                            this.MustRebuildChart = true;
                        }
                    }
                },

                AddData: function (chartItem) {

                    this.data.push(chartItem);
                },

                RefreshData: function (id, field, value) {

                    if (id) {

                        var index = this.dxChart.indexById(id);

                        if (index !== -1) {

                            chartData = this.data[index];

                            if (chartData[field] !== value) {

                                chartData[field] = value;
                                this.dxChart.remove(id);
                                this.dxChart.add(chartData, index);
                            }
                        }

                    } else {

                        buildDhtmlxChart(control);
                    }
                }
            };

            control.aasChartProperties.AllAxis[xAxis] = buildAxisProperties(0, xAxis);
            control.aasChartProperties.AllAxis[yAxis] = buildAxisProperties(1, yAxis);

            for (var i = 0; i < otherYAxis.length; i++) {
                control.aasChartProperties.AllAxis[otherYAxis[i]] = buildAxisProperties(2 + i, otherYAxis[i]);
            }

            buildDhtmlxChart(control);
        };

        controlInfo.InitCellControl = function (control, cellControl, rowId, rowIndex, columnIndex, columnName) {

            cellControl.aasChartProperties = control.aasChartProperties;
            cellControl.aasAxisName = columnName;
            cellControl.aasRowId = rowId;
        };

        controlInfo.BeforeRender = function (control, rowCount) {

            control.aasChartProperties.MustRebuildChart = true;
            control.aasChartProperties.data = [];
        }

        controlInfo.RowCreated = function (control, rowId, cellControls) {

            var chartItem = { id: rowId };

            for (var n = 0; n < cellControls.length; n++) {

                var cellControl = cellControls[n];

                var v = cellControl.aasControlInfo.PropertyBag.Value;
                var l = cellControl.aasControlInfo.PropertyBag.Label;

                chartItem[cellControl.aasAxisName] = v;
                chartItem[cellControl.aasAxisName + 'Label'] = l;
            }

            control.aasChartProperties.AddData(chartItem);
        };

        controlInfo.GridRendered = function (control, rowControls) {

            var xAxis = control.aasChartProperties.xAxis;

            var rowCount = rowControls.length;

            control.aasRowCount = rowCount;

            var currentWidth = control.clientWidth;

            var pointWidth = control.aasChartProperties.AllAxis[xAxis].PointWidth;

            if (currentWidth < rowCount * pointWidth) {
                control.style.width = rowCount * pointWidth + 'px';
            }
            else {
                control.style.width = control.parentNode.clientWidth + 'px';
            }

            control.aasChartProperties.RefreshData();
            //Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.clearAll);
            //Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.refresh);

            //if (rowControls.length > 0) {

            //    Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.parse, data, 'json');
            //    Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.refresh);
            //    Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.resize);
            //}
        };

        controlInfo.OnCurrentIndexChanged = function (control, currentIndex) {

        };
    }

};

Global.NewAxisBuilder = {

    aasService: 'NewAxisBuilder',
    aasPublished: false,

    Build: function (controlInfo) {

        var dataProperties = {};

        function translateToObjectProperty(p) {

            var obj = null;
            var property = null;

            if (p.indexOf('Line') === 0) obj = 'line';
            else if (p.indexOf('Item') === 0) obj = 'item';
            else obj = 'yAxis';

            switch (obj) {

                case 'line':
                case 'item': {

                    var stripedObj = p.substring(4);
                    property = stripedObj[0].toLowerCase() + stripedObj.substring(1);
                }

                case 'yAxis': {

                    property = (p === 'ShowLine') ? 'lines' : p.toLowerCase();
                }
            }

            return { Obj: obj, Property: property };
        }

        controlInfo.CreateInstance = function (ownerWindow, id) {

            var control = Aspectize.createElement('div', ownerWindow);

            controlInfo.ChangePropertyValue = function (property, newValue) {

                control.aasChartProperties.SetAxisProperty(control.aasAxisName, property, newValue);

                this.PropertyBag[property] = newValue;
                if ((property === 'Value') || (property === 'Label')) {

                    var field = (property === 'Value') ? control.aasAxisName : control.aasAxisName + 'Label';
                    control.aasChartProperties.RefreshData(control.aasRowId, field, newValue);
                }
            };

            return control;
        };
    }
};

<commit_msg>FF vLines<commit_after>/// <reference path="S:\Delivery\Aspectize.core\AspectizeIntellisenseLibrary.js" />

Global.NewChartBuilder = {

    aasService: 'NewChartBuilder',
    aasPublished: false,

    initCSS: false,

    Build: function (controlInfo) {

        if (!this.initCSS) {
            var style = document.createElement('style');
            style.innerHTML = ".hidden.dhx_chart_legend_item { display: block !important; visibility: visible !important; }";
            document.body.appendChild(style);
        }

        function buildChartAxisInfo(axis, name) {

            return {
                alpha: axis.AlphaTransparency,
                fill: axis.LineColor,
                value: '#' + name + '#',
                label: '#' + name + 'Label#',
                color: axis.LineColor,
                item: { radius: axis.ItemRadius, borderColor: axis.ItemBorderColor, color: axis.ItemColor, borderWidth: axis.ItemBorderWidth },
                line: { color: axis.LineColor, width: axis.LineWidth }
            }
        }

        function buildLegendEntry(axis) {

            return {
                text: axis.Title,
                color: axis.LineColor,
                toggle: true
            };
        }

        function buildDhtmlxChart(control) {

            var cp = control.aasChartProperties;

            var savedData = [];

            if (cp.dxChart && cp.MustRebuildChart) {
                control.innerHTML = '';
                cp.dxChart = null;
                savedData = cp.data;
            }

            if (cp.dxChart === null) {

                if (!window.dhtmlXChart) throw new Error('Missing DHTMLX integration scripts in the app.ashx file ?');

                var chartType = controlInfo.PropertyBag.Type;
                var xAxis = cp.xAxis;
                var yAxis = cp.yAxis;
                var otherYAxis = cp.otherYAxis;

                var info = { view: chartType, container: control.id };

                var cai = buildChartAxisInfo(cp.AllAxis[yAxis], yAxis);
                for (var k in cai) info[k] = cai[k];

                var min = controlInfo.PropertyBag.yStart;
                var max = controlInfo.PropertyBag.yEnd;
                var step = controlInfo.PropertyBag.yStep;

                info.lines = controlInfo.PropertyBag.hLines;
                info.disableItems = !controlInfo.PropertyBag.ShowPoints;

                info.xAxis = {
                    title: cp.AllAxis[xAxis].Title,
                    template: '#' + xAxis + 'Label#',
                    lines: controlInfo.PropertyBag.vLines
                };

                info.yAxis = {

                    start: getGraphBegin(min, max, step),
                    end: getGraphEnd(min, max, step),
                    step: getGraphStep(min, max, step)
                };

                if (otherYAxis.length > 0) {

                    var legend = {
                        layout: controlInfo.PropertyBag.Legendlayout,
                        align: controlInfo.PropertyBag.LegendAlign,
                        valign: "middle",
                        //marker: { width: 15, radius: 3 },
                        values: []
                    };

                    info.legend = legend;
                    legend.values.push(buildLegendEntry(cp.AllAxis[yAxis]));
                    for (var k = 0; k < otherYAxis.length; k++) {
                        legend.values.push(buildLegendEntry(cp.AllAxis[otherYAxis[k]]));
                    }
                }

                var chart = new dhtmlXChart(info);

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

                    var axisName = otherYAxis[i];

                    chart.addSeries(buildChartAxisInfo(cp.AllAxis[axisName], axisName));
                }

                if (cp.data.length > 0) {

                    Aspectize.ProtectedCall(chart, chart.parse, cp.data, 'json');

                } else Aspectize.ProtectedCall(chart, chart.refresh);

                cp.dxChart = chart;
                cp.data = savedData;

            } else {

                var dxc = cp.dxChart;

                if (cp.data.length > 0) {

                    Aspectize.ProtectedCall(dxc, dxc.parse, cp.data, 'json');

                } else Aspectize.ProtectedCall(dxc, dxc.refresh);
            }

            cp.MustRebuildChart = false;
        }

        function buildAxisProperties(index, title) {

            var colors = ['#000000', '#D4D4D4', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF'];

            var color = colors[index % colors.length];

            return {
                Title: title, ShowLine: false,
                Start: null, End: null, Step: null,
                AlphaTransparency: 0.2, LineColor: color, LineWidth: 1,
                ItemColor: color, ItemBorderColor: '#000000', ItemRadius: 4, ItemBorderWidth: 1,
                PointWidth: 50
            };
        }

        controlInfo.CreateInstance = function (ownerWindow, id) {

            var chart = Aspectize.createElement('div', ownerWindow);

            chart.aasSubControls = {};

            return chart;
        };

        controlInfo.ChangePropertyValue = function (property, newValue) {

            this.PropertyBag[property] = newValue;
        },

        controlInfo.InitGrid = function (control) {

            //control.style.height = '350px';
            control.style.height = '100%';
            control.style.width = '100%';
            control.style.minHeight = '100%';
            control.style.minWidth = '100%';

            if (control.parentNode.width) {
                control.style.width = control.parentNode.width;
            }

            control.parentNode.style.overflowX = "auto";
            control.parentNode.style.overflowY = "hidden";

            var chartType = this.PropertyBag.Type;

            var columnInfos = controlInfo.columnInfos;

            var axisCount = columnInfos.length;
            var xAxis = (axisCount > 1) ? columnInfos[0].name : null;
            var yAxis = (axisCount > 1) ? columnInfos[1].name : null;

            var otherYAxis = [];

            if (chartType !== 'pie') {
                for (var n = 2; n < axisCount; n++) otherYAxis.push(columnInfos[n].name);
            }

            control.aasChartProperties = {

                dxChart: null,
                MustRebuildChart: false,
                xAxis: xAxis, yAxis: yAxis, otherYAxis: otherYAxis, AllAxis: {},
                data: [],

                SetAxisProperty: function (axis, property, value) {

                    if (property === 'Value') {

                        var xy = (axis === this.xAxis) ? 'x' : 'y';

                        var minField = xy + 'Start';
                        var maxField = xy + 'End';

                        if (value < controlInfo.PropertyBag[minField]) {

                            controlInfo.PropertyBag[minField] = value;

                            this.MustRebuildChart = true;
                        }

                        if (value > controlInfo.PropertyBag[maxField]) {

                            controlInfo.PropertyBag[maxField] = value;

                            this.MustRebuildChart = true;
                        }

                    } else {

                        var a = this.AllAxis[axis];

                        if (a && (property in a) && (a[property] !== value)) {

                            a[property] = value;
                            this.MustRebuildChart = true;
                        }
                    }
                },

                AddData: function (chartItem) {

                    this.data.push(chartItem);
                },

                RefreshData: function (id, field, value) {

                    if (id) {

                        var index = this.dxChart.indexById(id);

                        if (index !== -1) {

                            chartData = this.data[index];

                            if (chartData[field] !== value) {

                                chartData[field] = value;
                                this.dxChart.remove(id);
                                this.dxChart.add(chartData, index);
                            }
                        }

                    } else {

                        buildDhtmlxChart(control);
                    }
                }
            };

            control.aasChartProperties.AllAxis[xAxis] = buildAxisProperties(0, xAxis);
            control.aasChartProperties.AllAxis[yAxis] = buildAxisProperties(1, yAxis);

            for (var i = 0; i < otherYAxis.length; i++) {
                control.aasChartProperties.AllAxis[otherYAxis[i]] = buildAxisProperties(2 + i, otherYAxis[i]);
            }

            buildDhtmlxChart(control);
        };

        controlInfo.InitCellControl = function (control, cellControl, rowId, rowIndex, columnIndex, columnName) {

            cellControl.aasChartProperties = control.aasChartProperties;
            cellControl.aasAxisName = columnName;
            cellControl.aasRowId = rowId;
        };

        controlInfo.BeforeRender = function (control, rowCount) {

            control.aasChartProperties.MustRebuildChart = true;
            control.aasChartProperties.data = [];
        }

        controlInfo.RowCreated = function (control, rowId, cellControls) {

            var chartItem = { id: rowId };

            for (var n = 0; n < cellControls.length; n++) {

                var cellControl = cellControls[n];

                var v = cellControl.aasControlInfo.PropertyBag.Value;
                var l = cellControl.aasControlInfo.PropertyBag.Label;

                chartItem[cellControl.aasAxisName] = v;
                chartItem[cellControl.aasAxisName + 'Label'] = l;
            }

            control.aasChartProperties.AddData(chartItem);
        };

        controlInfo.GridRendered = function (control, rowControls) {

            var xAxis = control.aasChartProperties.xAxis;

            var rowCount = rowControls.length;

            control.aasRowCount = rowCount;

            var currentWidth = control.clientWidth;

            var pointWidth = control.aasChartProperties.AllAxis[xAxis].PointWidth;

            if (currentWidth < rowCount * pointWidth) {
                control.style.width = rowCount * pointWidth + 'px';
            }
            else {
                control.style.width = control.parentNode.clientWidth + 'px';
            }

            control.aasChartProperties.RefreshData();
            //Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.clearAll);
            //Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.refresh);

            //if (rowControls.length > 0) {

            //    Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.parse, data, 'json');
            //    Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.refresh);
            //    Aspectize.ProtectedCall(control.aasDxChart, control.aasDxChart.resize);
            //}
        };

        controlInfo.OnCurrentIndexChanged = function (control, currentIndex) {

        };
    }

};

Global.NewAxisBuilder = {

    aasService: 'NewAxisBuilder',
    aasPublished: false,

    Build: function (controlInfo) {

        var dataProperties = {};

        function translateToObjectProperty(p) {

            var obj = null;
            var property = null;

            if (p.indexOf('Line') === 0) obj = 'line';
            else if (p.indexOf('Item') === 0) obj = 'item';
            else obj = 'yAxis';

            switch (obj) {

                case 'line':
                case 'item': {

                    var stripedObj = p.substring(4);
                    property = stripedObj[0].toLowerCase() + stripedObj.substring(1);
                }

                case 'yAxis': {

                    property = (p === 'ShowLine') ? 'lines' : p.toLowerCase();
                }
            }

            return { Obj: obj, Property: property };
        }

        controlInfo.CreateInstance = function (ownerWindow, id) {

            var control = Aspectize.createElement('div', ownerWindow);

            controlInfo.ChangePropertyValue = function (property, newValue) {

                control.aasChartProperties.SetAxisProperty(control.aasAxisName, property, newValue);

                this.PropertyBag[property] = newValue;
                if ((property === 'Value') || (property === 'Label')) {

                    var field = (property === 'Value') ? control.aasAxisName : control.aasAxisName + 'Label';
                    control.aasChartProperties.RefreshData(control.aasRowId, field, newValue);
                }
            };

            return control;
        };
    }
};

<|endoftext|>


<commit_before>import './AbortError'

import cast from 'as-type'
import chalk from 'chalk'
import readline from 'readline'

export class Command {
	app = null
	cli = null

	name = null
	description = null
	arguments = [ ]
	options = { }

	compiledValues = {
		arguments: { },
		options: { }
	}

	constructor(app, cli) {
		this.app = app
		this.cli = cli
	}

	argument(name, fallback = null) {
		return this.compiledValues.arguments[name] || fallback
	}

	containsArgument(name) {
		const value = this.compiledValues.arguments[name]
		return !value.isNil
	}

	option(name, fallback = null) {
		return this.compiledValues.options[name] || fallback
	}

	containsOption(name) {
		const value = this.compiledValues.options[name]
		return !value.isNil
	}

	ready() {
		return Promise.resolve()
	}

	run() {
		return Promise.resolve()
	}

	build(cli) {
		const command = cli.command(this.name)
		command.description(this.description)

		const usage = [ ]
		const options = Object.keys(this.options).map(key => [ key, this.options[key] ])

		if(options.length > 0) {
			usage.push('[options]')
			const shorthands = { h: true }

			for(const option of options) {
				let shorthandCharCode = option[0].charCodeAt(0)
				let shorthand = String.fromCharCode(shorthandCharCode)

				while(shorthands[shorthand] === true) {
					if(++shorthandCharCode > 122) {
						shorthandCharCode = 65
					}

					shorthand = String.fromCharCode(shorthandCharCode)
				}

				shorthands[shorthand] = true

				let flags = `-${shorthand}, --${option[0]}`

				if(typeof option[1] === 'string' || option.type.isNil) {
					flags += ' [string]'
				}

				if(typeof option[1] !== 'string') {
					option[1] = option[1].description || ''
				}

				command.option(flags, option[1])
			}
		}

		let hadOptional = false
		for(const argument of this.arguments) {
			const isOptional = argument.endsWith('?')

			if(!hadOptional && isOptional) {
				hadOptional = true
			} else if(hadOptional && !isOptional) {
				this.error(
					'Invalid arguments for %s: %s',
					this.name,
					'An optional argument can not be followed by a non-optional argument'
				)

				process.exit(1)
			}

			usage.push('<' + argument + '>')
		}

		command.usage(usage)
		command.action((...args) => this._execute(...args))

		return command
	}

	_execute(...args) {
		const cli = args.pop()

		const requiredArguments = [ ]

		for(const argument of this.arguments) {
			if(argument.endsWith('?')) {
				break
			}

			requiredArguments.push(argument)
		}

		if(args.length < requiredArguments.length) {
			this.error(
				'Not enough arguments, missing: %s',
				requiredArguments.slice(args.length).join(', ')
			)

			process.exit(1)
		} else if(args.length > this.arguments.length) {
			this.error('Too many arguments.', args)

			process.exit(1)
		}

		for(const i in args) {
			let name = this.arguments[i]

			if(name.endsWith('?')) {
				name = name.substring(0, name.length - 1)
			}

			this.compiledValues.arguments[name] = args[i]
		}

		for(const option of Object.keys(this.options)) {
			this.compiledValues.options[option] = cli[option]
		}

		process.title = 'node ' + this.name

		this.ready()
		.then(() => this.run())
		.then(() => process.exit(0))
		.catch(err => {
			if(err instanceof AbortError) {
				this.error(err.message)
			} else {
				this.error(err.message, err.stack)
			}

			process.exit(1)
		})
	}

	info(...message) {
		return this.cli.output.info(...message)
	}

	comment(...message) {
		return this.cli.output.comment(...message)
	}

	warn(...message) {
		return this.cli.output.warn(...message)
	}

	error(...message) {
		return this.cli.output.error(...message)
	}

	success(...message) {
		return this.cli.output.success(...message)
	}

	ask(question) {
		const prompt = chalk.magenta(question)

		return new Promise(resolve => {
			const iface = readline.createInterface({
				input: process.stdin,
				output: process.stdout
			})

			iface.question(`${prompt} `, answer => {
				iface.close()
				resolve((answer || '').trim())
			})
		})
	}

	confirm(question, defaultAnswer = true) {
		let prompt = `${question} ${chalk.dim(`[${defaultAnswer ? 'yes' : 'no'}]`)}`

		return this.ask(prompt, 'boolean', defaultAnswer ? 'yes' : 'no').then(answer => {
			if(answer.length === 0) {
				answer = defaultAnswer
			}

			return cast.boolean(answer)
		})
	}

}
<commit_msg>Fixed bug where option flags with a dash wouldn’t be detected properly<commit_after>import './AbortError'

import cast from 'as-type'
import chalk from 'chalk'
import readline from 'readline'

export class Command {
	app = null
	cli = null

	name = null
	description = null
	arguments = [ ]
	options = { }

	compiledValues = {
		arguments: { },
		options: { }
	}

	constructor(app, cli) {
		this.app = app
		this.cli = cli
	}

	argument(name, fallback = null) {
		return this.compiledValues.arguments[name] || fallback
	}

	containsArgument(name) {
		const value = this.compiledValues.arguments[name]
		return !value.isNil
	}

	option(name, fallback = null) {
		return this.compiledValues.options[name] || fallback
	}

	containsOption(name) {
		const value = this.compiledValues.options[name]
		return !value.isNil
	}

	ready() {
		return Promise.resolve()
	}

	run() {
		return Promise.resolve()
	}

	build(cli) {
		const command = cli.command(this.name)
		command.description(this.description)

		const usage = [ ]
		const options = Object.keys(this.options).map(key => [ key, this.options[key] ])

		if(options.length > 0) {
			usage.push('[options]')
			const shorthands = { h: true }

			for(const option of options) {
				let shorthandCharCode = option[0].charCodeAt(0)
				let shorthand = String.fromCharCode(shorthandCharCode)

				while(shorthands[shorthand] === true) {
					if(++shorthandCharCode > 122) {
						shorthandCharCode = 65
					}

					shorthand = String.fromCharCode(shorthandCharCode)
				}

				shorthands[shorthand] = true

				let flags = `-${shorthand}, --${option[0]}`

				if(typeof option[1] === 'string' || option.type.isNil) {
					flags += ' [string]'
				}

				if(typeof option[1] !== 'string') {
					option[1] = option[1].description || ''
				}

				command.option(flags, option[1])
			}
		}

		let hadOptional = false
		for(const argument of this.arguments) {
			const isOptional = argument.endsWith('?')

			if(!hadOptional && isOptional) {
				hadOptional = true
			} else if(hadOptional && !isOptional) {
				this.error(
					'Invalid arguments for %s: %s',
					this.name,
					'An optional argument can not be followed by a non-optional argument'
				)

				process.exit(1)
			}

			usage.push('<' + argument + '>')
		}

		command.usage(usage)
		command.action((...args) => this._execute(...args))

		return command
	}

	_execute(...args) {
		const cli = args.pop()

		const requiredArguments = [ ]

		for(const argument of this.arguments) {
			if(argument.endsWith('?')) {
				break
			}

			requiredArguments.push(argument)
		}

		if(args.length < requiredArguments.length) {
			this.error(
				'Not enough arguments, missing: %s',
				requiredArguments.slice(args.length).join(', ')
			)

			process.exit(1)
		} else if(args.length > this.arguments.length) {
			this.error('Too many arguments.', args)

			process.exit(1)
		}

		for(const i in args) {
			let name = this.arguments[i]

			if(name.endsWith('?')) {
				name = name.substring(0, name.length - 1)
			}

			this.compiledValues.arguments[name] = args[i]
		}

		for(const option of Object.keys(this.options)) {
			const name = option.split('-').reduce((str, word) => {
				return `${str}${word[0].toUpperCase()}${word.slice(1)}`
			})

			this.compiledValues.options[option] = cli[name]
		}

		process.title = 'node ' + this.name

		this.ready()
		.then(() => this.run())
		.then(() => process.exit(0))
		.catch(err => {
			if(err instanceof AbortError) {
				this.error(err.message)
			} else {
				this.error(err.message, err.stack)
			}

			process.exit(1)
		})
	}

	info(...message) {
		return this.cli.output.info(...message)
	}

	comment(...message) {
		return this.cli.output.comment(...message)
	}

	warn(...message) {
		return this.cli.output.warn(...message)
	}

	error(...message) {
		return this.cli.output.error(...message)
	}

	success(...message) {
		return this.cli.output.success(...message)
	}

	ask(question) {
		const prompt = chalk.magenta(question)

		return new Promise(resolve => {
			const iface = readline.createInterface({
				input: process.stdin,
				output: process.stdout
			})

			iface.question(`${prompt} `, answer => {
				iface.close()
				resolve((answer || '').trim())
			})
		})
	}

	confirm(question, defaultAnswer = true) {
		let prompt = `${question} ${chalk.dim(`[${defaultAnswer ? 'yes' : 'no'}]`)}`

		return this.ask(prompt, 'boolean', defaultAnswer ? 'yes' : 'no').then(answer => {
			if(answer.length === 0) {
				answer = defaultAnswer
			}

			return cast.boolean(answer)
		})
	}

}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import icBEM from './utils/icBEM';
import prefixClass from './utils/prefixClass';
import rowComp from './mixins/rowComp';
import './styles/Button.scss';

export const COMPONENT_NAME = prefixClass('button');
const ROOT_BEM = icBEM(COMPONENT_NAME);

const BLUE = 'blue';
const RED = 'red';
const WHITE = 'white';
const BLACK = 'black';
export const BUTTON_COLOR = { BLUE, RED, WHITE, BLACK };

function Button({
    color,
    solid,
    tagName: ButtonTag,
    // React props
    className,
    children,
    ...otherProps,
}) {
    const bemClass = ROOT_BEM
        .modifier(color)
        .modifier('solid', solid);

    const rootClassName = classNames(className, `${bemClass}`);

    // #TODO: Restore wrapper to <button> after Safari 11 goes mainstream
    return (
        <ButtonTag className={rootClassName} {...otherProps}>
            {children}
        </ButtonTag>
    );
}

Button.propTypes = {
    color: PropTypes.oneOf(Object.values(BUTTON_COLOR)),
    solid: PropTypes.bool,
    tagName: PropTypes.oneOf(['button', 'a', 'div']),
};

Button.defaultProps = {
    color: BLACK,
    solid: false,
    tagName: 'div',
};

// export for tests
export { Button as PureButton };

export default rowComp({ defaultMinified: true })(Button);
<commit_msg><Button>s are now bold by default<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import icBEM from './utils/icBEM';
import prefixClass from './utils/prefixClass';
import rowComp from './mixins/rowComp';
import './styles/Button.scss';

export const COMPONENT_NAME = prefixClass('button');
const ROOT_BEM = icBEM(COMPONENT_NAME);

const BLUE = 'blue';
const RED = 'red';
const WHITE = 'white';
const BLACK = 'black';
export const BUTTON_COLOR = { BLUE, RED, WHITE, BLACK };

function Button({
    color,
    solid,
    tagName: ButtonTag,
    // React props
    className,
    children,
    ...otherProps,
}) {
    const bemClass = ROOT_BEM
        .modifier(color)
        .modifier('solid', solid);

    const rootClassName = classNames(className, `${bemClass}`);

    // #TODO: Restore wrapper to <button> after Safari 11 goes mainstream
    return (
        <ButtonTag className={rootClassName} {...otherProps}>
            {children}
        </ButtonTag>
    );
}

Button.propTypes = {
    color: PropTypes.oneOf(Object.values(BUTTON_COLOR)),
    solid: PropTypes.bool,
    tagName: PropTypes.oneOf(['button', 'a', 'div']),
};

Button.defaultProps = {
    color: BLACK,
    solid: false,
    tagName: 'div',
};

// export for tests
export { Button as PureButton };

const RowCompButton = rowComp({ defaultMinified: true })(Button);
RowCompButton.defaultProps.bold = true;

export default RowCompButton;
<|endoftext|>


<commit_before>const uuid = require('node-uuid');

/**
 * Filter for finding out if message is a child of parentMessage
 * @param  {Object}  parentMessage the expected parent
 * @param  {Object}  message - message to evaluate lineage
 * @return {Boolean}
 */
function isChildMessage(parentMessage, message) {
  return Boolean(
    parentMessage && parentMessage.header &&
    message && message.parent_header &&
    parentMessage.header.msg_id === message.parent_header.msg_id);
}

/**
 * Create a message
 * @param  {string} username
 * @param  {string} session  guid for the session
 * @param  {string} msg_type
 * @return {object}          msg
 */
function createMessage(username, session, msg_type) {
  return {
    header: {
      username,
      session,
      msg_type,
      msg_id: uuid.v4(),
      date: new Date(),
      version: '5.0',
    },
    metadata: {},
    parent_header: {},
    content: {},
  };
}

/**
 * Send a shutdown request message
 *
 * Can also be used to restart
 * @param  {object} channels       object containing channels
 * @param  {string} username
 * @param  {string} session        guid for the session
 * @param  {boolean} restart=false should the shutdown request actually restart
 *                                 the kernel
 * @return {Promise}
 */
function shutdownRequest(channels, username, session, restart) {
  const shutDownRequest = createMessage(username, session, 'shutdown_request');
  shutDownRequest.content = { restart: Boolean(restart) };

  const shutDownReply = channels.shell
    .filter(isChildMessage.bind(null, shutDownRequest))
    .filter(msg => msg.header.msg_type === 'shutdown_reply')
    .map(msg => msg.content);

  return new Promise(resolve => {
    shutDownReply.subscribe(content => {
      if (!restart) {
        channels.shell.complete();
        channels.iopub.complete();
        channels.stdin.complete();
        channels.control.complete();
        if (channels.heartbeat) channels.heartbeat.complete();
      }
      resolve();
    });

    shell.next(shutDownRequest);
  });
}

module.exports = {
  isChildMessage,
  createMessage,
  shutdownRequest,
};
<commit_msg>Add missing `channels.`<commit_after>const uuid = require('node-uuid');

/**
 * Filter for finding out if message is a child of parentMessage
 * @param  {Object}  parentMessage the expected parent
 * @param  {Object}  message - message to evaluate lineage
 * @return {Boolean}
 */
function isChildMessage(parentMessage, message) {
  return Boolean(
    parentMessage && parentMessage.header &&
    message && message.parent_header &&
    parentMessage.header.msg_id === message.parent_header.msg_id);
}

/**
 * Create a message
 * @param  {string} username
 * @param  {string} session  guid for the session
 * @param  {string} msg_type
 * @return {object}          msg
 */
function createMessage(username, session, msg_type) {
  return {
    header: {
      username,
      session,
      msg_type,
      msg_id: uuid.v4(),
      date: new Date(),
      version: '5.0',
    },
    metadata: {},
    parent_header: {},
    content: {},
  };
}

/**
 * Send a shutdown request message
 *
 * Can also be used to restart
 * @param  {object} channels       object containing channels
 * @param  {string} username
 * @param  {string} session        guid for the session
 * @param  {boolean} restart=false should the shutdown request actually restart
 *                                 the kernel
 * @return {Promise}
 */
function shutdownRequest(channels, username, session, restart) {
  const shutDownRequest = createMessage(username, session, 'shutdown_request');
  shutDownRequest.content = { restart: Boolean(restart) };

  const shutDownReply = channels.shell
    .filter(isChildMessage.bind(null, shutDownRequest))
    .filter(msg => msg.header.msg_type === 'shutdown_reply')
    .map(msg => msg.content);

  return new Promise(resolve => {
    shutDownReply.subscribe(content => {
      if (!restart) {
        channels.shell.complete();
        channels.iopub.complete();
        channels.stdin.complete();
        channels.control.complete();
        if (channels.heartbeat) channels.heartbeat.complete();
      }
      resolve();
    });

    channels.shell.next(shutDownRequest);
  });
}

module.exports = {
  isChildMessage,
  createMessage,
  shutdownRequest,
};
<|endoftext|>


<commit_before>function encode64(data) {
	for (var r = "", i = 0, n = data.length; i < n; i += 3) {
		r += append3bytes(
			data.charCodeAt(i),
			i + 1 !== n ? data.charCodeAt(i + 1) : 0,
			i + 2 !== n ? data.charCodeAt(i + 2) : 0);
	}
	return r;
}

function append3bytes(b1, b2, b3) {
	var c1 = b1 >> 2;
	var c2 = ((b1 & 0x3) << 4) | (b2 >> 4);
	var c3 = ((b2 & 0xF) << 2) | (b3 >> 6);
	var c4 = b3 & 0x3F;
	return encode6bit(c1 & 0x3F) +
		encode6bit(c2 & 0x3F) +
		encode6bit(c3 & 0x3F) +
		encode6bit(c4 & 0x3F);
}

function encode6bit(b) {
	if (b < 10) return String.fromCharCode(48 + b);
	b -= 10;
	if (b < 26) return String.fromCharCode(65 + b);
	b -= 26;
	if (b < 26) return String.fromCharCode(97 + b);
	b -= 26;
	if (b === 0) return "-";
	if (b === 1) return "_";
	return "?";
}

function compress(s) {
	s = unescape(encodeURIComponent(s));
	return encode64(deflate(s));
}

function escapeHtml(text) {
	return text
		.replace(/&/g, "&")
		.replace(/</g, "<")
		.replace(/>/g, ">")
		.replace(/"/g, """)
		.replace(/'/g, "'");
}

[].forEach.call(document.querySelectorAll("pre[lang='uml']"), function(umlElem) {
	var parent = umlElem.parentNode;
	var plantuml = umlElem.querySelector("code").textContent.trim();
	if (plantuml.substr(0, "@start".length) !== "@start") return;

	var url = "https://www.plantuml.com/plantuml/img/" + compress(plantuml);
	var imgElem = document.createElement("img");
	imgElem.setAttribute("src", escapeHtml(url));
	imgElem.setAttribute("title", plantuml);
	parent.replaceChild(imgElem, umlElem);

	imgElem.onclick = function() {
		parent.replaceChild(umlElem, imgElem);
	};
	umlElem.onclick = function() {
		parent.replaceChild(imgElem, umlElem);
	};
});
<commit_msg>remove title attribte on img element<commit_after>function encode64(data) {
	for (var r = "", i = 0, n = data.length; i < n; i += 3) {
		r += append3bytes(
			data.charCodeAt(i),
			i + 1 !== n ? data.charCodeAt(i + 1) : 0,
			i + 2 !== n ? data.charCodeAt(i + 2) : 0);
	}
	return r;
}

function append3bytes(b1, b2, b3) {
	var c1 = b1 >> 2;
	var c2 = ((b1 & 0x3) << 4) | (b2 >> 4);
	var c3 = ((b2 & 0xF) << 2) | (b3 >> 6);
	var c4 = b3 & 0x3F;
	return encode6bit(c1 & 0x3F) +
		encode6bit(c2 & 0x3F) +
		encode6bit(c3 & 0x3F) +
		encode6bit(c4 & 0x3F);
}

function encode6bit(b) {
	if (b < 10) return String.fromCharCode(48 + b);
	b -= 10;
	if (b < 26) return String.fromCharCode(65 + b);
	b -= 26;
	if (b < 26) return String.fromCharCode(97 + b);
	b -= 26;
	if (b === 0) return "-";
	if (b === 1) return "_";
	return "?";
}

function compress(s) {
	s = unescape(encodeURIComponent(s));
	return encode64(deflate(s));
}

function escapeHtml(text) {
	return text
		.replace(/&/g, "&")
		.replace(/</g, "<")
		.replace(/>/g, ">")
		.replace(/"/g, """)
		.replace(/'/g, "'");
}

[].forEach.call(document.querySelectorAll("pre[lang='uml']"), function(umlElem) {
	var parent = umlElem.parentNode;
	var plantuml = umlElem.querySelector("code").textContent.trim();
	if (plantuml.substr(0, "@start".length) !== "@start") return;

	var url = "https://www.plantuml.com/plantuml/img/" + compress(plantuml);
	var imgElem = document.createElement("img");
	imgElem.setAttribute("src", escapeHtml(url));
	imgElem.setAttribute("title", "");
	parent.replaceChild(imgElem, umlElem);

	imgElem.onclick = function() {
		parent.replaceChild(umlElem, imgElem);
	};
	umlElem.onclick = function() {
		parent.replaceChild(imgElem, umlElem);
	};
});
<|endoftext|>


<commit_before>import Webiny from 'Webiny';
import AnimationSets from './../../Animate/AnimationSets';

const Ui = Webiny.Ui.Components;
const mountedDialogs = [];

function getShownDialog(id = null) {
    return _.find(mountedDialogs, item => item.state.isShown === true && item.id !== id);
}

class Dialog extends Webiny.Ui.Component {

    constructor(props) {
        super(props);
        this.id = _.uniqueId('modal-dialog-');

        this.state = {
            isShown: false,
            isDialogShown: false
        };

        this.clickStartedOnBackdrop = false;
        if (!document.querySelector(props.modalContainerTag)) {
            document.body.appendChild(document.createElement(props.modalContainerTag));
        }

        this.modalContainer = document.querySelector(props.modalContainerTag);

        this.bindMethods('show,hide,bindHandlers,unbindHandlers,prepareChildren,prepareChild,animationFinish');
    }

    componentWillUpdate(nextProps, nextState) {
        super.componentWillUpdate(nextProps, nextState);
        const currentDialog = getShownDialog();

        // Hide currently visible dialog but do not unmount it
        if (currentDialog && currentDialog.id !== this.id && nextState.isShown) {
            const container = $(currentDialog.modalContainer);
            const modal = container.find('.modal');
            const backdrop = container.find('.modal-backdrop');

            dynamics.animate(backdrop[0], {
                opacity: 0
            }, {
                type: dynamics.easeInOut,
                duration: 220
            });

            dynamics.animate(modal[0], {
                opacity: 0
            }, {
                type: dynamics.easeOut,
                duration: 250,
                complete: () => modal.hide()
            });
        }
    }

    componentDidUpdate(prevProps, prevState) {
        super.componentDidUpdate(prevProps, prevState);
        if (this.isShown()) {
            ReactDOM.render(this.props.renderDialog.call(this), this.modalContainer);
            $(this.modalContainer).find('.modal').focus();
            this.bindHandlers();
        } else if (prevState.isShown && !this.isShown()) {
            this.unbindHandlers();
            ReactDOM.unmountComponentAtNode(this.modalContainer);
        }

        // Show previous dialog if it was hidden
        if (!this.isShown()) {
            const prevDialog = getShownDialog(this.id);
            if (prevDialog) {
                const prevContainer = $(prevDialog.modalContainer);
                const prevModal = prevContainer.find('.modal');
                const prevBackdrop = prevContainer.find('.modal-backdrop');
                prevModal.show();
                dynamics.animate(prevModal[0], {
                    opacity: 1
                }, {
                    type: dynamics.easeIn,
                    duration: 250
                });

                dynamics.animate(prevBackdrop[0], {
                    opacity: 0.8
                }, {
                    type: dynamics.easeIn,
                    duration: 100
                });
            }
        }
    }

    componentDidMount() {
        super.componentDidMount();
        mountedDialogs.push(this);
    }

    componentWillUnmount() {
        super.componentWillUnmount();
        this.unbindHandlers();
        mountedDialogs.splice(_.findIndex(mountedDialogs, {id: this.id}), 1);
        ReactDOM.unmountComponentAtNode(this.modalContainer);
    }

    shouldComponentUpdate(nextProps, nextState) {
        return !_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state);
    }

    bindHandlers() {
        this.unbindHandlers();
        const namespace = '.' + this.id;
        $(this.props.modalContainerTag).on('keyup' + namespace, '.modal', e => {
            // Listen for ESC button
            if (e.keyCode === 27) {
                this.hide();
            }
        }).on('mousedown' + namespace, '.modal', e => {
            // Catch backdrop click
            if ($(e.target).hasClass('modal')) {
                this.clickStartedOnBackdrop = true;
            }
        }).on('click' + namespace, '.modal', () => {
            if (this.clickStartedOnBackdrop && this.props.closeOnClick) {
                this.hide();
            }
            this.clickStartedOnBackdrop = false;
        });
    }

    unbindHandlers() {
        $(this.props.modalContainerTag).off('.' + this.id);
    }

    hide() {
        if (!this.state.isShown) {
            return Q(true);
        }
        this.props.onHide();

        return new Promise(resolve => {
            this.hideResolve = resolve;
            this.setState({
                isDialogShown: false
            });
        });
    }

    show() {
        // This shows the modal container element in case it was previously hidden by another dialog
        this.props.onShow();

        return new Promise(resolve => {
            this.setState({
                isShown: true
            }, () => {
                this.setState({
                    isDialogShown: true
                }, () => {
                    this.props.onShown();
                    resolve();
                });
            });
        });
    }

    isShown() {
        return this.state.isShown;
    }

    prepareChild(child) {
        if (typeof child !== 'object' || child === null) {
            return child;
        }

        const props = {dialog: this};
        if (child.type === Ui.Modal.Header) {
            props['onClose'] = this.hide;
        }

        return React.cloneElement(child, props);
    }

    prepareChildren(children) {
        if (typeof children !== 'object' || children === null) {
            return children;
        }
        return React.Children.map(children, this.prepareChild);
    }

    animationFinish(isDialogShown) {
        if (!isDialogShown) {
            this.setState({isShown: false}, this.props.onHidden);
        }
        this.hideResolve();
    }
}

Dialog.defaultProps = {
    wide: false,
    onHide: _.noop,
    onHidden: _.noop,
    onShow: _.noop,
    onShown: _.noop,
    closeOnClick: true,
    modalContainerTag: 'webiny-modal',
    style: {},
    renderDialog() {
        const className = this.classSet({modal: true, 'modal-wizard': this.props.wide});
        return (

                <Ui.Animate
                    trigger={this.state.isDialogShown}
                    show={{opacity: 0.8, duration: 100, ease: 'linear'}}
                    hide={{opacity: 0, duration: 100, ease: 'linear'}}>

                </Ui.Animate>

                    <Ui.Animate
                        trigger={this.state.isDialogShown}
                        onFinish={this.animationFinish}
                        show={{translateY: 50, ease: 'spring', duration: 800}}
                        hide={{translateY: -100, ease: 'easeOut', opacity: 0, duration: 250}}>

                                {this.prepareChildren(this.props.children)}

                    </Ui.Animate>

        );
    },
    renderer() {
        return null;
    }
};

export default Dialog;<commit_msg>Improved ClickConfirm animations on modal dialogs<commit_after>import Webiny from 'Webiny';
import AnimationSets from './../../Animate/AnimationSets';

const Ui = Webiny.Ui.Components;
const mountedDialogs = [];

function getShownDialog(id = null) {
    return _.find(mountedDialogs, item => item.state.isShown === true && item.id !== id);
}

class Dialog extends Webiny.Ui.Component {

    constructor(props) {
        super(props);
        this.id = _.uniqueId('modal-dialog-');

        this.state = {
            isShown: false,
            isDialogShown: false
        };

        this.modalShowDuration = 800;
        this.modalHideDuration = 250;
        this.backdropShowDuration = 100;
        this.backdropHideDuration = 100;

        this.clickStartedOnBackdrop = false;
        if (!document.querySelector(props.modalContainerTag)) {
            document.body.appendChild(document.createElement(props.modalContainerTag));
        }

        this.modalContainer = document.querySelector(props.modalContainerTag);

        this.bindMethods('show,hide,bindHandlers,unbindHandlers,prepareChildren,prepareChild,animationFinish');
    }

    componentWillUpdate(nextProps, nextState) {
        super.componentWillUpdate(nextProps, nextState);
        const currentDialog = getShownDialog();

        // Hide currently visible dialog but do not unmount it
        if (currentDialog && currentDialog.id !== this.id && nextState.isShown) {
            const container = $(currentDialog.modalContainer);
            const modal = container.find('.modal-dialog');
            const backdrop = container.find('.modal-backdrop');

            dynamics.animate(modal[0], {
                opacity: 0,
                translateY: -100
            }, {
                type: dynamics.easeOut,
                duration: 250,
                complete: () => {
                    modal.closest('.modal').hide();
                }
            });

            dynamics.animate(backdrop[0], {
                opacity: 0
            }, {
                type: dynamics.linear,
                duration: this.backdropHideDuration
            });
        }
    }

    componentDidUpdate(prevProps, prevState) {
        super.componentDidUpdate(prevProps, prevState);
        if (this.isShown()) {
            ReactDOM.render(this.props.renderDialog.call(this), this.modalContainer);
            $(this.modalContainer).find('.modal').focus();
            this.bindHandlers();
        } else if (prevState.isShown && !this.isShown()) {
            this.unbindHandlers();
            ReactDOM.unmountComponentAtNode(this.modalContainer);
        }

        // Show previous dialog if it was hidden
        if (!this.isShown()) {
            const prevDialog = getShownDialog(this.id);
            if (prevDialog) {
                const prevContainer = $(prevDialog.modalContainer);
                const prevModal = prevContainer.find('.modal-dialog');
                const prevBackdrop = prevContainer.find('.modal-backdrop');
                prevModal.closest('.modal').show();
                dynamics.animate(prevModal[0], {
                    opacity: 1,
                    translateY: 50
                }, {
                    type: dynamics.spring,
                    duration: this.modalShowDuration
                });

                dynamics.animate(prevBackdrop[0], {
                    opacity: 0.8
                }, {
                    type: dynamics.linear,
                    duration: this.backdropShowDuration
                });
            }
        }
    }

    componentDidMount() {
        super.componentDidMount();
        mountedDialogs.push(this);
    }

    componentWillUnmount() {
        super.componentWillUnmount();
        this.unbindHandlers();
        mountedDialogs.splice(_.findIndex(mountedDialogs, {id: this.id}), 1);
        ReactDOM.unmountComponentAtNode(this.modalContainer);
    }

    shouldComponentUpdate(nextProps, nextState) {
        return !_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state);
    }

    bindHandlers() {
        this.unbindHandlers();
        const namespace = '.' + this.id;
        $(this.props.modalContainerTag).on('keyup' + namespace, '.modal', e => {
            // Listen for ESC button
            if (e.keyCode === 27) {
                this.hide();
            }
        }).on('mousedown' + namespace, '.modal', e => {
            // Catch backdrop click
            if ($(e.target).hasClass('modal')) {
                this.clickStartedOnBackdrop = true;
            }
        }).on('click' + namespace, '.modal', () => {
            if (this.clickStartedOnBackdrop && this.props.closeOnClick) {
                this.hide();
            }
            this.clickStartedOnBackdrop = false;
        });
    }

    unbindHandlers() {
        $(this.props.modalContainerTag).off('.' + this.id);
    }

    hide() {
        if (!this.state.isShown) {
            return Q(true);
        }
        this.props.onHide();

        return new Promise(resolve => {
            this.hideResolve = resolve;
            this.setState({
                isDialogShown: false
            });
        });
    }

    show() {
        // This shows the modal container element in case it was previously hidden by another dialog
        this.props.onShow();

        return new Promise(resolve => {
            this.setState({
                isShown: true
            }, () => {
                // Now we are supposed to show dialog with animation
                const show = () => {
                    this.setState({
                        isDialogShown: true
                    }, () => {
                        this.props.onShown();
                        resolve();
                    });
                };

                // If there was a previous dialog (eg: hidden with ClickConfirm), let the animation finish and show new dialog with delay
                if (getShownDialog(this.id)) {
                    setTimeout(show, 250);
                } else {
                    // No previous dialog was opened - we can safely show our new dialog
                    show();
                }

            });
        });
    }

    isShown() {
        return this.state.isShown;
    }

    prepareChild(child) {
        if (typeof child !== 'object' || child === null) {
            return child;
        }

        const props = {dialog: this};
        if (child.type === Ui.Modal.Header) {
            props['onClose'] = this.hide;
        }

        return React.cloneElement(child, props);
    }

    prepareChildren(children) {
        if (typeof children !== 'object' || children === null) {
            return children;
        }
        return React.Children.map(children, this.prepareChild);
    }

    animationFinish(isDialogShown) {
        if (!isDialogShown) {
            this.setState({isShown: false}, this.props.onHidden);
        }
        this.hideResolve();
    }
}

Dialog.defaultProps = {
    wide: false,
    onHide: _.noop,
    onHidden: _.noop,
    onShow: _.noop,
    onShown: _.noop,
    closeOnClick: true,
    modalContainerTag: 'webiny-modal',
    style: {},
    renderDialog() {
        const className = this.classSet({modal: true, 'modal-wizard': this.props.wide});
        return (

                <Ui.Animate
                    trigger={this.state.isDialogShown}
                    show={{opacity: 0.8, duration: this.backdropShowDuration, ease: 'linear'}}
                    hide={{opacity: 0, duration: this.backdropHideDuration, ease: 'linear'}}>

                </Ui.Animate>

                    <Ui.Animate
                        trigger={this.state.isDialogShown}
                        onFinish={this.animationFinish}
                        show={{translateY: 50, ease: 'spring', duration: this.modalShowDuration}}
                        hide={{translateY: -100, ease: 'easeOut', opacity: 0, duration: this.modalHideDuration}}>

                                {this.prepareChildren(this.props.children)}

                    </Ui.Animate>

        );
    },
    renderer() {
        return null;
    }
};

export default Dialog;<|endoftext|>