/*The MIT License (MIT)

Copyright (c) 2015 Apostolique

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/

// ==UserScript==
// @name        DonifransBako
// @namespace   Donifransbako
// @include     http://agar.io/*
// @version     3.63
// @grant       none
// @author      http://www.twitch.tv/donifransbako
// ==/UserScript==

var aposBotVersion = 3.63;

//TODO: Team mode
//      Detect when people are merging
//      Split to catch smaller targets
//      Angle based cluster code
//      Better wall code
//      In team mode, make allies be obstacles.

Number.prototype.mod = function(n) {
    return ((this % n) + n) % n;
};

Array.prototype.peek = function() {
    return this[this.length - 1];
};

var sha = "efde0488cc2cc176db48dd23b28a20b90314352b";
function getLatestCommit() {
    window.jQuery.ajax({
            url: "https://api.github.com/repos/donifransbako/Agar.io-bot/git/refs/heads/master",
            cache: false,
            dataType: "jsonp"
        }).done(function(data) {
            console.dir(data.data);
            console.log("hmm: " + data.data.object.sha);
            sha = data.data.object.sha;

            function update(prefix, name, url) {
                window.jQuery(document.body).prepend("
");
                window.jQuery('#' + prefix + 'Dialog').append("
");
                window.jQuery('#' + prefix + 'Message').append("
UPDATE TIME!!!
");
                window.jQuery('#' + prefix + 'Message').append("
Grab the update for: " + name + "
");
                window.jQuery('#' + prefix + 'Link').on('click', function() {
                    window.jQuery("#" + prefix + "Dialog").hide();
                    window.jQuery("#" + prefix + "Dialog").remove();
                });
                window.jQuery("#" + prefix + "Dialog").show();
            }

            $.get('https://raw.githubusercontent.com/donifransbako/Agar.io-bot/master/bot.user.js?' + Math.floor((Math.random() * 1000000) + 1), function(data) {
                var latestVersion = data.replace(/(\r\n|\n|\r)/gm,"");
                latestVersion = latestVersion.substring(latestVersion.indexOf("// @version")+11,latestVersion.indexOf("// @grant"));

                latestVersion = parseFloat(latestVersion + 0.0000);
                var myVersion = parseFloat(aposBotVersion + 0.0000);

                if(latestVersion > myVersion)
                {
                    update("aposBot", "bot.user.js", "https://github.com/donifransbako/Agar.io-bot/blob/" + sha + "/bot.user.js/");
                }
                console.log('Current bot.user.js Version: ' + myVersion + " on Github: " + latestVersion);
            });

        }).fail(function() {});
}
getLatestCommit();

console.log("Running Apos Bot!");

var f = window;
var g = window.jQuery;

console.log("Apos Bot!");

window.botList = window.botList || [];

/*function QuickBot() {
    this.name = "QuickBot V1";
    this.keyAction = function(key) {};
    this.displayText = function() {return [];};
    this.mainLoop = function() {
        return [screenToGameX(getMouseX()),
                screenToGameY(getMouseY())];
    };
}

window.botList.push(new QuickBot());*/

function AposBot() {
    this.name = "AposBot " + aposBotVersion;

    this.toggleFollow = false;
    this.keyAction = function(key) {
        if (81 == key.keyCode) {
            console.log("Toggle Follow Mouse!");
            this.toggleFollow = !this.toggleFollow;
        }
    };

    this.displayText = function() {
        return ["Q - Follow Mouse: " + (this.toggleFollow ? "On" : "Off")];
    };

    this.splitDistance = 710;

    //Given an angle value that was gotten from valueAndleBased(),
    //returns a new value that scales it appropriately.
    this.paraAngleValue = function(angleValue, range) {
        return (15 / (range[1])) * (angleValue * angleValue) - (range[1] / 6);
    };

    this.valueAngleBased = function(angle, range) {
        var leftValue = (angle - range[0]).mod(360);
        var rightValue = (this.rangeToAngle(range) - angle).mod(360);

        var bestValue = Math.min(leftValue, rightValue);

        if (bestValue <= range[1]) {
            return this.paraAngleValue(bestValue, range);
        }
        return -1;
    };

    this.computeDistance = function(x1, y1, x2, y2) {
        var xdis = x1 - x2; // <--- FAKE AmS OF COURSE!
        var ydis = y1 - y2;
        var distance = Math.sqrt(xdis * xdis + ydis * ydis);

        return distance;
    };

    this.computeDistanceFromCircleEdge = function(x1, y1, x2, y2, s2) {
        var tempD = this.computeDistance(x1, y1, x2, y2);

        var offsetX = 0;
        var offsetY = 0;

        var ratioX = tempD / (x1 - x2);
        var ratioY = tempD / (y1 - y2);

        offsetX = x1 - (s2 / ratioX);
        offsetY = y1 - (s2 / ratioY);

        drawPoint(offsetX, offsetY, 5, "");

        return this.computeDistance(x2, y2, offsetX, offsetY);
    };

    this.compareSize = function(player1, player2, ratio) {
        if (player1.size * player1.size * ratio < player2.size * player2.size) {
            return true;
        }
        return false;
    },

    this.canSplit = function(player1, player2) {
        return this.compareSize(player1, player2, 2.8) && !this.compareSize(player1, player2, 20);
    };

    this.isItMe = function(player, cell) {
        if (getMode() == ":teams") {
            var currentColor = player[0].color;
            var currentRed = currentColor.substring(1,3);
            var currentGreen = currentColor.substring(3,5);
            var currentBlue = currentColor.substring(5,7);

            var currentTeam = this.getTeam(currentRed, currentGreen, currentBlue);

            var cellColor = cell.color;

            var cellRed = cellColor.substring(1,3);
            var cellGreen = cellColor.substring(3,5);
            var cellBlue = cellColor.substring(5,7);

            var cellTeam = this.getTeam(cellRed, cellGreen, cellBlue);

            if (currentTeam == cellTeam && !cell.isVirus()) {
                return true;
            }

            //console.log("COLOR: " + color);

        } else {
            for (var i = 0; i < player.length; i++) {
                if (cell.id == player[i].id) {
                    return true;
                }
            }
        }
        return false;
    };

    this.getTeam = function(red, green, blue) {
        if (red == "ff") {
            return 0;
        } else if (green == "ff") {
            return 1;
        }
        return 2;
    };

    this.isFood = function(blob, cell) {
        if (!cell.isVirus() && this.compareSize(cell, blob, 1.33) || (cell.size <= 13)) {
            return true;
        }
        return false;
    };

    this.isThreat = function(blob, cell) {

        if (!cell.isVirus() && this.compareSize(blob, cell, 1.30)) {
            return true;
        }
        return false;
    };

    this.isVirus = function(blob, cell) {
        if (cell.isVirus() && this.compareSize(cell, blob, 1.2)) {
            return true;
        } else if (cell.isVirus() && cell.color.substring(3,5).toLowerCase() != "ff") {
            return true;
        }
        return false;
    };

    this.isSplitTarget = function(that, blob, cell) {
        if (that.canSplit(cell, blob)) {
            return true;
        }
        return false;
    };

    this.getTimeToRemerge = function(mass){
        return ((mass*0.02) + 30);
    };

    this.separateListBasedOnFunction = function(that, listToUse, blob) {
        var foodElementList = [];
        var threatList = [];
        var virusList = [];
        var splitTargetList = [];

        var player = getPlayer();

        Object.keys(listToUse).forEach(function(element, index) {
            var isMe = that.isItMe(player, listToUse[element]);

            if (!isMe) {
                if (that.isFood(blob, listToUse[element]) && listToUse[element].isNotMoving()) {
                    //IT'S FOOD!
                    foodElementList.push(listToUse[element]);

                } else if (that.isThreat(blob, listToUse[element])) {
                    //IT'S DANGER!
                    threatList.push(listToUse[element]);
                } else if (that.isVirus(blob, listToUse[element])) {
                    //IT'S VIRUS!
                    virusList.push(listToUse[element]);
                }
                else if (that.isSplitTarget(that, blob, listToUse[element])) {
                        drawCircle(listToUse[element].x, listToUse[element].y, listToUse[element].size + 50, 7);
                        splitTargetList.push(listToUse[element]);
                        foodElementList.push(listToUse[element]);
                    }
            }/*else if(isMe && (getBlobCount(getPlayer()) > 0)){
                //Attempt to make the other cell follow the mother one
                foodElementList.push(listToUse[element]);
            }*/
        });

        foodList = [];
        for (var i = 0; i < foodElementList.length; i++) {
            foodList.push([foodElementList[i].x, foodElementList[i].y, foodElementList[i].size]);
        }

        return [foodList, threatList, virusList, splitTargetList];
    };

    this.getAll = function(blob) {
        var dotList = [];
        var player = getPlayer();
        var interNodes = getMemoryCells();

        dotList = this.separateListBasedOnFunction(this, interNodes, blob);

        return dotList;
    };

    this.clusterFood = function(foodList, blobSize) {
        var clusters = [];
        var addedCluster = false;

        //1: x
        //2: y
        //3: size or value
        //4: Angle, not set here.

        for (var i = 0; i < foodList.length; i++) {
            for (var j = 0; j < clusters.length; j++) {
                if (this.computeDistance(foodList[i][0], foodList[i][1], clusters[j][0], clusters[j][1]) < blobSize * 1.5) {
                    clusters[j][0] = (foodList[i][0] + clusters[j][0]) / 2;
                    clusters[j][1] = (foodList[i][1] + clusters[j][1]) / 2;
                    clusters[j][2] += foodList[i][2];
                    addedCluster = true;
                    break;
                }
            }
            if (!addedCluster) {
                clusters.push([foodList[i][0], foodList[i][1], foodList[i][2], 0]);
            }
            addedCluster = false;
        }
        return clusters;
    };

    this.getAngle = function(x1, y1, x2, y2) {
        //Handle vertical and horizontal lines.

        if (x1 == x2) {
            if (y1 < y2) {
                return 271;
                //return 89;
            } else {
                return 89;
            }
        }

        return (Math.round(Math.atan2(-(y1 - y2), -(x1 - x2)) / Math.PI * 180 + 180));
    };

    this.slope = function(x1, y1, x2, y2) {
        var m = (y1 - y2) / (x1 - x2);

        return m;
    };

    this.slopeFromAngle = function(degree) {
        if (degree == 270) {
            degree = 271;
        } else if (degree == 90) {
            degree = 91;
        }
        return Math.tan((degree - 180) / 180 * Math.PI);
    };

    //Given two points on a line, finds the slope of a perpendicular line crossing it.
    this.inverseSlope = function(x1, y1, x2, y2) {
        var m = this.slope(x1, y1, x2, y2);
        return (-1) / m;
    };

    //Given a slope and an offset, returns two points on that line.
    this.pointsOnLine = function(slope, useX, useY, distance) {
        var b = useY - slope * useX;
        var r = Math.sqrt(1 + slope * slope);

        var newX1 = (useX + (distance / r));
        var newY1 = (useY + ((distance * slope) / r));
        var newX2 = (useX + ((-distance) / r));
        var newY2 = (useY + (((-distance) * slope) / r));

        return [
            [newX1, newY1],
            [newX2, newY2]
        ];
    };

    this.followAngle = function(angle, useX, useY, distance) {
        var slope = this.slopeFromAngle(angle);
        var coords = this.pointsOnLine(slope, useX, useY, distance);

        var side = (angle - 90).mod(360);
        if (side < 180) {
            return coords[1];
        } else {
            return coords[0];
        }
    };

    //Using a line formed from point a to b, tells if point c is on S side of that line.
    this.isSideLine = function(a, b, c) {
        if ((b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0) {
            return true;
        }
        return false;
    };

    //angle range2 is within angle range2
    //an Angle is a point and a distance between an other point [5, 40]
    this.angleRangeIsWithin = function(range1, range2) {
        if (range2[0] == (range2[0] + range2[1]).mod(360)) {
            return true;
        }
        //console.log("r1: " + range1[0] + ", " + range1[1] + " ... r2: " + range2[0] + ", " + range2[1]);

        var distanceFrom0 = (range1[0] - range2[0]).mod(360);
        var distanceFrom1 = (range1[1] - range2[0]).mod(360);

        if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 < distanceFrom1) {
            return true;
        }
        return false;
    };

    this.angleRangeIsWithinInverted = function(range1, range2) {
        var distanceFrom0 = (range1[0] - range2[0]).mod(360);
        var distanceFrom1 = (range1[1] - range2[0]).mod(360);

        if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 > distanceFrom1) {
            return true;
        }
        return false;
    };

    this.angleIsWithin = function(angle, range) {
        var diff = (this.rangeToAngle(range) - angle).mod(360);
        if (diff >= 0 && diff <= range[1]) {
            return true;
        }
        return false;
    };

    this.rangeToAngle = function(range) {
        return (range[0] + range[1]).mod(360);
    };

    this.anglePair = function(range) {
        return (range[0] + ", " + this.rangeToAngle(range) + " range: " + range[1]);
    };

    this.computeAngleRanges = function(blob1, blob2) {
        var mainAngle = this.getAngle(blob1.x, blob1.y, blob2.x, blob2.y);
        var leftAngle = (mainAngle - 90).mod(360);
        var rightAngle = (mainAngle + 90).mod(360);

        var blob1Left = this.followAngle(leftAngle, blob1.x, blob1.y, blob1.size);
        var blob1Right = this.followAngle(rightAngle, blob1.x, blob1.y, blob1.size);

        var blob2Left = this.followAngle(rightAngle, blob2.x, blob2.y, blob2.size);
        var blob2Right = this.followAngle(leftAngle, blob2.x, blob2.y, blob2.size);

        var blob1AngleLeft = this.getAngle(blob2.x, blob2.y, blob1Left[0], blob1Left[1]);
        var blob1AngleRight = this.getAngle(blob2.x, blob2.y, blob1Right[0], blob1Right[1]);

        var blob2AngleLeft = this.getAngle(blob1.x, blob1.y, blob2Left[0], blob2Left[1]);
        var blob2AngleRight = this.getAngle(blob1.x, blob1.y, blob2Right[0], blob2Right[1]);

        var blob1Range = (blob1AngleRight - blob1AngleLeft).mod(360);
        var blob2Range = (blob2AngleRight - blob2AngleLeft).mod(360);

        var tempLine = this.followAngle(blob2AngleLeft, blob2Left[0], blob2Left[1], 400);
        //drawLine(blob2Left[0], blob2Left[1], tempLine[0], tempLine[1], 0);

        if ((blob1Range / blob2Range) > 1) {
            drawPoint(blob1Left[0], blob1Left[1], 3, "");
            drawPoint(blob1Right[0], blob1Right[1], 3, "");
            drawPoint(blob1.x, blob1.y, 3, "" + blob1Range + ", " + blob2Range + " R: " + (Math.round((blob1Range / blob2Range) * 1000) / 1000));
        }

        //drawPoint(blob2.x, blob2.y, 3, "" + blob1Range);
    };

    this.debugAngle = function(angle, text) {
        var player = getPlayer();
        var line1 = this.followAngle(angle, player[0].x, player[0].y, 300);
        drawLine(player[0].x, player[0].y, line1[0], line1[1], 5);
        drawPoint(line1[0], line1[1], 5, "" + text);
    };

    //TODO: Don't let this function do the radius math.
    this.getEdgeLinesFromPoint = function(blob1, blob2, radius) {
        var px = blob1.x;
        var py = blob1.y;

        var cx = blob2.x;
        var cy = blob2.y;

        //var radius = blob2.size;

        /*if (blob2.isVirus()) {
            radius = blob1.size;
        } else if(canSplit(blob1, blob2)) {
            radius += splitDistance;
        } else {
            radius += blob1.size * 2;
        }*/

        var shouldInvert = false;

        var tempRadius = this.computeDistance(px, py, cx, cy);
        if (tempRadius <= radius) {
            radius = tempRadius - 5;
            shouldInvert = true;
        }

        var dx = cx - px;
        var dy = cy - py;
        var dd = Math.sqrt(dx * dx + dy * dy);
        var a = Math.asin(radius / dd);
        var b = Math.atan2(dy, dx);

        var t = b - a;
        var ta = {
            x: radius * Math.sin(t),
            y: radius * -Math.cos(t)
        };

        t = b + a;
        var tb = {
            x: radius * -Math.sin(t),
            y: radius * Math.cos(t)
        };

        var angleLeft = this.getAngle(cx + ta.x, cy + ta.y, px, py);
        var angleRight = this.getAngle(cx + tb.x, cy + tb.y, px, py);
        var angleDistance = (angleRight - angleLeft).mod(360);

        /*if (shouldInvert) {
            var temp = angleLeft;
            angleLeft = (angleRight + 180).mod(360);
            angleRight = (temp + 180).mod(360);
            angleDistance = (angleRight - angleLeft).mod(360);
        }*/

        return [angleLeft, angleDistance, [cx + tb.x, cy + tb.y],
            [cx + ta.x, cy + ta.y]
        ];
    };

    this.invertAngle = function(range) {
        var angle1 = this.rangeToAngle(badAngles[i]);
        var angle2 = (badAngles[i][0] - angle1).mod(360);
        return [angle1, angle2];
    },

    this.addWall = function(listToUse, blob) {
        //var mapSizeX = Math.abs(f.getMapStartX - f.getMapEndX);
        //var mapSizeY = Math.abs(f.getMapStartY - f.getMapEndY);
        //var distanceFromWallX = mapSizeX/3;
        //var distanceFromWallY = mapSizeY/3;
        var distanceFromWallY = 2000;
        var distanceFromWallX = 2000;
        if (blob.x < getMapStartX() + distanceFromWallX) {
            //LEFT
            //console.log("Left");
            listToUse.push([
                [90, true],
                [270, false], this.computeDistance(getMapStartX(), blob.y, blob.x, blob.y)
            ]);
            var lineLeft = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
            var lineRight = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
            drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
            drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
            drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
        }
        if (blob.y < getMapStartY() + distanceFromWallY) {
            //TOP
            //console.log("TOP");
            listToUse.push([
                [180, true],
                [0, false], this.computeDistance(blob.x, getMapStartY, blob.x, blob.y)
            ]);
            var lineLeft = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
            var lineRight = this.followAngle(360, blob.x, blob.y, 190 + blob.size);
            drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
            drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
            drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
        }
        if (blob.x > getMapEndX() - distanceFromWallX) {
            //RIGHT
            //console.log("RIGHT");
            listToUse.push([
                [270, true],
                [90, false], this.computeDistance(getMapEndX(), blob.y, blob.x, blob.y)
            ]);
            var lineLeft = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
            var lineRight = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
            drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
            drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
            drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
        }
        if (blob.y > getMapEndY() - distanceFromWallY) {
            //BOTTOM
            //console.log("BOTTOM");
            listToUse.push([
                [0, true],
                [180, false], this.computeDistance(blob.x, getMapEndY(), blob.x, blob.y)
            ]);
            var lineLeft = this.followAngle(0, blob.x, blob.y, 190 + blob.size);
            var lineRight = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
            drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
            drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
            drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
        }
        return listToUse;
    };

    //listToUse contains angles in the form of [angle, boolean].
    //boolean is true when the range is starting. False when it's ending.
    //range = [[angle1, true], [angle2, false]]

    this.getAngleIndex = function(listToUse, angle) {
        if (listToUse.length == 0) {
            return 0;
        }

        for (var i = 0; i < listToUse.length; i++) {
            if (angle <= listToUse[i][0]) {
                return i;
            }
        }

        return listToUse.length;
    };

    this.addAngle = function(listToUse, range) {
        //#1 Find first open element
        //#2 Try to add range1 to the list. If it is within other range, don't add it, set a boolean.
        //#3 Try to add range2 to the list. If it is withing other range, don't add it, set a boolean.

        //TODO: Only add the new range at the end after the right stuff has been removed.

        var newListToUse = listToUse.slice();

        var startIndex = 1;

        if (newListToUse.length > 0 && !newListToUse[0][1]) {
            startIndex = 0;
        }

        var startMark = this.getAngleIndex(newListToUse, range[0][0]);
        var startBool = startMark.mod(2) != startIndex;

        var endMark = this.getAngleIndex(newListToUse, range[1][0]);
        var endBool = endMark.mod(2) != startIndex;

        var removeList = [];

        if (startMark != endMark) {
            //Note: If there is still an error, this would be it.
            var biggerList = 0;
            if (endMark == newListToUse.length) {
                biggerList = 1;
            }

            for (var i = startMark; i < startMark + (endMark - startMark).mod(newListToUse.length + biggerList); i++) {
                removeList.push((i).mod(newListToUse.length));
            }
        } else if (startMark < newListToUse.length && endMark < newListToUse.length) {
            var startDist = (newListToUse[startMark][0] - range[0][0]).mod(360);
            var endDist = (newListToUse[endMark][0] - range[1][0]).mod(360);

            if (startDist < endDist) {
                for (var i = 0; i < newListToUse.length; i++) {
                    removeList.push(i);
                }
            }
        }

        removeList.sort(function(a, b){return b-a;});

        for (var i = 0; i < removeList.length; i++) {
            newListToUse.splice(removeList[i], 1);
        }

        if (startBool) {
            newListToUse.splice(this.getAngleIndex(newListToUse, range[0][0]), 0, range[0]);
        }
        if (endBool) {
            newListToUse.splice(this.getAngleIndex(newListToUse, range[1][0]), 0, range[1]);
        }

        return newListToUse;
    };

    this.getAngleRange = function(blob1, blob2, index, radius) {
        var angleStuff = this.getEdgeLinesFromPoint(blob1, blob2, radius);

        var leftAngle = angleStuff[0];
        var rightAngle = this.rangeToAngle(angleStuff);
        var difference = angleStuff[1];

        drawPoint(angleStuff[2][0], angleStuff[2][1], 3, "");
        drawPoint(angleStuff[3][0], angleStuff[3][1], 3, "");

        //console.log("Adding badAngles: " + leftAngle + ", " + rightAngle + " diff: " + difference);

        var lineLeft = this.followAngle(leftAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);
        var lineRight = this.followAngle(rightAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);

        if (blob2.isVirus()) {
            drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 6);
            drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 6);
            drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 6);
        } else if(getCells().hasOwnProperty(blob2.id)) {
            drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 0);
            drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 0);
            drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 0);
        } else {
            drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 3);
            drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 3);
            drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 3);
        }

        return [leftAngle, difference];
    };

    //Given a list of conditions, shift the angle to the closest available spot respecting the range given.
    this.shiftAngle = function(listToUse, angle, range) {
        //TODO: shiftAngle needs to respect the range! DONE?
        for (var i = 0; i < listToUse.length; i++) {
            if (this.angleIsWithin(angle, listToUse[i])) {
                //console.log("Shifting needed!");

                var angle1 = listToUse[i][0];
                var angle2 = this.rangeToAngle(listToUse[i]);

                var dist1 = (angle - angle1).mod(360);
                var dist2 = (angle2 - angle).mod(360);

                if (dist1 < dist2) {
                    if (this.angleIsWithin(angle1, range)) {
                        return angle1;
                    } else {
                        return angle2;
                    }
                } else {
                    if (this.angleIsWithin(angle2, range)) {
                        return angle2;
                    } else {
                        return angle1;
                    }
                }
            }
        }
        //console.log("No Shifting Was needed!");
        return angle;
    };

    /**
     * This is the main bot logic. This is called quite often.
     * @return A 2 dimensional array with coordinates for every cells.  [[x, y], [x, y]]
     */
    this.mainLoop = function() {
        var player = getPlayer();
        var interNodes = getMemoryCells();

        if ( /*!toggle*/ 1) {
            //The following code converts the mouse position into an
            //absolute game coordinate.
            var useMouseX = screenToGameX(getMouseX());
            var useMouseY = screenToGameY(getMouseY());
            tempPoint = [useMouseX, useMouseY, 1];

            //The current destination that the cells were going towards.
            var tempMoveX = getPointX();
            var tempMoveY = getPointY();

            //This variable will be returned at the end.
            //It will contain the destination choices for all the cells.
            //BTW!!! ERROR ERROR ABORT MISSION!!!!!!! READ BELOW -----------
            //
            //SINCE IT'S STUPID NOW TO ASK EACH CELL WHERE THEY WANT TO GO,
            //THE BOT SHOULD SIMPLY PICK ONE AND THAT'S IT, I MEAN WTF....
            var destinationChoices = []; //destination, size, danger

            //Just to make sure the player is alive.
            if (player.length > 0) {

                //Loop through all the player's cells.
                for (var k = 0; k < player.length; k++) {
                    if (true) {
                        drawPoint(player[k].x, player[k].y + player[k].size, 0, "" + (getLastUpdate() - player[k].birth) + " / " + (30000 + (player[k].birthMass * 57) - (getLastUpdate() - player[k].birth)) + " / " + player[k].birthMass);
                    }
                }

                //Loops only for one cell for now.
                for (var k = 0; /*k < player.length*/ k < 1; k++) {

                    //console.log("Working on blob: " + k);

                    drawCircle(player[k].x, player[k].y, player[k].size + this.splitDistance, 5);
                    //drawPoint(player[0].x, player[0].y - player[0].size, 3, "" + Math.floor(player[0].x) + ", " + Math.floor(player[0].y));

                    //var allDots = processEverything(interNodes);

                    //loop through everything that is on the screen and
                    //separate everything in it's own category.
                    var allIsAll = this.getAll(player[k]);

                    //The food stored in element 0 of allIsAll
                    var allPossibleFood = allIsAll[0];
                    //The threats are stored in element 1 of allIsAll
                    var allPossibleThreats = allIsAll[1];
                    //The viruses are stored in element 2 of allIsAll
                    var allPossibleViruses = allIsAll[2];

                    //The bot works by removing angles in which it is too
                    //dangerous to travel towards to.
                    var badAngles = [];
                    var obstacleList = [];

                    var isSafeSpot = true;
                    var isMouseSafe = true;

                    var clusterAllFood = this.clusterFood(allPossibleFood, player[k].size);

                    //console.log("Looking for enemies!");

                    //Loop through all the cells that were identified as threats.
                    for (var i = 0; i < allPossibleThreats.length; i++) {

                        var enemyDistance = this.computeDistanceFromCircleEdge(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y, allPossibleThreats[i].size);

                        allPossibleThreats[i].enemyDist = enemyDistance;
                    }

                    /*allPossibleThreats.sort(function(a, b){
                        return a.enemyDist-b.enemyDist;
                    })*/

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

                        var enemyDistance = this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);

                        var splitDangerDistance = allPossibleThreats[i].size + this.splitDistance + 150;

                        var normalDangerDistance = allPossibleThreats[i].size + 150;

                        var shiftDistance = player[k].size;

                        //console.log("Found distance.");

                        var enemyCanSplit = this.canSplit(player[k], allPossibleThreats[i]);
                        var secureDistance = (enemyCanSplit ? splitDangerDistance : normalDangerDistance);

                        for (var j = clusterAllFood.length - 1; j >= 0 ; j--) {
                            if (this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, clusterAllFood[j][0], clusterAllFood[j][1]) < secureDistance + shiftDistance)
                                clusterAllFood.splice(j, 1);
                        }

                        //console.log("Removed some food.");

                        if (enemyCanSplit) {
                            drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance, 0);
                            drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance + shiftDistance, 6);
                        } else {
                            drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance, 3);
                            drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance + shiftDistance, 6);
                        }

                        if (allPossibleThreats[i].danger && getLastUpdate() - allPossibleThreats[i].dangerTimeOut > 1000) {

                            allPossibleThreats[i].danger = false;
                        }

                        /*if ((enemyCanSplit && enemyDistance < splitDangerDistance) ||
                            (!enemyCanSplit && enemyDistance < normalDangerDistance)) {

                            allPossibleThreats[i].danger = true;
                            allPossibleThreats[i].dangerTimeOut = f.getLastUpdate();
                        }*/

                        //console.log("Figured out who was important.");

                        if ((enemyCanSplit && enemyDistance < splitDangerDistance) || (enemyCanSplit && allPossibleThreats[i].danger)) {

                            badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance).concat(allPossibleThreats[i].enemyDist));

                        } else if ((!enemyCanSplit && enemyDistance < normalDangerDistance) || (!enemyCanSplit && allPossibleThreats[i].danger)) {

                            badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance).concat(allPossibleThreats[i].enemyDist));

                        } else if (enemyCanSplit && enemyDistance < splitDangerDistance + shiftDistance) {
                            var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance + shiftDistance);
                            var angle1 = tempOb[0];
                            var angle2 = this.rangeToAngle(tempOb);

                            obstacleList.push([[angle1, true], [angle2, false]]);
                        } else if (!enemyCanSplit && enemyDistance < normalDangerDistance + shiftDistance) {
                            var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance + shiftDistance);
                            var angle1 = tempOb[0];
                            var angle2 = this.rangeToAngle(tempOb);

                            obstacleList.push([[angle1, true], [angle2, false]]);
                        }
                        //console.log("Done with enemy: " + i);
                    }

                    //console.log("Done looking for enemies!");

                    var goodAngles = [];
                    var stupidList = [];

                    for (var i = 0; i < allPossibleViruses.length; i++) {
                        if (player[k].size < allPossibleViruses[i].size) {
                            drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size + 10, 3);
                            drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size * 2, 6);

                        } else {
                            drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size + 50, 3);
                            drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size * 2, 6);
                        }
                    }

                    for (var i = 0; i < allPossibleViruses.length; i++) {
                        var virusDistance = this.computeDistance(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].x, player[k].y);
                        if (player[k].size < allPossibleViruses[i].size) {
                            if (virusDistance < (allPossibleViruses[i].size * 2)) {
                                var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, allPossibleViruses[i].size + 10);
                                var angle1 = tempOb[0];
                                var angle2 = this.rangeToAngle(tempOb);
                                obstacleList.push([[angle1, true], [angle2, false]]);
                            }
                        } else {
                            if (virusDistance < (player[k].size * 2)) {
                                var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, player[k].size + 50);
                                var angle1 = tempOb[0];
                                var angle2 = this.rangeToAngle(tempOb);
                                obstacleList.push([[angle1, true], [angle2, false]]);
                            }
                        }
                    }

                    if (badAngles.length > 0) {
                        //NOTE: This is only bandaid wall code. It's not the best way to do it.
                        stupidList = this.addWall(stupidList, player[k]);
                    }

                    for (var i = 0; i < badAngles.length; i++) {
                        var angle1 = badAngles[i][0];
                        var angle2 = this.rangeToAngle(badAngles[i]);
                        stupidList.push([[angle1, true], [angle2, false], badAngles[i][2]]);
                    }

                    //stupidList.push([[45, true], [135, false]]);
                    //stupidList.push([[10, true], [200, false]]);

                    stupidList.sort(function(a, b){
                        //console.log("Distance: " + a[2] + ", " + b[2]);
                        return a[2]-b[2];
                    });

                    //console.log("Added random noob stuff.");

                    var sortedInterList = [];
                    var sortedObList = [];

                    for (var i = 0; i < stupidList.length; i++) {
                        //console.log("Adding to sorted: " + stupidList[i][0][0] + ", " + stupidList[i][1][0]);
                        var tempList = this.addAngle(sortedInterList, stupidList[i]);

                        if (tempList.length == 0) {
                            console.log("MAYDAY IT'S HAPPENING!");
                            break;
                        } else {
                            sortedInterList = tempList;
                        }
                    }

                    for (var i = 0; i < obstacleList.length; i++) {
                        sortedObList = this.addAngle(sortedObList, obstacleList[i]);

                        if (sortedObList.length == 0) {
                            break;
                        }
                    }

                    var offsetI = 0;
                    var obOffsetI = 1;

                    if (sortedInterList.length > 0 && sortedInterList[0][1]) {
                        offsetI = 1;
                    }
                    if (sortedObList.length > 0 && sortedObList[0][1]) {
                        obOffsetI = 0;
                    }

                    var goodAngles = [];
                    var obstacleAngles = [];

                    for (var i = 0; i < sortedInterList.length; i += 2) {
                        var angle1 = sortedInterList[(i + offsetI).mod(sortedInterList.length)][0];
                        var angle2 = sortedInterList[(i + 1 + offsetI).mod(sortedInterList.length)][0];
                        var diff = (angle2 - angle1).mod(360);
                        goodAngles.push([angle1, diff]);
                    }

                    for (var i = 0; i < sortedObList.length; i += 2) {
                        var angle1 = sortedObList[(i + obOffsetI).mod(sortedObList.length)][0];
                        var angle2 = sortedObList[(i + 1 + obOffsetI).mod(sortedObList.length)][0];
                        var diff = (angle2 - angle1).mod(360);
                        obstacleAngles.push([angle1, diff]);
                    }

                    for (var i = 0; i < goodAngles.length; i++) {
                        var line1 = this.followAngle(goodAngles[i][0], player[k].x, player[k].y, 100 + player[k].size);
                        var line2 = this.followAngle((goodAngles[i][0] + goodAngles[i][1]).mod(360), player[k].x, player[k].y, 100 + player[k].size);
                        drawLine(player[k].x, player[k].y, line1[0], line1[1], 1);
                        drawLine(player[k].x, player[k].y, line2[0], line2[1], 1);

                        drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 1);

                        //drawPoint(player[0].x, player[0].y, 2, "");

                        drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
                        drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
                    }

                    for (var i = 0; i < obstacleAngles.length; i++) {
                        var line1 = this.followAngle(obstacleAngles[i][0], player[k].x, player[k].y, 50 + player[k].size);
                        var line2 = this.followAngle((obstacleAngles[i][0] + obstacleAngles[i][1]).mod(360), player[k].x, player[k].y, 50 + player[k].size);
                        drawLine(player[k].x, player[k].y, line1[0], line1[1], 6);
                        drawLine(player[k].x, player[k].y, line2[0], line2[1], 6);

                        drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 6);

                        //drawPoint(player[0].x, player[0].y, 2, "");

                        drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
                        drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
                    }

                    if (this.toggleFollow && goodAngles.length == 0) {
                        //This is the follow the mouse mode
                        var distance = this.computeDistance(player[k].x, player[k].y, tempPoint[0], tempPoint[1]);

                        var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(tempPoint[0], tempPoint[1], player[k].x, player[k].y), [0, 360]);

                        var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);

                        destinationChoices = destination;
                        drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
                        //tempMoveX = destination[0];
                        //tempMoveY = destination[1];

                    } else if (goodAngles.length > 0) {
                        var bIndex = goodAngles[0];
                        var biggest = goodAngles[0][1];
                        for (var i = 1; i < goodAngles.length; i++) {
                            var size = goodAngles[i][1];
                            if (size > biggest) {
                                biggest = size;
                                bIndex = goodAngles[i];
                            }
                        }
                        var perfectAngle = (bIndex[0] + bIndex[1] / 2).mod(360);

                        perfectAngle = this.shiftAngle(obstacleAngles, perfectAngle, bIndex);

                        var line1 = this.followAngle(perfectAngle, player[k].x, player[k].y, verticalDistance());

                        destinationChoices = line1;
                        drawLine(player[k].x, player[k].y, line1[0], line1[1], 7);
                        //tempMoveX = line1[0];
                        //tempMoveY = line1[1];
                    } else if (badAngles.length > 0 && goodAngles == 0) {
                        //When there are enemies around but no good angles
                        //You're likely screwed. (This should never happen.)

                        console.log("Failed");
                        destinationChoices = [tempMoveX, tempMoveY];
                        /*var angleWeights = [] //Put weights on the angles according to enemy distance
                        for (var i = 0; i < allPossibleThreats.length; i++){
                            var dist = this.computeDistance(player[k].x, player[k].y, allPossibleThreats[i].x, allPossibleThreats[i].y);
                            var angle = this.getAngle(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);
                            angleWeights.push([angle,dist]);
                        }
                        var maxDist = 0;
                        var finalAngle = 0;
                        for (var i = 0; i < angleWeights.length; i++){
                            if (angleWeights[i][1] > maxDist){
                                maxDist = angleWeights[i][1];
                                finalAngle = (angleWeights[i][0] + 180).mod(360);
                            }
                        }
                        var line1 = this.followAngle(finalAngle,player[k].x,player[k].y,f.verticalDistance());
                        drawLine(player[k].x, player[k].y, line1[0], line1[1], 2);
                        destinationChoices.push(line1);*/
                    } else if (clusterAllFood.length > 0) {
                        for (var i = 0; i < clusterAllFood.length; i++) {
                            //console.log("mefore: " + clusterAllFood[i][2]);
                            //This is the cost function. Higher is better.

                                var clusterAngle = this.getAngle(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);

                                clusterAllFood[i][2] = clusterAllFood[i][2] * 6 - this.computeDistance(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);
                                //console.log("Current Value: " + clusterAllFood[i][2]);

                                //(goodAngles[bIndex][1] / 2 - (Math.abs(perfectAngle - clusterAngle)));

                                clusterAllFood[i][3] = clusterAngle;

                                drawPoint(clusterAllFood[i][0], clusterAllFood[i][1], 1, "");
                                //console.log("After: " + clusterAllFood[i][2]);
                        }

                        var bestFoodI = 0;
                        var bestFood = clusterAllFood[0][2];
                        for (var i = 1; i < clusterAllFood.length; i++) {
                            if (bestFood < clusterAllFood[i][2]) {
                                bestFood = clusterAllFood[i][2];
                                bestFoodI = i;
                            }
                        }

                        //console.log("Best Value: " + clusterAllFood[bestFoodI][2]);

                        var distance = this.computeDistance(player[k].x, player[k].y, clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1]);

                        var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1], player[k].x, player[k].y), [0, 360]);

                        var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);

                        destinationChoices = destination;
                        //tempMoveX = destination[0];
                        //tempMoveY = destination[1];
                        drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
                    } else {
                        //If there are no enemies around and no food to eat.
                        destinationChoices = [tempMoveX, tempMoveY];
                    }

                    drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "");
                    //drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "" + Math.floor(this.computeDistance(tempPoint[0], tempPoint[1], I, J)));
                    //drawLine(tempPoint[0], tempPoint[1], player[0].x, player[0].y, 6);
                    //console.log("Slope: " + slope(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Angle: " + getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Side: " + (getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) - 90).mod(360));
                    tempPoint[2] = 1;

                    //console.log("Done working on blob: " + i);
                }

                //TODO: Find where to go based on destinationChoices.
                /*var dangerFound = false;
                for (var i = 0; i < destinationChoices.length; i++) {
                    if (destinationChoices[i][2]) {
                        dangerFound = true;
                        break;
                    }
                }

                destinationChoices.sort(function(a, b){return b[1] - a[1]});

                if (dangerFound) {
                    for (var i = 0; i < destinationChoices.length; i++) {
                        if (destinationChoices[i][2]) {
                            tempMoveX = destinationChoices[i][0][0];
                            tempMoveY = destinationChoices[i][0][1];
                            break;
                        }
                    }
                } else {
                    tempMoveX = destinationChoices.peek()[0][0];
                    tempMoveY = destinationChoices.peek()[0][1];
                    //console.log("Done " + tempMoveX + ", " + tempMoveY);
                }*/
            }
            //console.log("MOVING RIGHT NOW!");

            //console.log("______Never lied ever in my life.");

            return destinationChoices;
        }
    };
};
window.botList.push(New doni frans());

window.updateBotList(); //This function might not exist yet.


 #[zstack Test Bot Report] P A S S
 Integration Test Result:
Test Summary:

 TestSuite|TestCase | Pass | Fail | Timeout | Skip
 ---------|---------| ---- | ---- | ------- | ----
 basic_test|__suite_setup__|0|1|0|0
basic_test|_basic/test_create_vm_|0|0|0|1
basic_test|_basic/test_stop_vm_|0|0|0|1
basic_test|_basic/test_start_vm_|0|0|0|1
basic_test|_basic/test_reboot_vm_|0|0|0|1
basic_test|_basic/test_add_volume_|0|0|0|1
basic_test|_basic/test_add_vol_to_stopvm_|0|0|0|1
basic_test|_basic/test_add_volume_reboot_vm_|0|0|0|1
basic_test|_basic/test_add_multi_volumes_|0|0|0|1
basic_test|_basic/test_add_volume_negative_|0|0|0|1
basic_test|_basic/test_crt_temp_from_volume_|0|0|0|1
basic_test|_basic/test_crt_vm_with_volume_|0|0|0|1
basic_test|_basic/test_vm_securitygroup_|0|0|0|1
basic_test|_basic/test_create_iso_vm_|0|0|0|1
basic_test|_account/test_crt_vm_by_normal_account_|0|0|0|1
basic_test|_account/test_crt_vm_by_normal_account2_|0|0|0|1
basic_test|_account/test_vm_ops_by_normal_account_|0|0|0|1
basic_test|_account/test_multi_accounts_vm_ops_|0|0|0|1
basic_test|_suite_teardown_|0|0|0|1
virtual_router_test|__suite_setup__|0|1|0|0
virtual_router_test|_host/test_reconnect_host_|0|0|0|1
virtual_router_test|_account/test_vm_ops_by_normal_account_|0|0|0|1
virtual_router_test|_account/test_multi_accounts_vm_ops_|0|0|0|1
virtual_router_test|_novlan/test_create_vm_|0|0|0|1
virtual_router_test|_novlan/test_reboot_vm_|0|0|0|1
virtual_router_test|_novlan/test_ping_vms_|0|0|0|1
virtual_router_test|_host/test_reconnect_host_|0|0|0|1
virtual_router_test|_vlan/test_create_vm_|0|0|0|1
virtual_router_test|_vlan/test_reboot_vm_|0|0|0|1
virtual_router_test|_vlan/test_snat_create_|0|0|0|1
virtual_router_test|_vlan/test_dnat_reboot_|0|0|0|1
virtual_router_test|_vlan/test_ping_vms_|0|0|0|1
virtual_router_test|_vlan/test_create_3vms_|0|0|0|1
virtual_router_test|_vlan/test_start_vm_|0|0|0|1
virtual_router_test|_vlan/test_3l3s_vm_|0|0|0|1
virtual_router_test|_vlan/test_remove_dhcp_|0|0|0|1
virtual_router_test|_vlan/test_2l3_vm_|0|0|0|1
virtual_router_test|_vlan/test_crt_vms_with_limited_ips_|0|0|0|1
virtual_router_test|_vlan/test_crt_vms_with_limited_ips2.0_|0|0|0|1
virtual_router_test|_vlan/test_crt_vms_with_limited_ips2.1_|0|0|0|1
virtual_router_test|_vlan/test_start_vms_simultaneously_|0|0|0|1
virtual_router_test|_vlan/test_crt_static_ip_vm_|0|0|0|1
virtual_router_test|_vlan/test_crt_vm_with_hostname_|0|0|0|1
virtual_router_test|_vlan/test_attach_nic_|0|0|0|1
virtual_router_test|_vlan/test_attach_nic_stopped_vm_|0|0|0|1
virtual_router_test|_vlan/test_attach_nic_reboot_vm_|0|0|0|1
virtual_router_test|_vlan/test_chg_static_ip_vm_|0|0|0|1
virtual_router_test|_vlan/test_attach_nic_with_static_ip_|0|0|0|1
virtual_router_test|_volume/test_add_volume_|0|0|0|1
virtual_router_test|_volume/test_add_m_vols_|0|0|0|1
virtual_router_test|_volume/test_add_volume_vr_|0|0|0|1
virtual_router_test|_volume/test_crt_vm_volume_|0|0|0|1
virtual_router_test|_volume/test_crt_vm_2_volumes_|0|0|0|1
virtual_router_test|_volume/test_crt_vm_24_volumes_|0|0|0|1
virtual_router_test|_volume/test_volume_ops_on_stopped_vm_|0|0|0|1
virtual_router_test|_volume/test_crt_vm_from_dvt_|0|0|0|1
virtual_router_test|_template_image/test_crt_temp_image_|0|0|0|1
virtual_router_test|_template_image/test_del_temp_image_|0|0|0|1
virtual_router_test|_sg/test_ingress_|0|0|0|1
virtual_router_test|_sg/test_egress_|0|0|0|1
virtual_router_test|_sg/test_icmp_|0|0|0|1
virtual_router_test|_sg/test_udp_|0|0|0|1
virtual_router_test|_sg/test_stopped_vm_|0|0|0|1
virtual_router_test|_sg/test_vm_ops_|0|0|0|1
virtual_router_test|_sg/test_2vm_egress_|0|0|0|1
virtual_router_test|_sg/test_2vm_ingress_|0|0|0|1
virtual_router_test|_sg/test_4vm_complx_|0|0|0|1
virtual_router_test|_sg/test_detach_l3_|0|0|0|1
virtual_router_test|_pf/test_2l3s_pfs_|0|0|0|1
virtual_router_test|_pf/test_attach_pf_|0|0|0|1
virtual_router_test|_pf/test_delete_pf_after_destroy_vm_|0|0|0|1
virtual_router_test|_pf/test_del_vip_before_add_pf_to_vm_|0|0|0|1
virtual_router_test|_pf/test_multi_pfs_sg_tcp_|0|0|0|1
virtual_router_test|_pf/test_multi_rules_|0|0|0|1
virtual_router_test|_pf/test_pf_after_destroy_vm_|0|0|0|1
virtual_router_test|_pf/test_pf_sg_tcp_|0|0|0|1
virtual_router_test|_pf/test_pfs_tcp_udp_same_vip_ports_|0|0|0|1
virtual_router_test|_pf/test_pfs_tcp_with_same_vip_|0|0|0|1
virtual_router_test|_pf/test_tcp_|0|0|0|1
virtual_router_test|_pf/test_udp_|0|0|0|1
virtual_router_test|_pf/test_vm_ops_|0|0|0|1
virtual_router_test|_eip/test_2_eips_|0|0|0|1
virtual_router_test|_eip/test_2l3s_eip_pf_|0|0|0|1
virtual_router_test|_eip/test_2l3s_eips_|0|0|0|1
virtual_router_test|_eip/test_attach_eip_|0|0|0|1
virtual_router_test|_eip/test_create_eip_vm_|0|0|0|1
virtual_router_test|_eip/test_del_vip_before_add_eip_to_vm_|0|0|0|1
virtual_router_test|_eip/test_eip_sg_tcp_|0|0|0|1
virtual_router_test|_eip/test_pf_eip_attach_|0|0|0|1
virtual_router_test|_eip/test_vm_ops_|0|0|0|1
virtual_router_test|_eip/test_vm_ops2_|0|0|0|1
virtual_router_test|_lb/test_create_lb_alone_vr_|0|0|0|1
virtual_router_test|_lb/test_create_lb_source_|0|0|0|1
virtual_router_test|_lb/test_create_lb_|0|0|0|1
virtual_router_test|_lb/test_lb_health_check_|0|0|0|1
virtual_router_test|_snapshot/test_create_snapshot_|0|0|0|1
virtual_router_test|_snapshot/test_create_sp_after_delete_|0|0|0|1
virtual_router_test|_snapshot/test_create_image_by_snapshot_|0|0|0|1
virtual_router_test|_snapshot/test_crt_sp_for_both_root_..._|0|0|0|1
virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm2_|0|0|0|1
virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm3_|0|0|0|1
virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm_|0|0|0|1
virtual_router_test|_snapshot/test_delete_snapshot_on_ru..._|0|0|0|1
virtual_router_test|_snapshot/test_crt_sp_in_live_vm_|0|0|0|1
virtual_router_test|_snapshot/test_crt_sp_from_vol_crt_f..._|0|0|0|1
virtual_router_test|_snapshot/test_change_max_sp_depth_l..._|0|0|0|1
virtual_router_test|_regression/delete_sg_with_2_attache..._|0|0|0|1
virtual_router_test|_regression/rm_nic_sg_on_stopped_vm_|0|0|0|1
virtual_router_test|_regression/test_data_volume_with_vm..._|0|0|0|1
virtual_router_test|_vr/test_ping_vms_reboot_vr_|0|0|0|1
virtual_router_test|_vr/test_reconnect_vr_|0|0|0|1
virtual_router_test|_vr/test_start_vrs_simultaneously_|0|0|0|1
virtual_router_test|_host/test_reconnect_host_|0|0|0|1
virtual_router_test|_suite_teardown_|0|0|0|1
local_ps_virtual_router_test|__suite_setup__|0|1|0|0
local_ps_virtual_router_test|_host/test_reconnect_host_|0|0|0|1
local_ps_virtual_router_test|_account/test_vm_ops_by_normal_account_|0|0|0|1
local_ps_virtual_router_test|_account/test_multi_accounts_vm_ops_|0|0|0|1
local_ps_virtual_router_test|_novlan/test_create_vm_|0|0|0|1
local_ps_virtual_router_test|_novlan/test_reboot_vm_|0|0|0|1
local_ps_virtual_router_test|_novlan/test_ping_vms_|0|0|0|1
local_ps_virtual_router_test|_host/test_reconnect_host_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_create_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_reboot_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_snat_create_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_dnat_reboot_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_ping_vms_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_create_3vms_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_start_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_3l3s_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_remove_dhcp_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_2l3_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_crt_vms_with_limited_ips_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_crt_vms_with_limited_ips2.0_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_crt_vms_with_limited_ips2.1_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_start_vms_simultaneously_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_crt_static_ip_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_crt_vm_with_hostname_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_attach_nic_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_attach_nic_stopped_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_attach_nic_reboot_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_chg_static_ip_vm_|0|0|0|1
local_ps_virtual_router_test|_vlan/test_attach_nic_with_static_ip_|0|0|0|1
local_ps_virtual_router_test|_volume/test_add_volume_|0|0|0|1
local_ps_virtual_router_test|_volume/test_add_m_vols_|0|0|0|1
local_ps_virtual_router_test|_volume/test_add_volume_vr_|0|0|0|1
local_ps_virtual_router_test|_volume/test_crt_vm_volume_|0|0|0|1
local_ps_virtual_router_test|_volume/test_crt_vm_2_volumes_|0|0|0|1
local_ps_virtual_router_test|_volume/test_crt_vm_24_volumes_|0|0|0|1
local_ps_virtual_router_test|_volume/test_volume_ops_on_stopped_vm_|0|0|0|1
local_ps_virtual_router_test|_volume/test_crt_vm_from_dvt_|0|0|0|1
local_ps_virtual_router_test|_template_image/test_crt_temp_image_|0|0|0|1
local_ps_virtual_router_test|_template_image/test_del_temp_image_|0|0|0|1
local_ps_virtual_router_test|_sg/test_ingress_|0|0|0|1
local_ps_virtual_router_test|_sg/test_egress_|0|0|0|1
local_ps_virtual_router_test|_sg/test_icmp_|0|0|0|1
local_ps_virtual_router_test|_sg/test_udp_|0|0|0|1
local_ps_virtual_router_test|_sg/test_stopped_vm_|0|0|0|1
local_ps_virtual_router_test|_sg/test_vm_ops_|0|0|0|1
local_ps_virtual_router_test|_sg/test_2vm_egress_|0|0|0|1
local_ps_virtual_router_test|_sg/test_2vm_ingress_|0|0|0|1
local_ps_virtual_router_test|_sg/test_4vm_complx_|0|0|0|1
local_ps_virtual_router_test|_sg/test_detach_l3_|0|0|0|1
local_ps_virtual_router_test|_pf/test_2l3s_pfs_|0|0|0|1
local_ps_virtual_router_test|_pf/test_attach_pf_|0|0|0|1
local_ps_virtual_router_test|_pf/test_delete_pf_after_destroy_vm_|0|0|0|1
local_ps_virtual_router_test|_pf/test_del_vip_before_add_pf_to_vm_|0|0|0|1
local_ps_virtual_router_test|_pf/test_multi_pfs_sg_tcp_|0|0|0|1
local_ps_virtual_router_test|_pf/test_multi_rules_|0|0|0|1
local_ps_virtual_router_test|_pf/test_pf_after_destroy_vm_|0|0|0|1
local_ps_virtual_router_test|_pf/test_pf_sg_tcp_|0|0|0|1
local_ps_virtual_router_test|_pf/test_pfs_tcp_udp_same_vip_ports_|0|0|0|1
local_ps_virtual_router_test|_pf/test_pfs_tcp_with_same_vip_|0|0|0|1
local_ps_virtual_router_test|_pf/test_tcp_|0|0|0|1
local_ps_virtual_router_test|_pf/test_udp_|0|0|0|1
local_ps_virtual_router_test|_pf/test_vm_ops_|0|0|0|1
local_ps_virtual_router_test|_eip/test_2_eips_|0|0|0|1
local_ps_virtual_router_test|_eip/test_2l3s_eip_pf_|0|0|0|1
local_ps_virtual_router_test|_eip/test_2l3s_eips_|0|0|0|1
local_ps_virtual_router_test|_eip/test_attach_eip_|0|0|0|1
local_ps_virtual_router_test|_eip/test_create_eip_vm_|0|0|0|1
local_ps_virtual_router_test|_eip/test_del_vip_before_add_eip_to_vm_|0|0|0|1
local_ps_virtual_router_test|_eip/test_eip_sg_tcp_|0|0|0|1
local_ps_virtual_router_test|_eip/test_pf_eip_attach_|0|0|0|1
local_ps_virtual_router_test|_eip/test_vm_ops_|0|0|0|1
local_ps_virtual_router_test|_eip/test_vm_ops2_|0|0|0|1
local_ps_virtual_router_test|_lb/test_create_lb_alone_vr_|0|0|0|1
local_ps_virtual_router_test|_lb/test_create_lb_source_|0|0|0|1
local_ps_virtual_router_test|_lb/test_create_lb_|0|0|0|1
local_ps_virtual_router_test|_lb/test_lb_health_check_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_create_snapshot_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_create_sp_after_delete_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_create_image_by_snapshot_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_crt_sp_for_both_root_..._|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm2_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm3_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_delete_snapshot_on_ru..._|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_crt_sp_in_live_vm_|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_crt_sp_from_vol_crt_f..._|0|0|0|1
local_ps_virtual_router_test|_snapshot/test_change_max_sp_depth_l..._|0|0|0|1
local_ps_virtual_router_test|_regression/delete_sg_with_2_attache..._|0|0|0|1
local_ps_virtual_router_test|_regression/rm_nic_sg_on_stopped_vm_|0|0|0|1
local_ps_virtual_router_test|_regression/test_data_volume_with_vm..._|0|0|0|1
local_ps_virtual_router_test|_vr/test_ping_vms_reboot_vr_|0|0|0|1
local_ps_virtual_router_test|_vr/test_reconnect_vr_|0|0|0|1
local_ps_virtual_router_test|_vr/test_start_vrs_simultaneously_|0|0|0|1
local_ps_virtual_router_test|_host/test_reconnect_host_|0|0|0|1
local_ps_virtual_router_test|_suite_teardown_|0|0|0|1
local_nfs_virtual_router_test|__suite_setup__|0|1|0|0
local_nfs_virtual_router_test|_host/test_reconnect_host_|0|0|0|1
local_nfs_virtual_router_test|_account/test_vm_ops_by_normal_account_|0|0|0|1
local_nfs_virtual_router_test|_account/test_multi_accounts_vm_ops_|0|0|0|1
local_nfs_virtual_router_test|_novlan/test_create_vm_|0|0|0|1
local_nfs_virtual_router_test|_novlan/test_reboot_vm_|0|0|0|1
local_nfs_virtual_router_test|_novlan/test_ping_vms_|0|0|0|1
local_nfs_virtual_router_test|_host/test_reconnect_host_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_create_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_reboot_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_snat_create_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_dnat_reboot_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_ping_vms_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_create_3vms_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_start_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_3l3s_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_remove_dhcp_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_2l3_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_crt_vms_with_limited_ips_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_crt_vms_with_limited_ips2.0_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_crt_vms_with_limited_ips2.1_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_start_vms_simultaneously_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_crt_static_ip_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_crt_vm_with_hostname_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_attach_nic_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_attach_nic_stopped_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_attach_nic_reboot_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_chg_static_ip_vm_|0|0|0|1
local_nfs_virtual_router_test|_vlan/test_attach_nic_with_static_ip_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_add_volume_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_add_m_vols_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_add_volume_vr_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_crt_vm_volume_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_crt_vm_2_volumes_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_crt_vm_24_volumes_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_volume_ops_on_stopped_vm_|0|0|0|1
local_nfs_virtual_router_test|_volume/test_crt_vm_from_dvt_|0|0|0|1
local_nfs_virtual_router_test|_template_image/test_crt_temp_image_|0|0|0|1
local_nfs_virtual_router_test|_template_image/test_del_temp_image_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_ingress_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_egress_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_icmp_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_udp_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_stopped_vm_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_vm_ops_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_2vm_egress_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_2vm_ingress_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_4vm_complx_|0|0|0|1
local_nfs_virtual_router_test|_sg/test_detach_l3_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_2l3s_pfs_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_attach_pf_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_delete_pf_after_destroy_vm_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_del_vip_before_add_pf_to_vm_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_multi_pfs_sg_tcp_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_multi_rules_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_pf_after_destroy_vm_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_pf_sg_tcp_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_pfs_tcp_udp_same_vip_ports_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_pfs_tcp_with_same_vip_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_tcp_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_udp_|0|0|0|1
local_nfs_virtual_router_test|_pf/test_vm_ops_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_2_eips_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_2l3s_eip_pf_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_2l3s_eips_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_attach_eip_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_create_eip_vm_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_del_vip_before_add_eip_to_vm_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_eip_sg_tcp_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_pf_eip_attach_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_vm_ops_|0|0|0|1
local_nfs_virtual_router_test|_eip/test_vm_ops2_|0|0|0|1
local_nfs_virtual_router_test|_lb/test_create_lb_alone_vr_|0|0|0|1
local_nfs_virtual_router_test|_lb/test_create_lb_source_|0|0|0|1
local_nfs_virtual_router_test|_lb/test_create_lb_|0|0|0|1
local_nfs_virtual_router_test|_lb/test_lb_health_check_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_create_snapshot_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_create_sp_after_delete_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_create_image_by_snapshot_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_crt_sp_for_both_root_..._|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm2_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm3_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_crt_sp_in_stopped_vm_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_delete_snapshot_on_ru..._|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_crt_sp_in_live_vm_|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_crt_sp_from_vol_crt_f..._|0|0|0|1
local_nfs_virtual_router_test|_snapshot/test_change_max_sp_depth_l..._|0|0|0|1
local_nfs_virtual_router_test|_regression/delete_sg_with_2_attache..._|0|0|0|1
local_nfs_virtual_router_test|_regression/rm_nic_sg_on_stopped_vm_|0|0|0|1
local_nfs_virtual_router_test|_regression/test_data_volume_with_vm..._|0|0|0|1
local_nfs_virtual_router_test|_vr/test_ping_vms_reboot_vr_|0|0|0|1
local_nfs_virtual_router_test|_vr/test_reconnect_vr_|0|0|0|1
local_nfs_virtual_router_test|_vr/test_start_vrs_simultaneously_|0|0|0|1
local_nfs_virtual_router_test|_host/test_reconnect_host_|0|0|0|1
local_nfs_virtual_router_test|_suite_teardown_|0|0|0|1
Total|304|0|4|0|300


A good start would be 250MB


Lmap probably should not do shit high😂😂


パラメーターとして送った方が良いですね。

> = find_prototypes(@tag.name)　というヘルパーメソッドで使ったり、
> = button_tag "#{@tag.name}　とかでも使ってるので、定義は必要かなと思っているのですが、どうでしょうか？
tagの名前にしか使用しないので、@tag_nameという変数を用意してあげればいいと思います。


FYI, this change from WHEN to IF* breaks building cl-quakeinfo on non-Allegro Lisps.


Might I suggest you save the log as a map which uses the system time as a key instead of just a counter? You could print the entire log by implementing the toString method of the log.


Some things I can see need doing with the 'testall.sh' and 'testone.sh'...

First why do they seem to use different log files, 'testall.log', and 'tempall.txt'?

In the equivalent windows batch/command files there is only 1 log...

And that log is prefaced with the DATE TIME, and the '$ tidy -v' output... version is important...

And then I add another comment to the end... see 'alltest1.cmd'... either side of the 'for each call onetest'...

Would you be interestd in effecting that?

I too am now having some linux niggles about the diff... 2 files show differences still to look at...

But no difference for this latest 1642186-1...

 1. msg_431895.txt

the input file name is prefixed with './', not in testbase???

 2. msg_676205.txt and out_676205.html

but still to look at the inputs on this, to begin to understand why...

Any help appreciated. Thanks...


+1 Great work.


This is ok, but during the time while the document is not ready, the section will be visible, a better solution would be the hide it by css.


Line 732 in this commit has a spelling booboo. It has been fixed in a subsequent commit.


Extra space before `else`


> Hmm, I thought this was a pretty minor addition - in terms of LOC & complexity, this feature is pretty small.
> What are your thoughts on what problems this could cause in terms of maintenance issues down the line?

I agree that this one is small and alone doesn't do much harm. The problem is more a combination of changes like those where one day we wake up with a big library with many convenience properties... and big size ... and big documentation. I've bean there, I saw libraries growing to the point that people didn't want to use them any more.

My point is that we should balance convenience with frequency. If something is rare (IMO this one is) and can be solved in the user-land, we shouldn't merge it (even if it means 5 more lines of code for users).  Obviously we should monitor user requests and add things that are mostly requested, but I wouldn't merge any convenience shortcut just because it is small. Once again, frequency matters, IMO.


Please tell me these aren't real access tokens.


@Schiffers, está no fórum para download.
O mapa não está em git.


Looks good!


Maybe it is better to seek for other alternatives. Inserting HTML into MD can be quick hack if time is limited but we had better keep it clean and original.


LGTM.


No, your understanding is correct. In fact, now that I'm mocking/stubbing all calls to GROBID, this test can go away.


Unfortunately, the focus will happen at the same time as the section starts fading in. It should be set as a callback of the fadeIn, when it's completed.


And this one, can it also become too long?


Ok, that is fair - I will revert this then, and keep this in mind for the future.


welcome to


Well, the goal of these markdown tests is to match up completely with the XLS input and XML output so in theory this should equate to a manual test. The values used in L42 and [L45](https://github.com/XLSForm/pyxform/commit/cde6b323f96df71b4746ad471c58f8b597bfb78b#diff-8b6271e95381ffaed30c4c7b8a2a2c1eR45) are copy-pasted (spaces added) from your GH comments. These tests pass.

When [I tested it manually](https://odk.enke.to/preview?form=http://23.21.114.69/xlsform/downloads/tmpmslNv4/urdu_mixed.xml) it seems to be more-or-less working in Enketo (once you've entered a value). So, as far as I can tell the problem is not between XLS and XML.

But this confuses me quite a bit. Fortunately, the Urdu word for "what" looks like a W (کیا) and I gather everything's supposed to go between that and the reverse-question mark...


upd: таки не из системных, а из своих, только для дефолтной локали en.


It seems it is here by mistake. It will be removed.


Awesome, thnx @wesleycho !


if you are only calling this function from the function below (where you'll already done this check), you shouldn't have to test isArray again, correct?


I think it is in an another brunch


I told you to include Contact details of organizations, each org can have multiple phone/email. Also we should not give a rating for the organization.


The name of this method is quite misleading. It doesn't necessarily enable printing, it toggles it.


Why are you commenting here? Make a webpage or fiddle that shows the problem, and open an issue or send an e-mail if you want help.


@KOnaitis Good work but can you stop and go through the outstanding comments before continuing?


In the future we don't want this to be hardcoded


Bullshit!


Great one...Very useful for developers!!!
Cheers and thanks! :+1:


for org/main.png the disasters must be like scrollable tiles (like facebook) , they should not have a separate scrollbar


not sure if it's a good idea to put float as left here and add marginLeft?  to make the table more compact...


Warum so viel Leerzeilen?


Is this function used in someplace?


s


Raising is correct (a higher level exception handler will deal with adding to the errors array), but the exception should be a new subclass of Liquid::Error (see https://github.com/Shopify/liquid/blob/affae5ebefa9bb3338691810189214e919f4677d/lib/liquid/errors.rb#L49-L58)


This endpoint should be redirecting as a POST to /login on the calling application with token as a URL parameter, used [here](https://github.com/mediapublic/mediapublic/pull/51/files#diff-0da2e782bbd17fbf39ed578b6d6a4f50R144).

The real flow is:

1. User goes to /login, hits button to log in with twitter
2. User is sent to `POST /auth/login/twitter` by the form
3. User is redirected to twitter.com's oauth provider, where they log in (or their existing login is used)
3. Twitter redirects them to `POST <ourapp>/login` with the token parameter
4. We grab the auth_info from velruse using the token

The fake flow should be:

1. User goes to /login, hits form button
2. Stub `POST /auth/login/twitter` redirects back to `POST /login` with fake token parameter
3. mediapublic then uses the token to ask /auth_info for info about the login associated with the token
4. The fake login data is sent back


This doesn't satisfy step 5:
>Calling Add with a negative number will throw an exception “negatives not allowed” - and the negative that was passed.if there are multiple negatives, show all of them in the exception message.


Что-то у меня подозрение, что это из-за понатыканных везде lang='de'. Но с другой — с основным текстом на странице всё нормально.


#4854-ZoneHVACOutdoorAirUnit-does-not-autosize-child-objects-correctly (rraustad) - x86_64-Linux-Ubuntu-14.04-cppcheck-1.61: OK (0 of 0 tests passed)

![Build Badge](http://img.shields.io/badge/build%20status-passing-green.svg)


If you're right. I forgot that you use the boost touch.
My idea on my kernel, id you use powerbias for example over intellidemand, the max frequency is 1026000, so the unplug limit work perfectly.

Anyway, only a suggestion. On the other hand, I have to investigate the lazzyplug, if I have good news, I'll let you know if you want.

Have a good day Hells.


Actually, my bad for not pointing this out yesterday, but thinking it through a little more, if we are going to define the filter "encounterRole:{uuidOfEncounterRoleToFilterBy}" then we should *only* display providers with that role--ie, return empty string if for some reason an encounter role not specified (this would more or less be an illegal usage of the filter) or an empty string if none of the providers have that role (so we'd have have to do a check again the role even if the input wasn't an array.)


How about `strict_variable_access`?


xzc


@julen absolutely agreed - it was a quick fix to make the 2.7.1 release and docs work


Per my comment below, we'd change this to return an empty string, because no match for the role was found.


Interesting!  I presented a proof of concept for this at balisage this year - see https://www.icloud.com/keynote/AwBUCAESEO1f4pgFIHDxfMPmoaPOCy4aKdlw6kMCAhuLTWNDUpOMULQ7f4OKvLXlOIQdE0Mi__L7WoU27jan0IpSMCUCAQEEIHcKi1QoET6XTPSSWu_fTrhRclDyad-MP56SG5bKuqxh#bal2015hill1203 for slides.

I'd be more than happy to provide the proof of concept as a basis for this, if you'd like?


Sure! I will let you know


なるほど、たしかにこのページからは繰り返しの処理が消えましたが、どちらにせよ、別のファイルで繰り返しをしているのでは意味がなくありませんか？
部分テンプレートを使うのはRailsの概念であるDRY(Don't Repeat Yourself)にのっとるためです。
同じ記述を複数のファイルで記述するのは、DRYにのっとっていないために部分テンプレートを使うのですね。

悪いことではないので、そのままでOKです！


`0.5.*` is better ;)


:+1: — let's address that after the release.


Aha, so this was key in making sure the timestamps were actually different. Clever thinking


Partially this is (now) added in 32c9666cc52c06dff91e1b878ad655474d8f88ab by warning the user of mode 1/3/5


Okay, main confusion on my part coming from the difference between text editor and github.
![rtl_wth](https://cloud.githubusercontent.com/assets/97589/9906355/c34ccbca-5c57-11e5-879b-cd2716b22437.png)


Sorry `5.1.*` lol


Show! Dei uma olhada no atirarFlechaRefactory e o flechas-- é redudante, concorda?


Can we add a comment here saying the assumption this makes, (ie that the display string is in the format "123 - Dr. Bob".)


You are right. I'll fix it.


It's great, but:
https://github.com/nodejs/node/blob/v4.0.0/CHANGELOG.md


Good start, but not finished yet. Good usage of the logs to debug the app though!


revised ✅


updated title, description added.


Nice! The figure looks good. We need to add a link to the original and attribute it. I believe that is done in the lecture slides, so we can copy that.


:joy::joy::joy:
OK, thank you for the feedback :relieved:


Does mkdir -Z work on rhel7?

setup_selinux_context_root_dir

Should check if selinux is enabled, and return success if it is not.

```
+  if ! restore_selinux_context $DOCKER_ROOT_DIR; then
+    return 1
+  fi
```

Should be in the SELinux block


here we can break


OK, then it is fine.


I think `pplnt_grid` is not quite what we want.  Here are the issues I see:

1. We probably want the arguments to be grid size and extent, rather than resolution and extent (I may have steered you wrong on this point.  Sorry!).  The reason why is that I'm a little nervous about round-off error and edge effects if we compute a resolution and then do calculations with it.  Working in terms of grid size lets us stick to more predictable integer arithmetic.
2. We need to explicitly handle edge effects.  The issue here is that under the obvious way of doing things the lower edge of a grid cell is included in that cell, while the upper edge is included in the next cell.  So, how do we handle the upper boundary of the grid.  We can either (a) treat it as off the edge of the grid and exclude it, (b) make a special case of it and include it in the last cell, (c) fudge the size of the grid by a tiny amount so that the boundary falls into the last cell on its own, or (d) something else.  I'm leaning toward (a), but I'm willing to be persuaded otherwise.
3. We don't want the output to be a list of entries for each grid cell; we want it to be an total value for the cell.
4. We need to decide what to do if we encounter values outside the grid:  exclude silently, exclude with warning, or exception.  I think exclude with warning is the way to go here.


It really looks the same.


If `obj` is a drop, it won't have `has_key?` defined. This probably needs to ignore the drop case explicitly, with a `raise` in the default `Drop#before_method` implementation if the context has strict variable access enabled.


Looks good. If the attribution could be added, that would be great! We can then merge this on to master


I think this would just return input.provider, and the gerProviderNameFromDisplayString would take a provider as an input and then pull out the displayString and do the input.split(" - ")... this makes the "encounterRole" filter more useful, because we could use it in some case when we want something other than the displayString off the result object.


Intensität could be maybe better than Helligkeit, but I think it's fine. Don't worry about translation's quality you'll be able to perfect it once you get used to Souliss. Thank you for your work


This fails for tokens going to graveyard.

I added now a "getOwnerId(UUID objectId)" method to the Game class to handle this only once.

So use:
```
if (onlyToControllerGraveyard && !getControllerId().equals(game.getOwnerId(zEvent.getTargetId())) {
return false;
}
```


Let's just put a comment saying that if there are multiple providers with the same encounter role, this method just returns the first one it finds, just for future consumes of this filter to know what it does.


all people can use it


Remove the comments before you PR.


This should be changed to
``Dict("width" => convert(Float64,width), "transform" => transform)``


I agree this test should exist, is there a reason it's not implemented?


Syndra Balls to the Wall/Syndra Balls to the Wall/Program.cs


MANAPERCENT


i will do


All others named from 0 but this one, I'm curious :)


good point. this line change shouldn't introduce side effects. the rest of the code could fall over if it relies on some sort of (global) state, though.


we should keep using the loader processors, comes down to the same result in the end but avoid having to inject the processorChain. This class is only to create a new loader from the old one and just adding the doctrine data loaders as providers, nothing more.


Prueba de modificación finalizada.


Nice addition. I'd really appreciate it if you pushed this back upstream. I've also added you as a collaborator on the abettor repository if you'd like to work on the package directly.


Might want to consider different name for ``width`` see the documentation for description of ``width`` to get an inspiration for a new name. Also, the parameter ``transform`` is an artifact from the slice sampler, should probably be dropped.


In this case, I will just put the processor chain as attribute and add a getter.


Thanks for the comments!
For 2. I had chosen option b--including upper boundaries in the last cell (see line 37). I can change this to option a.


Using IndexOf here causes issues if `\n` is specified as the custom delimiter.
`[TestCase("//[\n]\n1\n2\n3", Result = 6)]` doesn't work.

I might get burnt at the stake for saying this but regex lookaheads are super useful here (and fun!)


É que se não tiver flechas não tem como atirar com o arco.


I chose the name because this is what Twig uses, but I don't really care ;-)


Shorter form is
```julia
vertices = eye(length(kappa))
```


#4854-ZoneHVACOutdoorAirUnit-does-not-autosize-child-objects-correctly (rraustad) - x86_64-MacOS-10.9-clang: OK (1865 of 1867 tests passed)

![Build Badge](http://img.shields.io/badge/build%20status-passing-green.svg) ![Test Badge](http://img.shields.io/badge/tests%20passed-99.89%25-yellow.svg)


Tia, wszystkie syscalle tutaj są dziurawe na wszystkie możliwe sposoby. Miałem nadzieję to poprawić przy ogarnianiu zarządzania pamięcią, ale jakoś nie zdążyłem do tego dojść. Trochę będzie zabawy, żeby to zrobić lepiej, bo m.in. będzie trzeba łapać wyjątki gdy user da błędny pointer, ale może się tym jeszcze pobawię kiedyś.


Tested, found I forgot it also reuses file name after, so modified function and tested again, now it works fine. I will submit PR soon.


Nope I did that initially, system time in mills can be the same for actions, this is why I'm not doing that.


Esses commits foram no username errado.


Would it be a bit cleaner to publish changes for different issues in separate commits?


Why 8080 when not in LB?


I'd change this to `[ -n "$MSTP_BRIDGES" ]`
some shells don't know how to evaluate -v [zsh is one, ash is another]


Just haven't had the time yet ;-)


Something to that effect, yes.


nitpick: change this to ?  `if [ -d "$net_dir/$bridge/bridge" ]; then`
( i.e. space after the semi-colon , and move end-quote to end of path )


@masensio the target sdk must be 22 (!)


Ppoprawione. Walnąłem tego tak dużo bo mi coś nie działało i szukałem dlaczego mam nadal złe wyrównanie, potem zapomniałem wywalić (bug był w makrze align_up)


Poprawione


TeamCity Colore :: Main Build [Build 73](http://tc.sharpblade.net/viewLog.html?buildId=603&buildTypeId=colore_mainbuild) is now running


Is the `and` needed? Is this the same as `return successes unless successes?.length`?


oj tam. poprawione ;)


Sure, thank you for commenting on that :)


Why do you need to do this? Doesn't it automatically know from instance type and actual disk size?


TeamCity Colore :: Main Build [Build 73](http://tc.sharpblade.net/viewLog.html?buildId=603&buildTypeId=colore_mainbuild) outcome was **SUCCESS**
Summary: Tests passed: 111 Build time: 0:0:57


Not sure what you mean by fail, I would think that the method would simply return. The check makes sense, as it will help to preserve the actual `archived_at` timestamp.


Ty, Master!
Now all things is working fine!


I think there can be a method something like
int ageOfAnimal = GetNumberFromConsole("\nPlease, input age of animal")
with validation loop inside


Damn dude, thanks for the credit!  Much appreciated!


@jordanmendler: Just revert this absolut no-go on master. No more discussion about this change, this change is just wrong. When it even violates google terms of condition too..
You may keep your own branch for such modification.

With your change you kill Flyspray and push away peoples that were willing to help before. I think that's the opposite of what we all want.

@danoh: Full ack.

@Psychokiller1888: You are always saying the project managment has no structure. I disagree.

  * We have it wonderful hosted on github.com and it is free for open source project.
  * We could use also automatic tools like travis-ci on github.com for free for open source project.
  * The mailing list is still working and we reach also people who aren't following it on github.
  * floele maintains bugs.flyspray.org and obviuosly takes the cost of webserver.
The content on bugs.flyspray.org is well maintained in my opinion, I made my comments on the interesting tasks and everybody can take part in the task discussions.
  * Yes, volunteers come and go, try to help, choose by herself what has priority by their own needs, provide fixes if they want.

So the only non-personal cost is just for hosting bugs.flyspray.org!

And sure the time of the volunteers. (I spend parts of my free- and worktime on flyspray because I still trust in the potential power of flyspray, so it is yet "sponsored" by me and my employer)

Flyspray is sponsored by the people that volunteers to help with the project. If they do it just for fun and inspiration or indirectly paid by their employer, because they use it in their company.

Finally: "Nichts wird so heiß gegessen wie es gekocht wird." (german Sprichwort)


Yes - this code is unused; and generates a warning - but instead of removing it I would prefer to implement the `job_queue_status_name()` function in C.


Yes, as `#unarchive` would also return nil in that case (unless `:raise_errors` would be enabled).


you lost the style definition?!


Awesome! It worked!

Thank you!

On Wed, Sep 16, 2015 at 5:18 AM, dothework <notifications@github.com> wrote:

> There are at least two ways to start a new checkpoint (branch in
> git/guthub)
> with the changes from the last checkpoint (branch in git/github).
> 1. merge the branch to the master and then the master will be up-to-date
> and
> then when you use the master as the source for the new checkpoint you’ll
> get
> what you expect/want. this is ideal for your work on these checkpoints
> 2. $ git merge checkpoint-name-here
> 3. use the latest branch as the source for the new checkpoint
>
>
> Please read, and re-read, this unitl it’s clear -
> https://www.bloc.io/resources/git-checkpoint-workflow
> We can discuss tonight as needed.
>
> On Wed, Sep 16, 2015 at 12:16 AM, Abner < notifications@github.com >
> wrote:
> Yes, my question is:
>
> In every checkpoint and assignment I start with the master alcolator. This
> means that I start with the most basic alcolator file (wine only) and I
> have to add the whiskey controller, then navigation, then... etc.
>
> Is there a way I can use my last file which includes all the changes and
> updates so I don't need to do all over again when starting a new checkpoint
> or assignment?
>
> On Tue, Sep 15, 2015 at 12:52 PM, dothework < notifications@github.com >
> wrote:
>
> > @abnero < https://github.com/abnero > DWMR. Do you still need me to help
> > get the storyboard to editable state in this project?
> >
> > —
> > Reply to this email directly or view it on GitHub
> > < https://github.com/abnero/ Alcolator-1/commit/
> c8c45fa1ac550e6fc76e1e960e4250
> 91ceef1787#commitcomment- 13246144 >
> > .
> >
> —
> Reply to this email directly or view it on GitHub .
>
>
>
> Not using Mixmax yet?
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/abnero/Alcolator-1/commit/c8c45fa1ac550e6fc76e1e960e425091ceef1787#commitcomment-13260299>
> .
>


Is this now at 1.0? Or do you have more to do before tagging the release?

Also, great work, I'm loving this add-on.


:tada:


Wrong commit message. You said `update readme` when we've 6 changed files in this commit...


OK, will do.


There should be a space after `if` i.e. `if (`


In the official templates expects you to define it: https://github.com/cloudfoundry/cf-release/blob/master/templates/cf-jobs.yml#L606


I think this would also work with single brackets
I don't mind if this stays as is


Tssss - didn't add the new function


rest looks good


Please use the formal docblock syntax with tags, see http://www.phpdoc.org/docs/latest/guides/docblocks.html


This should be the userID on SourceForge **not** that on GitHub.
Pete's username on SourceForge is 'pete_cressman'


There is a reason why used uint instead of size_t.
but I g


use page.rec['x'] please.


This changes the behavior of vbox/hbox on scalar items
```
julia> using Escher

julia> vbox( plaintext( "foo" ))
ERROR: MethodError: `start` has no method matching start(::Escher.Leaf)
 in collect at array.jl:260
 in vbox at /home/michael/.julia/v0.4/Escher/src/basics/layout.jl:312
```
given that the following exists why do we have the extra method ?
```
vbox(args...) = flow(vertical, args...)
```


That was missed from copy&paster from the tsuru-terraform project.


You can message me on twitter or artinfection(at)outlook.com for any icons I could help you with :+1:


Não seria mais interessante se essa variável "f" tivesse um nome mais intuitivo?
seria esse "f" um "quantidadeDeFlechas"?


Typo?


alternative you add a "have_posts()" to the IF and ELSEIF statements:
```php
LINE 15: if ( is_home() && !is_paged() && ( ot_get_option('featured-posts-count') =='1') && $featured->have_posts() ):

LINE 23: else if ( is_home() && !is_paged() && ( ot_get_option('featured-posts-count') !='0') && $featured->have_posts() ):
```
which is perhaps the better option instead of my first code example. So, if you don't have any post marked as featured, the code-block will be completely ignored, and doesn't show up a blank space.


.rect please.
Btw, you could combine those 2 Wait calls, doing page.rec['x'] and page.is_displayed().
We do that already in other code.


This might end up with two values for the HSTS header (cos we're adding one from nginx) but we'll have to cross that when it comes to it if that's the case.


Same here.


I'm fine with your suggested changes.  Thanks.


Yep toujours.
Ca va et toi?


Sure, that's fair.


Se acertar já retorna um boolean, precisa comparar com "true" ?


Use formal docBlock syntax


gunicorn is missing from requirements.txt


Ошибки теперь нет, но имя пользователя не подставляется в talk


Space after `if`


Nice!
I think `import` command is sufficient for this use case. And "imagemagick" is very popular, famous.

So, `shutter` command is necessary?


Hi, can you bring this change to nuget version?


I think rebase would be better.


I think that this is all fine, but I admit that I'd be a little confused about needing to call `HashParams.fromLocationHash()` (in app.coffee) before I could access any parameters.

It's not clear from the function name what it does, or that it has the side effect of initializing the parameters object.

Would it make sense to just be able to call `getParam` from the start, and `getParam` could check and see if the location hash has changed since the last time it processed it? That way we'd never have to worry about whether `getParam` would return an out-of-date parameter, and we wouldn't have to remember to call `fromLocationHash`.

Just a thought.


@romilrobtsenkov tunnitöö ja kodutöö


Thanks, this is much cleaner.


Why here and not in the spring file?


We already notify Cuckoo when something we're monitoring is trying to restart the system, the problem is that once the system reboots, Cuckoo currently has no idea what to do -- it isn't injected into anything and doesn't even know what it should be injecting into.  Previously all that would happen after a reboot is this guest.py code would keep receiving CUCKOO_GUEST_INIT statuses, have no idea what to do with them (because it never saw an analysis failure or analysis complete status) and would just keep running until the critical timeout.


These tests seem to be able to run in a separate file without changing grammar.rs. Are we always putting tests within the modules they test then? I thought we only do this for tests that need acces to private stuff.


Hi @mattdwen

What effect does this fix have? Was thinking if it is worth merging into my master branch.


I meant return indeed (but maybe also flash an alert). The point would be to prevent an (active) repo from being overwritten with an old archive.


so that i can use it in test cases without the need to start the whole spring context. Per the 3.7 refactor, AbstractMuleContextTestCase starts a SimpleRegistry with basic injection capabilities in which that would work


Здесь обнуление кеша не нужно


ta faltando variaveis, vou adicionar.


Это не используется. Можно везде удалить return this


>  `lang='de'`

Да, он может поломать шрифты. Однако, это единственный аттрибут который наследуют все элементы и поэтому можно писать `#de-panel-buttons:lang(en)`, а не `#de-main[de-style-azaza] #de-panel-buttons`.
Эту проблему могли бы решить CSS-переменные, но они есть только в лисе.


Use .rect please.


Удалить


Looks good.


Yeah, I think I commented and complained about this.

so we want iterable things to become an array and non-iterable things to be put in an array `[  ]`. This will let us write `hbox([...])` or `hbox((...,))` or `hbox(x)`

the only solution looks to me like: `flow(vertical, method_exists(collect, args) ? collect(args) : args)` - but looks complicated

I don't mind getting rid of `vbox(args...) = flow(vertical, args...)` - it helps you write `hbox(a,b)` but you can write `hbox([a,b])` quite easily as well, but doing this will break all Escher things ever written.


сразу пишем
return driver.getCurrentUrl().contains("/group.php") && driver.findElements(By.name("new")).size() > 0


? удалить


That's a good question, and I don't have a definite answer. The way I read https://doc.rust-lang.org/book/testing.html is that the tests/ directory is for "integration tests" across modules. So, since these tests only test functionality in this module, it could be argued they're not integration tests. That said, I'm not 100% confident in the right approach, and I'm quite prepared to be persuaded one way or the other.


都是 Atom 搞的鬼...


I would, without a doubt put that in the loader but really not sure it's a good idea for the *interface*


#5067-CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit-inside-AirLoopHVACUnitarySystem (rraustad) - x86_64-MacOS-10.9-clang: OK (1866 of 1867 tests passed)

![Build Badge](http://img.shields.io/badge/build%20status-passing-green.svg) ![Test Badge](http://img.shields.io/badge/tests%20passed-99.95%25-yellow.svg)


I will revert this (again), and make sure it gets pulled down and updated on all of my systems.


доделать до контактов


:cake:


Typo here (COPDAP), so alert shows untranslated string.


support


That's a good enough answer to me to not question this further. I doesn't really matter too much if the tests are at the bottom of the same file or a different file. At least this way it's clear where the tests are and what they are testing.


Chris, this is still a work in progress at the moment I was doing for practice so I still need to ass some more tests. Thanks for taking a look at it though.


Tiny thing - forkptf -> forkpty


I see. I'll fix.


According to [generate_deployment_manifest](https://github.com/cloudfoundry/cf-release/blob/master/generate_deployment_manifest#L3) this path is deprecated and should be ````./scripts/generate_deployment_manifest```` instead.


ретурн тзис можно удалить


Juan, respeta la interfaz del tp...


обнуление кеша можно удалить здесь


@dduupp I'm trying to remove a font that illustrator will embed as base64 in <style> when using ExtendScripts to batch export SVGs.

The plugin you are looking for already exists.
https://github.com/svg/svgo/blob/master/plugins/convertStyleToAttrs.js


удалить


is working


Hmm, I agree I don't like the method_exists solution. I'd like to be able to write

```
vbox{T <: .Iterable}( collect( x::T ) ) = ...
vbox( x ) ) = ...
```

Meaning something like T is of the 'class' Iterable


to avoid to have to declare this function in `LoaderInterface`, we can do a instance check and throw an exception if the loader is not AliceBundle's loader.

This would be better IMO as it would avoid having to require to get the `ProcessorChain` in `LoaderInterface`. Besides although we pass a `LoaderInterface` in the signature it's just a signature. This loader generator is specific to AliceBundle `Loader` as it's entirely depending to the loader constructor.


@WebSpider On my Syno the `contrub` folder is still empty. Could you check yours.?


I'd recommend to use at least constants set, like:
private const int CatChoice = 0;
private const int DogChoice = 1;
(or advanced menu with enumerations)


Com isto ficou um `}` sobrando, cuidado.


Could you imagine to use an alternative packet property to the `Packet_ref ref()`, e.g., `Node_handle handle()` paired with a simple registry? IMO *ref()* is an artifact from the early stages of the file-system infrastructure.


можно обойтись без if
сразу пишем
return driver.getCurrentUrl().contains("/edit.php") && driver.findElements(By.name("Edit / add")).size()>0;