<commit_before>
(function(window){

    // A Javascript 2D vector library
    // conventions :
    // method that returns a float value do not modify the vector
    // method that implement operators return a new vector with the modifications without
    // modifying the calling vector or the parameters.
    //
    //      v3 = v1.add(v2); // v3 is set to v1 + v2, v1, v2 are not modified
    //
    // methods that take a single vector as a parameter are usually also available with
    // q '_xy' suffix. Those method takes two floats representing the x,y coordinates of
    // the vector parameter and allow you to avoid to needlessly create a vector object :
    //
    //      v2 = v1.add(new Vec2(3,4));
    //      v2 = v1.add_xy(3,4);             //equivalent to previous line
    //
    // angles are in radians by default but method that takes angle as parameters
    // or return angle values usually have a variant with a '_deg' suffix that works in degrees
    //

    // The 2D vector object
    function Vec2(x,y){
        this.x = x;
        this.y = y;
    }

    window.Vec2 = Vec2;

    // Multiply a number expressed in radiant by rad2deg to convert it in degrees
    var rad2deg = 57.29577951308232;
    // Multiply a number expressed in degrees by deg2rad to convert it to radiant
    var deg2rad = 0.017453292519943295;
    // The numerical precision used to compare vector equality
    var epsilon   = 0.0000001;

    // This static method creates a new vector from polar coordinates with the angle expressed
    // in degrees
    Vec2.new_polar_deg = function(len,angle){
        var v = new Vec2(len,0);
        return v.rotate_deg(angle);
    };
    // This static method creates a new vector from polar coordinates with the angle expressed in
    // radians
    Vec2.new_polar = function(len,angle){
        var v = new Vec2(len,0);
        v.rotate(angle);
        return v;
    };
    // returns the length or modulus or magnitude of the vector
    Vec2.prototype.len = function(){
        return Math.sqrt(this.x*this.x + this.y*this.y);
    };
    // returns the squared length of the vector, this method is much faster than len()
    Vec2.prototype.len_sq = function(){
        return this.x*this.x + this.y*this.y;
    };
    // return the distance between this vector and the vector v
    Vec2.prototype.dist = function(v){
        var dx = this.x - v.x;
        var dy = this.y - v.y;
        return Math.sqrt(dx*dx + dy*dy);
    };
    // return the distance between this vector and the vector of coordinates (x,y)
    Vec2.prototype.dist_xy = function(x,y){
        var dx = this.x - x;
        var dy = this.y - y;
        return Math.sqrt(dx*dx + dy*dy);
    };
    // return the squared distance between this vector and the vector and the vector v
    Vec2.prototype.dist_sq = function(v){
        var dx = this.x - v.x;
        var dy = this.y - v.y;
        return dx*dx + dy*dy;
    };
    // return the squared distance between this vector and the vector of coordinates (x,y)
    Vec2.prototype.dist_sq_xy = function(x,y){
        var dx = this.x - x;
        var dy = this.y - y;
        return dx*dx + dy*dy;
    };
    // return the dot product between this vector and the vector v
    Vec2.prototype.dot = function(v){
        return this.x*v.x + this.y*v.y;
    };
    // return the dot product between this vector and the vector of coordinate (x,y)
    Vec2.prototype.dot_xy = function(x,y){
        return this.x*x + this.y*y;
    };
    // return a new vector with the same coordinates as this
    Vec2.prototype.clone = function(){
        return new Vec2(this.x,this.y);
    };
    // return the sum of this and vector v as a new vector
    Vec2.prototype.add = function(v){
        return new Vec2(this.x+v.x,this.y+v.y);
    };
    // return the sum of this and vector (x,y) as a new vector
    Vec2.prototype.add_xy = function(x,y){
        return new Vec2(this.x+x,this.y+y);
    };
    // returns (this - v) as a new vector where v is a vector and - is the vector substraction
    Vec2.prototype.sub = function(v){
        return new Vec2(this.x-v.x,this.y-v.y);
    };
    // returns (this - (x,y)) as a new vector where - is vector substraction
    Vec2.prototype.sub_xy = function(x,y){
        return new Vec2(this.x-x,this.y-y);
    };
    // return (this * v) as a new vector where v is a vector and * is the by component product
    Vec2.prototype.mult = function(v){
        return new Vec2(this.x*v.x,this.y*v.y);
    };
    // return (this * (x,y)) as a new vector where * is the by component product
    Vec2.prototype.mult_xy = function(x,y){
        return new Vec2(this.x*x,this.y*y);
    };
    // return this scaled by float f as a new fector
    Vec2.prototype.scale = function(f){
        return new Vec2(this.x*f, this.y*f);
    };
    // return the negation of this vector
    Vec2.prototype.neg = function(f){
        return new Vec2(-this.x,-this.y);
    };
    // return this vector normalized as a new vector
    Vec2.prototype.normalize = function(){
        var len = this.len();
        if(len == 0){
            return new Vec2(0,1);
        }else if(len != 1){
            return this.scale(1.0/len);
        }
        return new Vec2(this.x,this.y);
    };
    // return a new vector with the same direction as this vector of length float l. (negative values of l will invert direction)
    Vec2.prototype.set_len = function(l){
        return this.normalize().scale(l);
    };
    // return the projection of this onto the vector v as a new vector
    Vec2.prototype.project = function(v){
        return v.set_len(this.dot(v));
    };
    // return a string representation of this vector
    Vec2.prototype.toString = function(){
        var str = "";
        str += "[";
        str += this.x;
        str += ",";
        str += this.y;
        str += "]";
        return str;
    };
    //return this vector counterclockwise rotated by rad radians as a new vector
    Vec2.prototype.rotate = function(rad){
        var c = Math.cos(rad);
        var s = Math.sin(rad);
        var px = this.x * c - this.y *s;
        var py = this.x * s + this.y *c;
        return new Vec2(px,py);
    };
    //return this vector counterclockwise rotated by deg degrees as a new vector
    Vec2.prototype.rotate_deg = function(deg){
        return this.rotate(deg * deg2rad);
    };
    //linearly interpolate this vector towards the vector v by float factor alpha.
    // alpha == 0 : does nothing
    // alpha == 1 : sets this to v
    Vec2.prototype.lerp = function(v,alpha){
        var inv_alpha = 1 - alpha;
        return new Vec2(    this.x * inv_alpha + v.x * alpha,
                            this.y * inv_alpha + v.y * alpha    );
    };
    // returns the angle between this vector and the vector (1,0) in radians
    Vec2.prototype.angle = function(){
        return Math.atan2(this.y,this.x);
    }
    // returns the angle between this vector and the vector (1,0) in degrees
    Vec2.prototype.angle_deg = function(){
        return Math.atan2(this.y,this.x) * rad2deg;
    };
    // returns true if this vector is equal to the vector v, with a tolerance defined by the epsilon module constant
    Vec2.prototype.equals = function(v){
        if(Math.abs(this.x-v.x) > epsilon){
            return false;
        }else if(Math.abs(this.y-v.y) > epsilon){
            return false;
        }
        return true;
    };
    // returns true if this vector is equal to the vector (x,y) with a tolerance defined by the epsilon module constant
    Vec2.prototype.equals_xy = function(x,y){
        if(Math.abs(this.x-x) > epsilon){
            return false;
        }else if(Math.abs(this.y-y) > epsilon){
            return false;
        }
        return true;
    };
})(window);

(function(window){
    // A Bounding Shapes Library

    // A Bounding Ellipse
    // cx,cy : center of the ellipse
    // rx,ry : radius of the ellipse
    function BEllipse(cx,cy,rx,ry){
        this.type = 'ellipse';
        this.x = cx-rx;     // minimum x coordinate contained in the ellipse
        this.y = cy-ry;     // minimum y coordinate contained in the ellipse
        this.sx = 2*rx;     // width of the ellipse on the x axis
        this.sy = 2*ry;     // width of the ellipse on the y axis
        this.hx = rx;       // half of the ellipse width on the x axis
        this.hy = ry;       // half of the ellipse width on the y axis
        this.cx = cx;       // x coordinate of the ellipse center
        this.cy = cy;       // y coordinate of the ellipse center
        this.mx = cx + rx;  // maximum x coordinate contained in the ellipse
        this.my = cy + ry;  // maximum x coordinate contained in the ellipse
    }
    window.BEllipse = BEllipse;

    // returns an unordered list of vector defining the positions of the intersections between the ellipse's
    // boundary and a line segment defined by the start and end vectors a,b
    BEllipse.prototype.collide_segment = function(a,b){
        // http://paulbourke.net/geometry/sphereline/
        var collisions = [];

        if(a.equals(b)){  //we do not compute the intersection in this case. TODO ?
            return collisions;
        }

        // make all computations in a space where the ellipse is a circle
        // centered on zero
        var c = new Vec2(this.cx,this.cy);
        a = a.sub(c).mult_xy(1/this.hx,1/this.hy);
        b = b.sub(c).mult_xy(1/this.hx,1/this.hy);

        if(a.len_sq() < 1 && b.len_sq() < 1){   //both points inside the ellipse
            return collisions;
        }

        // compute the roots of the intersection
        var ab = b.sub(a);
        var A = (ab.x*ab.x + ab.y*ab.y);
        var B = 2*( ab.x*a.x + ab.y*a.y);
        var C = a.x*a.x + a.y*a.y - 1;
        var u  = B * B - 4*A*C;

        if(u < 0){
            return collisions;
        }

        u = Math.sqrt(u);
        var u1 = (-B + u) / (2*A);
        var u2 = (-B - u) / (2*A);

        if(u1 >= 0 && u1 <= 1){
            var pos = a.add(ab.scale(u1));
            collisions.push(pos);
        }
        if(u1 != u2 && u2 >= 0 && u2 <= 1){
            var pos = a.add(ab.scale(u2));
            collisions.push(pos);
        }
        for(var i = 0; i < collisions.length; i++){
            collisions[i] = collisions[i].mult_xy(this.hx,this.hy);
            collisions[i] = collisions[i].add_xy(this.cx,this.cy);
        }
        return collisions;
    };

    // A bounding rectangle
    // x,y the minimum coordinate contained in the rectangle
    // sx,sy the size of the rectangle along the x,y axis
    function BRect(x,y,sx,sy){
        this.type = 'rect';
        this.x = x;              // minimum x coordinate contained in the rectangle
        this.y = y;              // minimum y coordinate contained in the rectangle
        this.sx = sx;            // width of the rectangle on the x axis
        this.sy = sy;            // width of the rectangle on the y axis
        this.hx = sx/2;          // half of the rectangle width on the x axis
        this.hy = sy/2;          // half of the rectangle width on the y axis
        this.cx = x + this.hx;   // x coordinate of the rectangle center
        this.cy = y + this.hy;   // y coordinate of the rectangle center
        this.mx = x + sx;        // maximum x coordinate contained in the rectangle
        this.my = y + sy;        // maximum x coordinate contained in the rectangle
    }

    window.BRect = BRect;
    // Static method creating a new bounding rectangle of size (sx,sy) centered on (cx,cy)
    BRect.new_centered = function(cx,cy,sx,sy){
        return new BRect(cx-sx/2,cy-sy/2,sx,sy);
    };
    //intersect line a,b with line c,d, returns null if no intersection
    function line_intersect(a,b,c,d){
        // http://paulbourke.net/geometry/lineline2d/
        var f = ((d.y - c.y)*(b.x - a.x) - (d.x - c.x)*(b.y - a.y));
        if(f == 0){
            return null;
        }
        f = 1 / f;
        var fab = ((d.x - c.x)*(a.y - c.y) - (d.y - c.y)*(a.x - c.x)) * f ;
        if(fab < 0 || fab > 1){
            return null;
        }
        var fcd = ((b.x - a.x)*(a.y - c.y) - (b.y - a.y)*(a.x - c.x)) * f ;
        if(fcd < 0 || fcd > 1){
            return null;
        }
        return new Vec2(a.x + fab * (b.x-a.x), a.y + fab * (b.y - a.y) );
    }

    // returns an unordered list of vector defining the positions of the intersections between the ellipse's
    // boundary and a line segment defined by the start and end vectors a,b

    BRect.prototype.collide_segment = function(a,b){
        var collisions = [];
        var corners = [ new Vec2(this.x,this.y), new Vec2(this.x,this.my),
                        new Vec2(this.mx,this.my), new Vec2(this.mx,this.y) ];
        var pos = line_intersect(a,b,corners[0],corners[1]);
        if(pos) collisions.push(pos);
        pos = line_intersect(a,b,corners[1],corners[2]);
        if(pos) collisions.push(pos);
        pos = line_intersect(a,b,corners[2],corners[3]);
        if(pos) collisions.push(pos);
        pos = line_intersect(a,b,corners[3],corners[0]);
        if(pos) collisions.push(pos);
        return collisions;
    };

    // returns true if the rectangle contains the position defined by the vector 'vec'
    BRect.prototype.contains_vec = function(vec){
        return ( vec.x >= this.x && vec.x <= this.mx &&
                 vec.y >= this.y && vec.y <= this.my  );
    };
    // returns true if the rectangle contains the position (x,y)
    BRect.prototype.contains_xy = function(x,y){
        return ( x >= this.x && x <= this.mx &&
                 y >= this.y && y <= this.my  );
    };
    // returns true if the ellipse contains the position defined by the vector 'vec'
    BEllipse.prototype.contains_vec = function(v){
        v = v.mult_xy(this.hx,this.hy);
        return v.len_sq() <= 1;
    };
    // returns true if the ellipse contains the position (x,y)
    BEllipse.prototype.contains_xy = function(x,y){
        return this.contains(new Vec2(x,y));
    };

})(window);

<commit_msg>[FIX] orthography in vec2.js<commit_after>
(function(window){

    // A Javascript 2D vector library
    // conventions :
    // method that returns a float value do not modify the vector
    // method that implement operators return a new vector with the modifications without
    // modifying the calling vector or the parameters.
    //
    //      v3 = v1.add(v2); // v3 is set to v1 + v2, v1, v2 are not modified
    //
    // methods that take a single vector as a parameter are usually also available with
    // q '_xy' suffix. Those method takes two floats representing the x,y coordinates of
    // the vector parameter and allow you to avoid to needlessly create a vector object :
    //
    //      v2 = v1.add(new Vec2(3,4));
    //      v2 = v1.add_xy(3,4);             //equivalent to previous line
    //
    // angles are in radians by default but method that takes angle as parameters
    // or return angle values usually have a variant with a '_deg' suffix that works in degrees
    //

    // The 2D vector object
    function Vec2(x,y){
        this.x = x;
        this.y = y;
    }

    window.Vec2 = Vec2;

    // Multiply a number expressed in radiant by rad2deg to convert it in degrees
    var rad2deg = 57.29577951308232;
    // Multiply a number expressed in degrees by deg2rad to convert it to radiant
    var deg2rad = 0.017453292519943295;
    // The numerical precision used to compare vector equality
    var epsilon   = 0.0000001;

    // This static method creates a new vector from polar coordinates with the angle expressed
    // in degrees
    Vec2.new_polar_deg = function(len,angle){
        var v = new Vec2(len,0);
        return v.rotate_deg(angle);
    };
    // This static method creates a new vector from polar coordinates with the angle expressed in
    // radians
    Vec2.new_polar = function(len,angle){
        var v = new Vec2(len,0);
        v.rotate(angle);
        return v;
    };
    // returns the length or modulus or magnitude of the vector
    Vec2.prototype.len = function(){
        return Math.sqrt(this.x*this.x + this.y*this.y);
    };
    // returns the squared length of the vector, this method is much faster than len()
    Vec2.prototype.len_sq = function(){
        return this.x*this.x + this.y*this.y;
    };
    // return the distance between this vector and the vector v
    Vec2.prototype.dist = function(v){
        var dx = this.x - v.x;
        var dy = this.y - v.y;
        return Math.sqrt(dx*dx + dy*dy);
    };
    // return the distance between this vector and the vector of coordinates (x,y)
    Vec2.prototype.dist_xy = function(x,y){
        var dx = this.x - x;
        var dy = this.y - y;
        return Math.sqrt(dx*dx + dy*dy);
    };
    // return the squared distance between this vector and the vector and the vector v
    Vec2.prototype.dist_sq = function(v){
        var dx = this.x - v.x;
        var dy = this.y - v.y;
        return dx*dx + dy*dy;
    };
    // return the squared distance between this vector and the vector of coordinates (x,y)
    Vec2.prototype.dist_sq_xy = function(x,y){
        var dx = this.x - x;
        var dy = this.y - y;
        return dx*dx + dy*dy;
    };
    // return the dot product between this vector and the vector v
    Vec2.prototype.dot = function(v){
        return this.x*v.x + this.y*v.y;
    };
    // return the dot product between this vector and the vector of coordinate (x,y)
    Vec2.prototype.dot_xy = function(x,y){
        return this.x*x + this.y*y;
    };
    // return a new vector with the same coordinates as this
    Vec2.prototype.clone = function(){
        return new Vec2(this.x,this.y);
    };
    // return the sum of this and vector v as a new vector
    Vec2.prototype.add = function(v){
        return new Vec2(this.x+v.x,this.y+v.y);
    };
    // return the sum of this and vector (x,y) as a new vector
    Vec2.prototype.add_xy = function(x,y){
        return new Vec2(this.x+x,this.y+y);
    };
    // returns (this - v) as a new vector where v is a vector and - is the vector subtraction
    Vec2.prototype.sub = function(v){
        return new Vec2(this.x-v.x,this.y-v.y);
    };
    // returns (this - (x,y)) as a new vector where - is vector subtraction
    Vec2.prototype.sub_xy = function(x,y){
        return new Vec2(this.x-x,this.y-y);
    };
    // return (this * v) as a new vector where v is a vector and * is the by component product
    Vec2.prototype.mult = function(v){
        return new Vec2(this.x*v.x,this.y*v.y);
    };
    // return (this * (x,y)) as a new vector where * is the by component product
    Vec2.prototype.mult_xy = function(x,y){
        return new Vec2(this.x*x,this.y*y);
    };
    // return this scaled by float f as a new fector
    Vec2.prototype.scale = function(f){
        return new Vec2(this.x*f, this.y*f);
    };
    // return the negation of this vector
    Vec2.prototype.neg = function(f){
        return new Vec2(-this.x,-this.y);
    };
    // return this vector normalized as a new vector
    Vec2.prototype.normalize = function(){
        var len = this.len();
        if(len == 0){
            return new Vec2(0,1);
        }else if(len != 1){
            return this.scale(1.0/len);
        }
        return new Vec2(this.x,this.y);
    };
    // return a new vector with the same direction as this vector of length float l. (negative values of l will invert direction)
    Vec2.prototype.set_len = function(l){
        return this.normalize().scale(l);
    };
    // return the projection of this onto the vector v as a new vector
    Vec2.prototype.project = function(v){
        return v.set_len(this.dot(v));
    };
    // return a string representation of this vector
    Vec2.prototype.toString = function(){
        var str = "";
        str += "[";
        str += this.x;
        str += ",";
        str += this.y;
        str += "]";
        return str;
    };
    //return this vector counterclockwise rotated by rad radians as a new vector
    Vec2.prototype.rotate = function(rad){
        var c = Math.cos(rad);
        var s = Math.sin(rad);
        var px = this.x * c - this.y *s;
        var py = this.x * s + this.y *c;
        return new Vec2(px,py);
    };
    //return this vector counterclockwise rotated by deg degrees as a new vector
    Vec2.prototype.rotate_deg = function(deg){
        return this.rotate(deg * deg2rad);
    };
    //linearly interpolate this vector towards the vector v by float factor alpha.
    // alpha == 0 : does nothing
    // alpha == 1 : sets this to v
    Vec2.prototype.lerp = function(v,alpha){
        var inv_alpha = 1 - alpha;
        return new Vec2(    this.x * inv_alpha + v.x * alpha,
                            this.y * inv_alpha + v.y * alpha    );
    };
    // returns the angle between this vector and the vector (1,0) in radians
    Vec2.prototype.angle = function(){
        return Math.atan2(this.y,this.x);
    };
    // returns the angle between this vector and the vector (1,0) in degrees
    Vec2.prototype.angle_deg = function(){
        return Math.atan2(this.y,this.x) * rad2deg;
    };
    // returns true if this vector is equal to the vector v, with a tolerance defined by the epsilon module constant
    Vec2.prototype.equals = function(v){
        if(Math.abs(this.x-v.x) > epsilon){
            return false;
        }else if(Math.abs(this.y-v.y) > epsilon){
            return false;
        }
        return true;
    };
    // returns true if this vector is equal to the vector (x,y) with a tolerance defined by the epsilon module constant
    Vec2.prototype.equals_xy = function(x,y){
        if(Math.abs(this.x-x) > epsilon){
            return false;
        }else if(Math.abs(this.y-y) > epsilon){
            return false;
        }
        return true;
    };
})(window);

(function(window){
    // A Bounding Shapes Library

    // A Bounding Ellipse
    // cx,cy : center of the ellipse
    // rx,ry : radius of the ellipse
    function BEllipse(cx,cy,rx,ry){
        this.type = 'ellipse';
        this.x = cx-rx;     // minimum x coordinate contained in the ellipse
        this.y = cy-ry;     // minimum y coordinate contained in the ellipse
        this.sx = 2*rx;     // width of the ellipse on the x axis
        this.sy = 2*ry;     // width of the ellipse on the y axis
        this.hx = rx;       // half of the ellipse width on the x axis
        this.hy = ry;       // half of the ellipse width on the y axis
        this.cx = cx;       // x coordinate of the ellipse center
        this.cy = cy;       // y coordinate of the ellipse center
        this.mx = cx + rx;  // maximum x coordinate contained in the ellipse
        this.my = cy + ry;  // maximum x coordinate contained in the ellipse
    }
    window.BEllipse = BEllipse;

    // returns an unordered list of vector defining the positions of the intersections between the ellipse's
    // boundary and a line segment defined by the start and end vectors a,b
    BEllipse.prototype.collide_segment = function(a,b){
        // http://paulbourke.net/geometry/sphereline/
        var collisions = [];

        if(a.equals(b)){  //we do not compute the intersection in this case. TODO ?
            return collisions;
        }

        // make all computations in a space where the ellipse is a circle
        // centered on zero
        var c = new Vec2(this.cx,this.cy);
        a = a.sub(c).mult_xy(1/this.hx,1/this.hy);
        b = b.sub(c).mult_xy(1/this.hx,1/this.hy);

        if(a.len_sq() < 1 && b.len_sq() < 1){   //both points inside the ellipse
            return collisions;
        }

        // compute the roots of the intersection
        var ab = b.sub(a);
        var A = (ab.x*ab.x + ab.y*ab.y);
        var B = 2*( ab.x*a.x + ab.y*a.y);
        var C = a.x*a.x + a.y*a.y - 1;
        var u  = B * B - 4*A*C;

        if(u < 0){
            return collisions;
        }

        u = Math.sqrt(u);
        var u1 = (-B + u) / (2*A);
        var u2 = (-B - u) / (2*A);

        if(u1 >= 0 && u1 <= 1){
            var pos = a.add(ab.scale(u1));
            collisions.push(pos);
        }
        if(u1 != u2 && u2 >= 0 && u2 <= 1){
            var pos = a.add(ab.scale(u2));
            collisions.push(pos);
        }
        for(var i = 0; i < collisions.length; i++){
            collisions[i] = collisions[i].mult_xy(this.hx,this.hy);
            collisions[i] = collisions[i].add_xy(this.cx,this.cy);
        }
        return collisions;
    };

    // A bounding rectangle
    // x,y the minimum coordinate contained in the rectangle
    // sx,sy the size of the rectangle along the x,y axis
    function BRect(x,y,sx,sy){
        this.type = 'rect';
        this.x = x;              // minimum x coordinate contained in the rectangle
        this.y = y;              // minimum y coordinate contained in the rectangle
        this.sx = sx;            // width of the rectangle on the x axis
        this.sy = sy;            // width of the rectangle on the y axis
        this.hx = sx/2;          // half of the rectangle width on the x axis
        this.hy = sy/2;          // half of the rectangle width on the y axis
        this.cx = x + this.hx;   // x coordinate of the rectangle center
        this.cy = y + this.hy;   // y coordinate of the rectangle center
        this.mx = x + sx;        // maximum x coordinate contained in the rectangle
        this.my = y + sy;        // maximum x coordinate contained in the rectangle
    }

    window.BRect = BRect;
    // Static method creating a new bounding rectangle of size (sx,sy) centered on (cx,cy)
    BRect.new_centered = function(cx,cy,sx,sy){
        return new BRect(cx-sx/2,cy-sy/2,sx,sy);
    };
    //intersect line a,b with line c,d, returns null if no intersection
    function line_intersect(a,b,c,d){
        // http://paulbourke.net/geometry/lineline2d/
        var f = ((d.y - c.y)*(b.x - a.x) - (d.x - c.x)*(b.y - a.y));
        if(f == 0){
            return null;
        }
        f = 1 / f;
        var fab = ((d.x - c.x)*(a.y - c.y) - (d.y - c.y)*(a.x - c.x)) * f ;
        if(fab < 0 || fab > 1){
            return null;
        }
        var fcd = ((b.x - a.x)*(a.y - c.y) - (b.y - a.y)*(a.x - c.x)) * f ;
        if(fcd < 0 || fcd > 1){
            return null;
        }
        return new Vec2(a.x + fab * (b.x-a.x), a.y + fab * (b.y - a.y) );
    }

    // returns an unordered list of vector defining the positions of the intersections between the ellipse's
    // boundary and a line segment defined by the start and end vectors a,b

    BRect.prototype.collide_segment = function(a,b){
        var collisions = [];
        var corners = [ new Vec2(this.x,this.y), new Vec2(this.x,this.my),
                        new Vec2(this.mx,this.my), new Vec2(this.mx,this.y) ];
        var pos = line_intersect(a,b,corners[0],corners[1]);
        if(pos) collisions.push(pos);
        pos = line_intersect(a,b,corners[1],corners[2]);
        if(pos) collisions.push(pos);
        pos = line_intersect(a,b,corners[2],corners[3]);
        if(pos) collisions.push(pos);
        pos = line_intersect(a,b,corners[3],corners[0]);
        if(pos) collisions.push(pos);
        return collisions;
    };

    // returns true if the rectangle contains the position defined by the vector 'vec'
    BRect.prototype.contains_vec = function(vec){
        return ( vec.x >= this.x && vec.x <= this.mx &&
                 vec.y >= this.y && vec.y <= this.my  );
    };
    // returns true if the rectangle contains the position (x,y)
    BRect.prototype.contains_xy = function(x,y){
        return ( x >= this.x && x <= this.mx &&
                 y >= this.y && y <= this.my  );
    };
    // returns true if the ellipse contains the position defined by the vector 'vec'
    BEllipse.prototype.contains_vec = function(v){
        v = v.mult_xy(this.hx,this.hy);
        return v.len_sq() <= 1;
    };
    // returns true if the ellipse contains the position (x,y)
    BEllipse.prototype.contains_xy = function(x,y){
        return this.contains(new Vec2(x,y));
    };

})(window);

<|endoftext|>


<commit_before>var url = require('url');
var https = require('https');
var http = require('http');
var util = require('../util');
var config = util.config;

function request(req, res, port) {
	var options = url.parse(util.getFullUrl(req));
	options.host = '127.0.0.1';
	options.method = req.method;
	options.hostname = null;
	options.protocol = null;
	if (port) {
		options.port = port;
	}
	req.headers['x-forwarded-for'] = util.getClientIp(req);
	options.headers = req.headers;
	req.pipe(http.request(options, function(_res) {
		res.writeHead(_res.statusCode || 0, _res.headers);
		res.src(_res);
	}));
}

module.exports = function(req, res, next) {
	var host = req.headers.host;
	if (host == config.localUIHost) {
		var path = req.url;
		if (util.hasProtocol(path)) {
			path = url.parse(path).path;
		}
		request(req, res, /^\/data\b/.test(path) ? config.uidataport : config.uiport);
	} else if (host == config.WEINRE_HOST) {
		request(req, res, config.weinreport);
	} else {
		next();
	}
};
<commit_msg>data ui<commit_after>var url = require('url');
var https = require('https');
var http = require('http');
var util = require('../util');
var config = util.config;

function request(req, res, port) {
	var options = url.parse(util.getFullUrl(req));
	options.host = '127.0.0.1';
	options.method = req.method;
	options.hostname = null;
	options.protocol = null;
	if (port) {
		options.port = port;
	}
	req.headers['x-forwarded-for'] = util.getClientIp(req);
	options.headers = req.headers;
	req.pipe(http.request(options, function(_res) {
		res.writeHead(_res.statusCode || 0, _res.headers);
		res.src(_res);
	}));
}

module.exports = function(req, res, next) {
	var host = req.headers.host;
	if (host == config.localUIHost) {
		var path = util.hasProtocol(req.url) ? url.parse(req.url).path : req.url;
		request(req, res, /^\/data\b/.test(path) ? config.uidataport : config.uiport);
	} else if (host == config.WEINRE_HOST) {
		request(req, res, config.weinreport);
	} else {
		next();
	}
};
<|endoftext|>


<commit_before>/** hidepost.js -- hides posts from page given $things */

// is a post elem an OP?
function postIsOP(elem) {
  var ds = elem.dataset;
  return ds && ds.rootmsgid == ds.msgid ;
}

function _hide_elem(elem) {
 if (elem.style) {
    elem.style.display = "none";
  } else {
    elem.style = { display: "none" };
  }
  elem.dataset.userhide = "yes";
}

function _unhide_elem(elem) {
 if (elem.style) {
    elem.style.display = "block";
  } else {
    elem.style = { display: "block" };
  }
  elem.dataset.userhide = "no";
}

// return true if element is hidden
function _elemIsHidden(elem) {
  return elem.dataset && elem.dataset.userhide == "yes";
}

// hide a post
function hidepost(elem) {
  console.log("hidepost("+elem.dataset.msgid+")");

  if(postIsOP(elem)) {
    // hide thread it's an OP
    var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
    if (thread) {
      var e = thread.getElementsByClassName("post");
      for ( var idx = 0; idx < e.length ; idx ++ ) {
        if (e[idx].dataset.msgid == elem.dataset.msgid) continue; // don't apply
        hidepost(e[idx]);
      }
    }
  }
  // hide attachments and post body
  var es = elem.getElementsByClassName("attachments");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _hide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("post_body");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _hide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("postheader");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _hide_elem(es[idx]);
  }
  elem.dataset.userhide = "yes";
  elem.setHideLabel("[show]");
}

// unhide a post
function unhidepost(elem) {
  console.log("unhidepost("+elem.dataset.msgid+")");
  if(postIsOP(elem)) {
    var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
    if(thread) {
      var e = thread.getElementsByClassName("post");
      for ( var idx = 0; idx < e.length ; idx ++ ) {
        if(e[idx].dataset.msgid == elem.dataset.msgid) continue;
        unhidepost(e[idx]);
      }
    }
  }
  // unhide attachments and post body
  var es = elem.getElementsByClassName("attachments");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _unhide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("post_body");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _unhide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("postheader");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _unhide_elem(es[idx]);
  }

  elem.dataset.userhide = "no";
  elem.setHideLabel("[hide]");
}

// hide a post given a callback that checks each post
function hideposts(check_func) {
  var es = document.getElementsByClassName("post");
  for ( var idx = 0; idx < es.length ; idx ++ ) {
    var elem = es[idx];
    if(check_func && elem && check_func(elem)) {
      hidepost(elem);
    }
  }
}

// unhide all posts given callback
// if callback is null unhide all
function unhideall(check_func) {
  var es = document.getElementsByClassName("post");
  for (var idx=0 ; idx < es.length; idx ++ ) {
    var elem = es[idx];
    if(!check_func) { unhide(elem); }
    else if(check_func(elem)) { unhide(elem); }
  }
}

// inject posthide into page
onready(function() {
  var posts = document.getElementsByClassName("post");
  for (var idx = 0 ; idx < posts.length; idx++ ) {
    console.log("inject hide: "+posts[idx].dataset.msgid);
    var inject = function (elem) {
      var hider = document.createElement("a");
      hider.setAttribute("class", "hider");
      elem.setHideLabel = function (txt) {
        var e_hider = hider;
        e_hider.innerHTML = txt;
      }
      elem.hide = function() {
        var e_self = elem;
        var e_hider = hider;
        hidepost(e_self);
      }
      elem.unhide = function() {
        var e_self = elem;
        var e_hider = hider;
        unhidepost(e_self);
      }
      elem.isHiding = function() {
        var e_self = elem;
        return _elemIsHidden(e_self);
      }
      hider.appendChild(document.createTextNode("[hide]"));
      hider.onclick = function() {
        var e_self = elem;
        if(e_self.isHiding()) {
          e_self.unhide();
        } else {
          e_self.hide();
        }
      }
      elem.appendChild(hider);
    };
    inject(posts[idx]);
  }
});
<commit_msg>have post hiding persist in localstorage<commit_after>/** hidepost.js -- hides posts from page given $things */

function get_hidden_posts() {
  var st = get_storage();
  var prefix = "nntpchan_hide_post_";
  return  {
    all : function() {
      var msgids = [];
      for ( var k in st) {
        if (k.indexOf(prefix) == 0) {
          var m = k.substring(prefix.length);
          msgids.push(m);
        }
      }
      return msgids;
    },

    add : function (msg) {
      st[prefix+msg] = "post";
    },

    del : function (msg) {
      st.removeItem(prefix+msg);
    }
  }
}

// is a post elem an OP?
function postIsOP(elem) {
  var ds = elem.dataset;
  return ds && ds.rootmsgid == ds.msgid ;
}

function _hide_elem(elem) {
 if (elem.style) {
    elem.style.display = "none";
  } else {
    elem.style = { display: "none" };
  }
  elem.dataset.userhide = "yes";
}

function _unhide_elem(elem) {
 if (elem.style) {
    elem.style.display = "block";
  } else {
    elem.style = { display: "block" };
  }
  elem.dataset.userhide = "no";
}

// return true if element is hidden
function _elemIsHidden(elem) {
  return elem.dataset && elem.dataset.userhide == "yes";
}

// hide a post
function hidepost(elem) {
  console.log("hidepost("+elem.dataset.msgid+")");
  var posts = get_hidden_posts();
  if (posts) {
    // add to persitant hide
    posts.add(elem.dataset.msgidhash);
  }
  if(postIsOP(elem)) {
    // hide thread it's an OP
    var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
    if (thread) {
      var e = thread.getElementsByClassName("post");
      for ( var idx = 0; idx < e.length ; idx ++ ) {
        if (e[idx].dataset.msgid == elem.dataset.msgid) continue; // don't apply
        hidepost(e[idx]);
      }
    }
  }
  // hide attachments and post body
  var es = elem.getElementsByClassName("attachments");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _hide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("post_body");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _hide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("postheader");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _hide_elem(es[idx]);
  }
  elem.dataset.userhide = "yes";
  elem.setHideLabel("[show]");
}

// unhide a post
function unhidepost(elem) {
  console.log("unhidepost("+elem.dataset.msgid+")");
  var posts = get_hidden_posts();
  if (posts) {
    // remove from persiting hide
    posts.del(elem.dataset.msgidhash);
  }
  if(postIsOP(elem)) {
    var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
    if(thread) {
      var e = thread.getElementsByClassName("post");
      for ( var idx = 0; idx < e.length ; idx ++ ) {
        if(e[idx].dataset.msgid == elem.dataset.msgid) continue;
        unhidepost(e[idx]);
      }
    }
  }
  // unhide attachments and post body
  var es = elem.getElementsByClassName("attachments");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _unhide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("post_body");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _unhide_elem(es[idx]);
  }
  es = elem.getElementsByClassName("postheader");
  for (var idx = 0; idx < es.length ; idx ++ ) {
    _unhide_elem(es[idx]);
  }

  elem.dataset.userhide = "no";
  elem.setHideLabel("[hide]");
}

// hide a post given a callback that checks each post
function hideposts(check_func) {
  var es = document.getElementsByClassName("post");
  for ( var idx = 0; idx < es.length ; idx ++ ) {
    var elem = es[idx];
    if(check_func && elem && check_func(elem)) {
      hidepost(elem);
    }
  }
}

// unhide all posts given callback
// if callback is null unhide all
function unhideall(check_func) {
  var es = document.getElementsByClassName("post");
  for (var idx=0 ; idx < es.length; idx ++ ) {
    var elem = es[idx];
    if(!check_func) { unhide(elem); }
    else if(check_func(elem)) { unhide(elem); }
  }
}

// inject posthide into page
onready(function() {
  var posts = document.getElementsByClassName("post");
  for (var idx = 0 ; idx < posts.length; idx++ ) {
    console.log("inject hide: "+posts[idx].dataset.msgid);
    var inject = function (elem) {
      var hider = document.createElement("a");
      hider.setAttribute("class", "hider");
      elem.setHideLabel = function (txt) {
        var e_hider = hider;
        e_hider.innerHTML = txt;
      }
      elem.hide = function() {
        var e_self = elem;
        var e_hider = hider;
        hidepost(e_self);
      }
      elem.unhide = function() {
        var e_self = elem;
        var e_hider = hider;
        unhidepost(e_self);
      }
      elem.isHiding = function() {
        var e_self = elem;
        return _elemIsHidden(e_self);
      }
      hider.appendChild(document.createTextNode("[hide]"));
      hider.onclick = function() {
        var e_self = elem;
        if(e_self.isHiding()) {
          e_self.unhide();
        } else {
          e_self.hide();
        }
      }
      elem.appendChild(hider);
    };
    inject(posts[idx]);
  }
  // apply persiting hidden posts
  var posts = get_hidden_posts();
  if(posts) {
    var all = posts.all();
    for ( var idx = 0 ; idx < all.length; idx ++ ) {
      var id = all[idx];
      var elem = document.getElementById(id);
      if(elem)
        elem.hide();
    }
  }
});
<|endoftext|>


<commit_before>/*!
 * Copyright 2014 Apereo Foundation (AF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/**
 * @RESTModel Config
 *
 * @Required    []
 * @Property    {ModuleConfig}              {module}                    Configuration for named module (e.g. "oae-activity"); may appear multiple times
 */

/**
 * @RESTModel ConfigFields
 *
 * @Required    [{configField}]
 * @Property    {string[]}                  configFields                Config values in the form `oae-authentication/twitter/enabled`; may be single string
 */

/**
 * @RESTModel ConfigSchema
 *
 * @Required    []
 * @Property    {ModuleConfigSchema}        {module}                    Configuration schema for named module (e.g. "oae-activity"); may appear multiple times
 */

/**
 * @RESTModel ConfigValue
 *
 * @Required    [{name}]
 * @Property    {string}                    {name}                      Value of the named config element; may also be boolean
 */

/**
 * @RESTModel ConfigValues
 *
 * @Required    [{configField}]
 * @Property    {string}                    {configField}               Value(s) for config keys in the form `oae-authentication/twitter/enabled`; may occur mutiple times for different keys
 */

/**
 * @RESTModel ElementConfigItem
 *
 * @Required    [name,value]
 * @Property    {string}                    name                        Name of configuration item
 * @Property    {string}                    value                       Value of configuration item
 */

/**
 * @RESTModel ElementConfigSchema
 *
 * @Required    [defaultValue,description,globalAdmin,name,suppress,tenantOverride,type]
 * @Property    {string}                    defaultValue                Default value for element (use "" for false)
 * @Property    {string}                    description                 Description of element
 * @Property    {boolean}                   globalAdminOnly             Is element restricted to global adminstrators
 * @Property    {ElementConfigItem[]}       group                       Possible values for group elements
 * @Property    {ElementConfigItem[]}       list                        Possible values for list elements
 * @Property    {string}                    name                        Name of element
 * @Property    {boolean}                   suppress                    Allow presentation of element in adminstrative user interface
 * @Property    {boolean}                   tenantOverride              Can tenants override global values
 * @Property    {string}                    type                        Type of element [boolean,internationalizableText,list,radio,text]
 */

/**
 * @RESTModel ElementsConfigSchema
 *
 * @Required    [{elementName}]
 * @Property    {ElementConfigSchema}       {elementName}               Configuration schema for named element; may appear multiple times
 */

/**
 * @RESTModel FeatureConfig
 *
 * @Required    [{element}]
 * @Property    {ConfigValue[]}             {element}                   Configuration for named element; may appear multiple times
 */

/**
 * @RESTModel FeatureConfigSchema
 *
 * @Required    [description,elements,name]
 * @Property    {string}                    description                 Description of module
 * @Property    {ElementsConfigSchema}      elements                    Elements of the module
 * @Property    {string}                    name                        Name of module
 * @Property    {boolean}                   tenantOverride              Can tenants override global values
 */

/**
 * @RESTModel ModuleConfig
 *
 * @Required    [title]
 * @Property    {FeatureConfig}             {feature}                   Configuration for named feature; may appear multiple times
 * @Property    {string}                    title                       Name of configuration module; not currently used
 */

/**
 * @RESTModel ModuleConfigSchema
 *
 * @Required    [title]
 * @Property    {FeatureConfigSchema}       {feature}                   Configuration schema for named feature; may appear multiple times
 * @Property    {ConfigTitle}               title                       Name of configuration module
 */
<commit_msg>clarify array value<commit_after>/*!
 * Copyright 2014 Apereo Foundation (AF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/**
 * @RESTModel Config
 *
 * @Required    []
 * @Property    {ModuleConfig}              {module}                    Configuration for named module (e.g. "oae-activity"); may appear multiple times
 */

/**
 * @RESTModel ConfigFields
 *
 * @Required    [{configField}]
 * @Property    {string[]}                  configFields                Config values in the form `oae-authentication/twitter/enabled`; may be single string or array of strings
 */

/**
 * @RESTModel ConfigSchema
 *
 * @Required    []
 * @Property    {ModuleConfigSchema}        {module}                    Configuration schema for named module (e.g. "oae-activity"); may appear multiple times
 */

/**
 * @RESTModel ConfigValue
 *
 * @Required    [{name}]
 * @Property    {string}                    {name}                      Value of the named config element; may also be boolean
 */

/**
 * @RESTModel ConfigValues
 *
 * @Required    [{configField}]
 * @Property    {string}                    {configField}               Value(s) for config keys in the form `oae-authentication/twitter/enabled`; may occur mutiple times for different keys
 */

/**
 * @RESTModel ElementConfigItem
 *
 * @Required    [name,value]
 * @Property    {string}                    name                        Name of configuration item
 * @Property    {string}                    value                       Value of configuration item
 */

/**
 * @RESTModel ElementConfigSchema
 *
 * @Required    [defaultValue,description,globalAdmin,name,suppress,tenantOverride,type]
 * @Property    {string}                    defaultValue                Default value for element (use "" for false)
 * @Property    {string}                    description                 Description of element
 * @Property    {boolean}                   globalAdminOnly             Is element restricted to global adminstrators
 * @Property    {ElementConfigItem[]}       group                       Possible values for group elements
 * @Property    {ElementConfigItem[]}       list                        Possible values for list elements
 * @Property    {string}                    name                        Name of element
 * @Property    {boolean}                   suppress                    Allow presentation of element in adminstrative user interface
 * @Property    {boolean}                   tenantOverride              Can tenants override global values
 * @Property    {string}                    type                        Type of element [boolean,internationalizableText,list,radio,text]
 */

/**
 * @RESTModel ElementsConfigSchema
 *
 * @Required    [{elementName}]
 * @Property    {ElementConfigSchema}       {elementName}               Configuration schema for named element; may appear multiple times
 */

/**
 * @RESTModel FeatureConfig
 *
 * @Required    [{element}]
 * @Property    {ConfigValue[]}             {element}                   Configuration for named element; may appear multiple times
 */

/**
 * @RESTModel FeatureConfigSchema
 *
 * @Required    [description,elements,name]
 * @Property    {string}                    description                 Description of module
 * @Property    {ElementsConfigSchema}      elements                    Elements of the module
 * @Property    {string}                    name                        Name of module
 * @Property    {boolean}                   tenantOverride              Can tenants override global values
 */

/**
 * @RESTModel ModuleConfig
 *
 * @Required    [title]
 * @Property    {FeatureConfig}             {feature}                   Configuration for named feature; may appear multiple times
 * @Property    {string}                    title                       Name of configuration module; not currently used
 */

/**
 * @RESTModel ModuleConfigSchema
 *
 * @Required    [title]
 * @Property    {FeatureConfigSchema}       {feature}                   Configuration schema for named feature; may appear multiple times
 * @Property    {ConfigTitle}               title                       Name of configuration module
 */
<|endoftext|>


<commit_before>import Ember from 'ember'
const {get} = Ember
import computed, {readOnly} from 'ember-computed-decorators'
import _ from 'lodash'

import AbstractInput from './abstract-input'
import layout from 'ember-frost-bunsen/templates/components/frost-bunsen-input-checkbox-array'

export default AbstractInput.extend({
  // == Component Properties ===================================================

  classNames: [
    'frost-bunsen-input-checkbox-array',
    'frost-field'
  ],

  layout,

  // == State Properties =======================================================

  getDefaultProps () {
    return {
      selected: []
    }
  },

  // == Computed Properties ====================================================
  @readOnly
  @computed('cellConfig')
  size (cellConfig) {
    return _.get(cellConfig, 'renderer.size') || 'small'
  },

  @readOnly
  @computed('bunsenModel', 'cellConfig', 'value')
  options (bunsenModel, cellConfig, value) {
    const items = get(bunsenModel, 'items.enum') || []
    const labels = get(cellConfig, 'renderer.labels') || []

    value = value || []

    return items.map((item) => {
      return {
        checked: value.indexOf(item) > -1,
        label: labels[item] || item,
        value: item
      }
    })
  },

  // == Functions ==============================================================
  /**
   * Convert value to appropriate format for template
   * @param {Boolean|String} data - value to parse
   * @returns {any} parsed value
   */
  parseValue (data) {
    var selected = this.get('selected')
    if (data.value) {
      selected.push(data.id)
    } else {
      var index = selected.indexOf(data.id)
      selected.splice(index, 1)
    }
    return selected
  }
})
<commit_msg>fix checkbox-array bug where selected is not kept on refresh<commit_after>import Ember from 'ember'
const {get} = Ember
import computed, {readOnly} from 'ember-computed-decorators'
import _ from 'lodash'

import AbstractInput from './abstract-input'
import layout from 'ember-frost-bunsen/templates/components/frost-bunsen-input-checkbox-array'

export default AbstractInput.extend({
  // == Component Properties ===================================================

  classNames: [
    'frost-bunsen-input-checkbox-array',
    'frost-field'
  ],

  layout,

  // == State Properties =======================================================

  getDefaultProps () {
    return {
      selected: _.clone(this.get('value')) || []
    }
  },

  // == Computed Properties ====================================================
  @readOnly
  @computed('cellConfig')
  size (cellConfig) {
    return _.get(cellConfig, 'renderer.size') || 'small'
  },

  @readOnly
  @computed('bunsenModel', 'cellConfig', 'value')
  options (bunsenModel, cellConfig, value) {
    const items = get(bunsenModel, 'items.enum') || []
    const labels = get(cellConfig, 'renderer.labels') || []

    value = value || []

    return items.map((item) => {
      return {
        checked: value.indexOf(item) > -1,
        label: labels[item] || item,
        value: item
      }
    })
  },

  // == Functions ==============================================================
  /**
   * Convert value to appropriate format for template
   * @param {Boolean|String} data - value to parse
   * @returns {any} parsed value
   */
  parseValue (data) {
    var selected = this.get('selected')
    if (data.value) {
      selected.push(data.id)
    } else {
      var index = selected.indexOf(data.id)
      selected.splice(index, 1)
    }
    return selected
  }
})
<|endoftext|>


<commit_before>app.controller('DashboardController', ['$q', '$scope', '$interval', 'AuthService', 'Restangular',
                              function ($q,   $scope,   $interval,   AuthService,   Restangular) {

        Restangular.setDefaultHeaders({token: AuthService.getToken()});

        var resources = Restangular.all('resources');
        resources.getList().then(function (response) {
            $scope.services = response;
        });

        var provisionedResources = Restangular.all('provisioned_resources');
        provisionedResources.getList().then(function (response) {
            $scope.instances = response;
        });

        $scope.showAdminOptions = function() {
            return AuthService.isAdmin();
        }

        var currentService = null;
        $scope.selectService = function(service) {
            currentService = service;
            $scope.config = currentService.config;
        }

        $scope.updateConfig = function() {
            currentService.config = $scope.config;
            currentService.put();
        }
        $scope.provision = function (resource) {
            resource.post().then(function (response) {
                    provisionedResources.getList().then(function (response) {
                            $scope.instances = response;
                        }
                    )
                }
            )
            ;
        }

        $scope.deprovision = function (provisionedResource) {
            provisionedResource.patch({state:'deleting'}).then(function () {
                var index = $scope.instances.indexOf(provisionedResource);
                if (index > -1) $scope.instances[index].state='deleting';
            });
        }

        var pollInterval = $interval(function () {
            if (AuthService.isAuthenticated()) {
                var provisionedResources = Restangular.all('provisioned_resources');
                provisionedResources.getList().then(function (response) {
                    $scope.instances = response;
                });
            } else {
                $interval.cancel(pollInterval);
            }
        }, 60000);
    }]);
<commit_msg>Changed polling interval<commit_after>app.controller('DashboardController', ['$q', '$scope', '$interval', 'AuthService', 'Restangular',
                              function ($q,   $scope,   $interval,   AuthService,   Restangular) {

        Restangular.setDefaultHeaders({token: AuthService.getToken()});

        var resources = Restangular.all('resources');
        resources.getList().then(function (response) {
            $scope.services = response;
        });

        var provisionedResources = Restangular.all('provisioned_resources');
        provisionedResources.getList().then(function (response) {
            $scope.instances = response;
        });

        $scope.showAdminOptions = function() {
            return AuthService.isAdmin();
        }

        var currentService = null;
        $scope.selectService = function(service) {
            currentService = service;
            $scope.config = currentService.config;
        }

        $scope.updateConfig = function() {
            currentService.config = $scope.config;
            currentService.put();
        }
        $scope.provision = function (resource) {
            resource.post().then(function (response) {
                    provisionedResources.getList().then(function (response) {
                            $scope.instances = response;
                        }
                    )
                }
            )
            ;
        }

        $scope.deprovision = function (provisionedResource) {
            provisionedResource.patch({state:'deleting'}).then(function () {
                var index = $scope.instances.indexOf(provisionedResource);
                if (index > -1) $scope.instances[index].state='deleting';
            });
        }

        var pollInterval = $interval(function () {
            if (AuthService.isAuthenticated()) {
                var provisionedResources = Restangular.all('provisioned_resources');
                provisionedResources.getList().then(function (response) {
                    $scope.instances = response;
                });
            } else {
                $interval.cancel(pollInterval);
            }
        }, 10000);
    }]);
<|endoftext|>


<commit_before>(function (angular) {
    "use strict";
    angular
        .module('advancedFolderPluginDesignEnums', [])
        .constant('CODES', {
            NOT_FOUND: 'NOTFOUND',
            SUCCESS: 'SUCCESS'
        })
        .constant('MESSAGES', {
            ERROR: {
                NOT_FOUND: "No result found",
                CALLBACK_NOT_DEFINED: "Callback is not defined",
                ID_NOT_DEFINED: "Id is not defined",
                DATA_NOT_DEFINED: "Data is not defined",
                OPTION_REQUIRES: "Requires options"
            }
        })
        .constant('COLLECTIONS', {
            advancedFolderInfo: "advancedFolderInfo"
        })
        .constant('DEFAULT_DATA', {
            SOUND_CLOUD_INFO: {
                data: {
                    content: {
                        images: [],
                        description: '',
                        soundcloudClientID: '9a09ee0e50798267cb7644fb5c238ade',
                        link: 'https://soundcloud.com/laraparkerkent/tracks'
                    },
                    design: {
                        itemListLayout: "list-layout1",
                        bgImage: ""
                    }
                }
            }
        });

})(window.angular);<commit_msg>design side minor issues solved<commit_after>(function (angular) {
    "use strict";
    angular
        .module('advancedFolderPluginDesignEnums', [])
        .constant('CODES', {
            NOT_FOUND: 'NOTFOUND',
            SUCCESS: 'SUCCESS'
        })
        .constant('MESSAGES', {
            ERROR: {
                NOT_FOUND: "No result found",
                CALLBACK_NOT_DEFINED: "Callback is not defined",
                ID_NOT_DEFINED: "Id is not defined",
                DATA_NOT_DEFINED: "Data is not defined",
                OPTION_REQUIRES: "Requires options"
            }
        })
        .constant('COLLECTIONS', {
            advancedFolderInfo: "advancedFolderInfo"
        })
        .constant('DEFAULT_DATA', {
            ADVANCED_FOLDER_INFO: {
                data: {
                    content: {
                        images: [],
                        description: '',
                        link: ''
                    },
                    design: {
                        itemListLayout: "list-layout1",
                        bgImage: ""
                    }
                }
            }
        });

})(window.angular);<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();

// var badge = require('../helpers/badge');
// var request = require('request');
// var cheerio = require('cheerio');

/* GET home page. */
router.get('/', function(req, res) {
  //Blank home page
  res.send(204);
});

//Rounds number n to number of significant figures sig.
function sigFigs(n, sig) {
    var mult = Math.pow(10,
        sig - Math.floor(Math.log(n) / Math.LN10) - 1);
    return Math.round(n * mult) / mult;
}

//To recieve webhooks data on
router.post('/:project/pullRequests/', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');
    var authenticate = require('../helpers/authenticate');
    var packageJSON = require('../package.json');

    //Ignore closing of pull requests
    if(req.body.action == 'closed'){
        return;
    }

    //Getting merge SHA
    var mergeSHA = req.body.pull_request.merge_commit_sha;

    //If no merge SHA, then ignore
    if(!mergeSHA || mergeSHA == null){
        return;
    }

    //Getting base SHA
    var baseSHA = req.body.pull_request.base.sha;

    //Getting repository full name and number
    var fullRepoName = req.body.repository.full_name;
    var number = req.body.number;

    //Generating comment to make
    var cbadgeURL = process.env.CBADGE_URL;
    var comment = ['| Base ('+baseSHA.substring(0, 7)+') | Merge ('+mergeSHA.substring(0, 7)+')|',
        '\n|:---:|:---:|',
        '\n|![Base Coverage]('+cbadgeURL+'/'+req.params.project+'/coverage/'+baseSHA+')|![Merge Coverage]('+cbadgeURL+'/'+req.params.project+'/coverage/'+mergeSHA+')',
        '\n|![Base Test]('+cbadgeURL+'/'+req.params.project+'/test/'+baseSHA+')|![Merge Test]('+cbadgeURL+'/'+req.params.project+'/test/'+mergeSHA+')',
        '\n|![Base Build]('+cbadgeURL+'/'+req.params.project+'/build/'+baseSHA+')|![Merge Build]('+cbadgeURL+'/'+req.params.project+'/build/'+mergeSHA+')',
        '\n|![Base Configure]('+cbadgeURL+'/'+req.params.project+'/configure/'+baseSHA+')|![Merge Configure]('+cbadgeURL+'/'+req.params.project+'/configure/'+mergeSHA+')'].join();

    var options = {
        url: 'https://api.github.com/repos/'+fullRepoName+'/issues/'+req.body.number+'/comments',
        headers: {
            'User-Agent': 'CBadge/'+packageJSON.version,
            'Authorization': authenticate()
        },
        body: {
            body: comment
        }
    };
    request.post(options);
});

//Get coverage on a per-revision basis
router.get('/:project/coverage/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    request('http://open.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var coverage = JSON.parse(body);
            var loctested = 0;
            var locuntested = 0;
            var buildswithcoverage = 0;
            for(var i = 0; i < coverage.length; i++){
                if( coverage[i].loctested != null &&
                    Number(coverage[i].loctested) &&
                    coverage[i].locuntested != null &&
                    Number(coverage[i].locuntested)){

                    loctested += coverage[i].loctested;
                    locuntested += coverage[i].locuntested;
                }
            }
            if(loctested + locuntested > 0){
                var percent = loctested/(loctested+locuntested);
                percent = sigFigs(percent, 3);
                percent *= 100;
                if(percent > 80){
                    res.redirect(badge('coverage', percent+'%', 'brightgreen'));
                }else if(percent > 60){
                    res.redirect(badge('coverage', percent+'%', 'yellow'));
                }else{
                    res.redirect(badge('coverage', percent+'%', 'red'));
                }
            }else{
                res.redirect(badge('coverage', 'unknown', 'lightgrey'));
            }
        }
    });
});

router.get('/:project/build/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    request('http://open.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var builds = JSON.parse(body);
            var buildErrors = 0;
            var buildWarnings = 0;

            if(builds.length > 0){
                for(var i = 0; i < builds.length; i++){
                    if(Number(builds[i].builderrors)){
                        buildErrors += Number(builds[i].builderrors);
                    }
                    if(Number(builds[i].buildwarnings)){
                        buildWarnings += Number(builds[i].buildwarnings);
                    }
                }

                if(Number(buildErrors) > 0){
                    res.redirect(badge('build', buildErrors+' errors', 'red'));
                }else if(Number(buildWarnings) > 0){
                    res.redirect(badge('build', buildWarnings+' warnings', 'yellow'));
                }else{
                    res.redirect(badge('build', 'passing', 'brightgreen'));
                }
            }else{
                res.redirect(badge('build', 'unknown', 'lightgrey'));
            }

        }
    });
});

router.get('/:project/configure/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    //console.log('http://open.cdash.org/api/?method=build&task=checkinsdefects&project='+req.params.project);

    request('http://open.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var builds = JSON.parse(body);
            var configureErrors = 0;
            var configureWarnings = 0;

            if(builds.length > 0){
                for(var i = 0; i < builds.length; i++){
                    if(Number(builds[i].configureerrors)){
                        configureErrors += Number(builds[i].configureerrors);
                    }
                    if(Number(builds[i].configurewarnings)){
                        configureWarnings += Number(builds[i].configurewarnings);
                    }
                }

                if(Number(configureErrors) > 0){
                    res.redirect(badge('configure', configureErrors+' errors', 'red'));
                }else if(Number(configureWarnings) > 0){
                    res.redirect(badge('configure', configureWarnings+' warnings', 'yellow'));
                }else{
                    res.redirect(badge('configure', 'passing', 'brightgreen'));
                }
            }else{
                res.redirect(badge('build', 'unknown', 'lightgrey'));
            }

        }
    });
});

router.get('/:project/test/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    request('http://trunk.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var builds = JSON.parse(body);
            var testsPassed = 0;
            var testsFailed = 0;
            var testsNotRun = 0;

            for(var i = 0; i < builds.length; i++){
                if(Number(builds[i].testpassed)){
                    testsPassed += Number(builds[i].testpassed);
                }
                if(Number(builds[i].testfailed)){
                    testsFailed += Number(builds[i].testfailed);
                }
                if(Number(builds[i].testnotrun)){
                    testsNotRun += Number(builds[i].testnotrun);
                }
            }

            if(testsPassed+testsNotRun+testsFailed > 0){
                var percent = (testsPassed)/(testsPassed+testsNotRun+testsFailed);
                percent = sigFigs(percent, 3);
                percent *= 100;
                if(percent > 80){
                    res.redirect(badge('tests', percent+'%', 'brightgreen'));
                }else if (percent > 60){
                    res.redirect(badge('tests', percent+'%', 'yellow'));
                }else{
                    res.redirect(badge('tests', percent+'%', 'red'));
                }
            }else{
                res.redirect(badge('tests', 'unknown', 'lightgrey'));
            }
        }
    });
});

module.exports = router;
<commit_msg>Cleaned up extraneous comments.<commit_after>var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res) {
  //Blank home page
  res.send(204);
});

//Rounds number n to number of significant figures sig.
function sigFigs(n, sig) {
    var mult = Math.pow(10,
        sig - Math.floor(Math.log(n) / Math.LN10) - 1);
    return Math.round(n * mult) / mult;
}

//To recieve webhooks data on
router.post('/:project/pullRequests/', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');
    var authenticate = require('../helpers/authenticate');
    var packageJSON = require('../package.json');

    //Ignore closing of pull requests
    if(req.body.action == 'closed'){
        return;
    }

    //Getting merge SHA
    var mergeSHA = req.body.pull_request.merge_commit_sha;

    //If no merge SHA, then ignore
    if(!mergeSHA || mergeSHA == null){
        return;
    }

    //Getting base SHA
    var baseSHA = req.body.pull_request.base.sha;

    //Getting repository full name and number
    var fullRepoName = req.body.repository.full_name;
    var number = req.body.number;

    //Generating comment to make
    var cbadgeURL = process.env.CBADGE_URL;
    var comment = ['| Base ('+baseSHA.substring(0, 7)+') | Merge ('+mergeSHA.substring(0, 7)+')|',
        '\n|:---:|:---:|',
        '\n|![Base Coverage]('+cbadgeURL+'/'+req.params.project+'/coverage/'+baseSHA+')|![Merge Coverage]('+cbadgeURL+'/'+req.params.project+'/coverage/'+mergeSHA+')',
        '\n|![Base Test]('+cbadgeURL+'/'+req.params.project+'/test/'+baseSHA+')|![Merge Test]('+cbadgeURL+'/'+req.params.project+'/test/'+mergeSHA+')',
        '\n|![Base Build]('+cbadgeURL+'/'+req.params.project+'/build/'+baseSHA+')|![Merge Build]('+cbadgeURL+'/'+req.params.project+'/build/'+mergeSHA+')',
        '\n|![Base Configure]('+cbadgeURL+'/'+req.params.project+'/configure/'+baseSHA+')|![Merge Configure]('+cbadgeURL+'/'+req.params.project+'/configure/'+mergeSHA+')'].join();

    var options = {
        url: 'https://api.github.com/repos/'+fullRepoName+'/issues/'+req.body.number+'/comments',
        headers: {
            'User-Agent': 'CBadge/'+packageJSON.version,
            'Authorization': authenticate()
        },
        body: {
            body: comment
        }
    };
    request.post(options);
});

//Get coverage on a per-revision basis
router.get('/:project/coverage/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    request('http://open.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var coverage = JSON.parse(body);
            var loctested = 0;
            var locuntested = 0;
            var buildswithcoverage = 0;
            for(var i = 0; i < coverage.length; i++){
                if( coverage[i].loctested != null &&
                    Number(coverage[i].loctested) &&
                    coverage[i].locuntested != null &&
                    Number(coverage[i].locuntested)){

                    loctested += coverage[i].loctested;
                    locuntested += coverage[i].locuntested;
                }
            }
            if(loctested + locuntested > 0){
                var percent = loctested/(loctested+locuntested);
                percent = sigFigs(percent, 3);
                percent *= 100;
                if(percent > 80){
                    res.redirect(badge('coverage', percent+'%', 'brightgreen'));
                }else if(percent > 60){
                    res.redirect(badge('coverage', percent+'%', 'yellow'));
                }else{
                    res.redirect(badge('coverage', percent+'%', 'red'));
                }
            }else{
                res.redirect(badge('coverage', 'unknown', 'lightgrey'));
            }
        }
    });
});

router.get('/:project/build/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    request('http://open.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var builds = JSON.parse(body);
            var buildErrors = 0;
            var buildWarnings = 0;

            if(builds.length > 0){
                for(var i = 0; i < builds.length; i++){
                    if(Number(builds[i].builderrors)){
                        buildErrors += Number(builds[i].builderrors);
                    }
                    if(Number(builds[i].buildwarnings)){
                        buildWarnings += Number(builds[i].buildwarnings);
                    }
                }

                if(Number(buildErrors) > 0){
                    res.redirect(badge('build', buildErrors+' errors', 'red'));
                }else if(Number(buildWarnings) > 0){
                    res.redirect(badge('build', buildWarnings+' warnings', 'yellow'));
                }else{
                    res.redirect(badge('build', 'passing', 'brightgreen'));
                }
            }else{
                res.redirect(badge('build', 'unknown', 'lightgrey'));
            }

        }
    });
});

router.get('/:project/configure/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    request('http://open.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var builds = JSON.parse(body);
            var configureErrors = 0;
            var configureWarnings = 0;

            if(builds.length > 0){
                for(var i = 0; i < builds.length; i++){
                    if(Number(builds[i].configureerrors)){
                        configureErrors += Number(builds[i].configureerrors);
                    }
                    if(Number(builds[i].configurewarnings)){
                        configureWarnings += Number(builds[i].configurewarnings);
                    }
                }

                if(Number(configureErrors) > 0){
                    res.redirect(badge('configure', configureErrors+' errors', 'red'));
                }else if(Number(configureWarnings) > 0){
                    res.redirect(badge('configure', configureWarnings+' warnings', 'yellow'));
                }else{
                    res.redirect(badge('configure', 'passing', 'brightgreen'));
                }
            }else{
                res.redirect(badge('build', 'unknown', 'lightgrey'));
            }

        }
    });
});

router.get('/:project/test/:revision', function(req, res) {
    var request = require('request');
    var badge = require('../helpers/badge');

    request('http://trunk.cdash.org/api/?method=build&task=revisionstatus&project='+req.params.project+'&revision='+req.params.revision, function (error, response, body) {
        if (error){
            res.send(500);
        }else{
            var builds = JSON.parse(body);
            var testsPassed = 0;
            var testsFailed = 0;
            var testsNotRun = 0;

            for(var i = 0; i < builds.length; i++){
                if(Number(builds[i].testpassed)){
                    testsPassed += Number(builds[i].testpassed);
                }
                if(Number(builds[i].testfailed)){
                    testsFailed += Number(builds[i].testfailed);
                }
                if(Number(builds[i].testnotrun)){
                    testsNotRun += Number(builds[i].testnotrun);
                }
            }

            if(testsPassed+testsNotRun+testsFailed > 0){
                var percent = (testsPassed)/(testsPassed+testsNotRun+testsFailed);
                percent = sigFigs(percent, 3);
                percent *= 100;
                if(percent > 80){
                    res.redirect(badge('tests', percent+'%', 'brightgreen'));
                }else if (percent > 60){
                    res.redirect(badge('tests', percent+'%', 'yellow'));
                }else{
                    res.redirect(badge('tests', percent+'%', 'red'));
                }
            }else{
                res.redirect(badge('tests', 'unknown', 'lightgrey'));
            }
        }
    });
});

module.exports = router;
<|endoftext|>


<commit_before>import Ember from 'ember';

export function timeString(payload) {
  return `${payload.object} (Rendering: ${payload.initialRender ? 'initial' : 'update' })`;
}

if (/[\?\&]_ember-perf-timeline=true/ig.test(self.location.search)) {
  Ember.subscribe('render.component', {
    before(eventName, time, payload) {
      console.time(timeString(payload));
    },
    after(eventName, time, payload) {
      console.timeEnd(timeString(payload));
    }}
  );
}
export default {
  name: 'ember-perf-timeline',
  initialize() { }
};
<commit_msg>improve method names<commit_after>import Ember from 'ember';

export function timeString(payload) {
  return `${payload.object} (Rendering: ${payload.initialRender ? 'initial' : 'update' })`;
}

if (/[\?\&]_ember-perf-timeline=true/ig.test(self.location.search)) {
  Ember.subscribe('render.component', {
    before: function $beforeRenderComponent(eventName, time, payload) {
      console.time(timeString(payload));
    },
    after: function $afterRenderComponent(eventName, time, payload) {
      console.timeEnd(timeString(payload));
    }}
  );
}
export default {
  name: 'ember-perf-timeline',
  initialize() { }
};
<|endoftext|>


<commit_before>var _ = require("lodash");
var ipaddr = require('ipaddr.js');
var eventEmmiter = require('events').EventEmitter;
var util = require("util");
var methods = require("./methods");

/// Packaged Policies
var defaultPolicy = require("./policies/default");
var newPolicy = require("./policies/new");
var newMember = require("./policies/member");
///

/// Packaged Frameworks
var expressFramework = require("./frameworks/express");
///

var blackwall = function(policy) {
    // Set memory-stored policy to either passed policy or default
    this.policy = policy || defaultPolicy;
    eventEmmiter.call(this);
}

util.inherits(blackwall, eventEmmiter);

blackwall.prototype.createPolicy = function(name, policy) {
    this.policy = _.defaults(newPolicy, policy, { name: name });
}

blackwall.prototype.addList = function(name, rule, priority, force) {
    // Convert list name to lowercase
    var name = name.toLowerCase();

    // If policy exists and list is not forced
    if((this.policy.lists[name])&&(!force)) return { error: "List already exists! \n Lists are not case-sensitive." };

    // Create new list
    this.policy.lists[name] = {
        name: name,
        priority: priority || 0.1,
        members: new Object
    }

    // Assign rule
    this.policy.rules[name] = rule;

    return this.policy.lists[name];
}

blackwall.prototype.addMember = function(list, ip) {
    // Convert list name to lowercase
    var list = list.toLowerCase();

    // If list does not exist
    if(!this.policy.lists[list]) return { error: "List not found!" };

    // Check if ip-address is invalid (accepts both v4 and v6 ips)
    if(!ipaddr.isValid(ip)) return { error: "Invalid ip address!" };

    // Expand ipv6 address
    ip = ipaddr.parse(ip).toNormalizedString();

    this.policy.lists[list].members[ip] = newMember;
}

blackwall.prototype.lookup = function(ip) {
    return methods.lookup.apply(this, [ip]);
}

blackwall.prototype.admit = function(ip) {
    return methods.auto.apply(this, [ip]);
}

blackwall.prototype.enforce = function(method) {
    var array = _.rest(_.toArray(arguments));
    if(method === "express") return expressFramework.create.apply(this, array);
}

module.exports = blackwall;
<commit_msg>Added framework support<commit_after>var _ = require("lodash");
var ipaddr = require('ipaddr.js');
var eventEmmiter = require('events').EventEmitter;
var util = require("util");
var methods = require("./methods");

/// Packaged Policies
var defaultPolicy = require("./policies/default");
var newPolicy = require("./policies/new");
var newMember = require("./policies/member");
///

/// Packaged Frameworks
var frameworks = {
    express: require("./frameworks/express")
}
///

//// TODO
////// Add support for policy creation
///// Add ip range support
//// Add session-based policies
/// Add dump and restore

var blackwall = function(policy) {
    // Set memory-stored policy to either passed policy or default
    this.policy = policy || defaultPolicy;
    eventEmmiter.call(this);
}

util.inherits(blackwall, eventEmmiter);

blackwall.prototype.newPolicy = function(name, policy) {
    // Save old policy
    var oldPolicy = this.policy;
    // Create a new policy from defaults and user provided object
    this.policy = _.defaults(newPolicy, policy, { name: name });

    return oldPolicy;
}

blackwall.prototype.addList = function(name, rule, priority, force) {
    // Convert list name to lowercase
    var name = name.toLowerCase();

    // If policy exists and list is not forced
    if((this.policy.lists[name])&&(!force)) return { error: "List already exists! \n Lists are not case-sensitive." };

    // Create new list
    this.policy.lists[name] = {
        name: name,
        priority: priority || 0.1,
        members: new Object
    }

    // Assign rule
    this.policy.rules[name] = rule;

    return this.policy.lists[name];
}

blackwall.prototype.addMember = function(list, ip) {
    // Convert list name to lowercase
    var list = list.toLowerCase();

    // If list does not exist
    if(!this.policy.lists[list]) return { error: "List not found!" };

    // Check if ip-address is invalid (accepts both v4 and v6 ips)
    if(!ipaddr.isValid(ip)) return { error: "Invalid ip address!" };

    // Expand ipv6 address
    ip = ipaddr.parse(ip).toNormalizedString();

    this.policy.lists[list].members[ip] = newMember;
}

blackwall.prototype.admit = function(ip) {
    return methods.auto.apply(this, [ip]);
}

blackwall.prototype.addFramework = function(name, object) {
    return frameworks[name] = object;
}

blackwall.prototype.enforce = function(method) {
    if((_.isObject(frameworks[method])) && (_.isFunction(frameworks[method].create))) return frameworks[method].create.apply(this);
}

module.exports = blackwall;
<|endoftext|>


<commit_before>const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: './src/index',

  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js'
  },

  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },

  devServer: {
    host: 'localhost',
    port: 3000
  }
}<commit_msg>Webpack resolves .vue files.<commit_after>const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: './src/index',

  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js'
  },

  resolve: {
    extensions: ['.js', '.vue']
  },

  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },

  devServer: {
    host: 'localhost',
    port: 3000
  }
}<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

FBL.ns(function() { with (FBL) {

// ************************************************************************************************
// Constants

// ************************************************************************************************

FirebugReps.Table = domplate(Firebug.Rep,
{
    className: "table",

    tag:
        DIV({"class": "profileSizer", "tabindex": "-1" },
            TABLE({"class": "profileTable", cellspacing: 0, cellpadding: 0, width: "100%",
                "role": "grid"},
                THEAD({"class": "profileThead", "role": "presentation"},
                    TR({"class": "headerRow focusRow profileRow subFocusRow", "role": "row",
                        onclick: "$onClickHeader"},
                        FOR("column", "$object.columns",
                            TH({"class": "headerCell a11yFocus", "role": "columnheader",
                                $alphaValue: "$column.alphaValue"},
                                DIV({"class": "headerCellBox"},
                                    "$column.label"
                                )
                            )
                        )
                    )
                ),
                TBODY({"class": "profileTbody", "role": "presentation"},
                    FOR("row", "$object.data|getRows",
                        TR({"class": "focusRow profileRow subFocusRow", "role": "row"},
                            FOR("column", "$row|getColumns",
                                TD({"class": "a11yFocus profileCell", "role": "gridcell"},
                                    TAG("$column|getValueTag", {object: "$column"})
                                )
                            )
                        )
                    )
                )
            )
        ),

    getValueTag: function(object)
    {
        var rep = Firebug.getRep(object);
        return rep.shortTag || rep.tag;
    },

    getRows: function(data)
    {
        var props = this.getProps(data);
        if (!props.length)
            return [];
        return props;
    },

    getColumns: function(row)
    {
        if (typeof(row) != "object")
            return [row];

        var cols = [];
        for (var i=0; i<this.columns.length; i++)
            cols.push(row[this.columns[i].property]);
        return cols;
    },

    getProps: function(obj)
    {
        if (typeof(obj) != "object")
            return [obj];

        if (obj.length)
            return cloneArray(obj);

        var arr = [];
        for (var p in obj)
            arr.push(obj[p]);
        return arr;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Sorting

    onClickHeader: function(event)
    {
        var table = getAncestorByClass(event.target, "profileTable");
        var header = getAncestorByClass(event.target, "headerCell");
        if (!header)
            return;

        var numerical = !hasClass(header, "alphaValue");

        var colIndex = 0;
        for (header = header.previousSibling; header; header = header.previousSibling)
            ++colIndex;

        this.sort(table, colIndex, numerical);
    },

    sort: function(table, colIndex, numerical)
    {
        var tbody = getChildByClass(table, "profileTbody");
        var thead = getChildByClass(table, "profileThead");

        var values = [];
        for (var row = tbody.childNodes[0]; row; row = row.nextSibling)
        {
            var cell = row.childNodes[colIndex];
            var value = numerical ? parseFloat(cell.textContent) : cell.textContent;
            values.push({row: row, value: value});
        }

        values.sort(function(a, b) { return a.value < b.value ? -1 : 1; });

        var headerRow = thead.firstChild;
        var headerSorted = getChildByClass(headerRow, "headerSorted");
        removeClass(headerSorted, "headerSorted");
        if (headerSorted)
            headerSorted.removeAttribute('aria-sort');

        var header = headerRow.childNodes[colIndex];
        setClass(header, "headerSorted");

        if (!header.sorted || header.sorted == 1)
        {
            removeClass(header, "sortedDescending");
            setClass(header, "sortedAscending");
            header.setAttribute("aria-sort", "ascending");

            header.sorted = -1;

            for (var i = 0; i < values.length; ++i)
                tbody.appendChild(values[i].row);
        }
        else
        {
            removeClass(header, "sortedAscending");
            setClass(header, "sortedDescending");
            header.setAttribute("aria-sort", "descending")

            header.sorted = 1;

            for (var i = values.length-1; i >= 0; --i)
                tbody.appendChild(values[i].row);
        }
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Console logging

    log: function(data, cols, context)
    {
        // No arguments passed into console.table method, bail out for now,
        // but some error message could be displayed in the future.
        if (!data)
            return;

        // Get header info from passed argument (can be null).
        var columns = [];
        for (var i=0; cols && i<cols.length; i++)
        {
            var col = cols[i];
            columns.push({
                property: (typeof(col.property) != "undefined") ? col.property : col,
                label: (typeof(col.property) != "undefined") ? col.label : col.toString(),
                alphaValue: true
            });
        }

        // Generate header info from the data dynamically.
        if (!columns.length)
            columns = this.getHeaderColumns(data);

        // Limit string values. The default value for cropping is still to big
        // to be displayed within a table cell.
        // xxxHonza: is there better way how to do this?
        var prevValue = Firebug.stringCropLength;
        Firebug.stringCropLength = 15;

        try
        {
            this.columns = columns;
            var row = Firebug.Console.log({data: data, columns: columns}, context, "table", this, true);

            // Set vertical height for scroll bar.
            var tBody = row.querySelector(".profileTbody");
            var maxHeight = Firebug.tabularLogMaxHeight;
            if (maxHeight > 0 && tBody.clientHeight > maxHeight)
                tBody.style.height = maxHeight + "px";
        }
        catch (err)
        {
            if (FBTrace.DBG_CONSOLE)
                FBTrace.sysout("consoleInjector.table; EXCEPTION " + err, err);
        }
        finally
        {
            Firebug.stringCropLength = prevValue;
            delete this.columns;
        }
    },

    /**
     * Analyse data and return dynamically created list of columns.
     * @param {Object} data
     */
    getHeaderColumns: function(data)
    {
        // Get the first row in the object.
        var firstRow;
        for (var p in data)
        {
            firstRow = data[p];
            break;
        }

        if (typeof(firstRow) != "object")
            return [{label: "Object Properties"}]; //xxxHonza: localization

        // Put together a column property, label and type (type for default sorting logic).
        var header = [];
        for (var p in firstRow)
        {
            var value = firstRow[p];
            header.push({
                property: p,
                label: p,
                alphaValue: (typeof(value) != "number")
            });
        }

        return header;
    },
});

// ************************************************************************************************
}});
<commit_msg>Support dot notation for specifying logged properties/columns.<commit_after>/* See license.txt for terms of usage */

FBL.ns(function() { with (FBL) {

// ************************************************************************************************
// Constants

// ************************************************************************************************

FirebugReps.Table = domplate(Firebug.Rep,
{
    className: "table",

    tag:
        DIV({"class": "profileSizer", "tabindex": "-1" },
            TABLE({"class": "profileTable", cellspacing: 0, cellpadding: 0, width: "100%",
                "role": "grid"},
                THEAD({"class": "profileThead", "role": "presentation"},
                    TR({"class": "headerRow focusRow profileRow subFocusRow", "role": "row",
                        onclick: "$onClickHeader"},
                        FOR("column", "$object.columns",
                            TH({"class": "headerCell a11yFocus", "role": "columnheader",
                                $alphaValue: "$column.alphaValue"},
                                DIV({"class": "headerCellBox"},
                                    "$column.label"
                                )
                            )
                        )
                    )
                ),
                TBODY({"class": "profileTbody", "role": "presentation"},
                    FOR("row", "$object.data|getRows",
                        TR({"class": "focusRow profileRow subFocusRow", "role": "row"},
                            FOR("column", "$row|getColumns",
                                TD({"class": "a11yFocus profileCell", "role": "gridcell"},
                                    TAG("$column|getValueTag", {object: "$column"})
                                )
                            )
                        )
                    )
                )
            )
        ),

    getValueTag: function(object)
    {
        var rep = Firebug.getRep(object);
        return rep.shortTag || rep.tag;
    },

    getRows: function(data)
    {
        var props = this.getProps(data);
        if (!props.length)
            return [];
        return props;
    },

    getColumns: function(row)
    {
        if (typeof(row) != "object")
            return [row];

        var cols = [];
        for (var i=0; i<this.columns.length; i++)
        {
            var prop = this.columns[i].property;
            var props = (typeof(prop) == "string") ? prop.split(".") : [prop];

            var value = row;
            try {
                for (var p in props)
                    value = value[props[p]];
            } catch (e) {
            }

            cols.push(value);
        }
        return cols;
    },

    getProps: function(obj)
    {
        if (typeof(obj) != "object")
            return [obj];

        if (obj.length)
            return cloneArray(obj);

        var arr = [];
        for (var p in obj)
            arr.push(obj[p]);
        return arr;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Sorting

    onClickHeader: function(event)
    {
        var table = getAncestorByClass(event.target, "profileTable");
        var header = getAncestorByClass(event.target, "headerCell");
        if (!header)
            return;

        var numerical = !hasClass(header, "alphaValue");

        var colIndex = 0;
        for (header = header.previousSibling; header; header = header.previousSibling)
            ++colIndex;

        this.sort(table, colIndex, numerical);
    },

    sort: function(table, colIndex, numerical)
    {
        var tbody = getChildByClass(table, "profileTbody");
        var thead = getChildByClass(table, "profileThead");

        var values = [];
        for (var row = tbody.childNodes[0]; row; row = row.nextSibling)
        {
            var cell = row.childNodes[colIndex];
            var value = numerical ? parseFloat(cell.textContent) : cell.textContent;
            values.push({row: row, value: value});
        }

        values.sort(function(a, b) { return a.value < b.value ? -1 : 1; });

        var headerRow = thead.firstChild;
        var headerSorted = getChildByClass(headerRow, "headerSorted");
        removeClass(headerSorted, "headerSorted");
        if (headerSorted)
            headerSorted.removeAttribute('aria-sort');

        var header = headerRow.childNodes[colIndex];
        setClass(header, "headerSorted");

        if (!header.sorted || header.sorted == 1)
        {
            removeClass(header, "sortedDescending");
            setClass(header, "sortedAscending");
            header.setAttribute("aria-sort", "ascending");

            header.sorted = -1;

            for (var i = 0; i < values.length; ++i)
                tbody.appendChild(values[i].row);
        }
        else
        {
            removeClass(header, "sortedAscending");
            setClass(header, "sortedDescending");
            header.setAttribute("aria-sort", "descending")

            header.sorted = 1;

            for (var i = values.length-1; i >= 0; --i)
                tbody.appendChild(values[i].row);
        }
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    // Console logging

    log: function(data, cols, context)
    {
        // No arguments passed into console.table method, bail out for now,
        // but some error message could be displayed in the future.
        if (!data)
            return;

        // Get header info from passed argument (can be null).
        var columns = [];
        for (var i=0; cols && i<cols.length; i++)
        {
            var col = cols[i];
            columns.push({
                property: (typeof(col.property) != "undefined") ? col.property : col,
                label: (typeof(col.property) != "undefined") ? col.label : col.toString(),
                alphaValue: true
            });
        }

        // Generate header info from the data dynamically.
        if (!columns.length)
            columns = this.getHeaderColumns(data);

        // Limit string values. The default value for cropping is still to big
        // to be displayed within a table cell.
        // xxxHonza: is there better way how to do this?
        var prevValue = Firebug.stringCropLength;
        Firebug.stringCropLength = 15;

        try
        {
            this.columns = columns;
            var row = Firebug.Console.log({data: data, columns: columns}, context, "table", this, true);

            // Set vertical height for scroll bar.
            var tBody = row.querySelector(".profileTbody");
            var maxHeight = Firebug.tabularLogMaxHeight;
            if (maxHeight > 0 && tBody.clientHeight > maxHeight)
                tBody.style.height = maxHeight + "px";
        }
        catch (err)
        {
            if (FBTrace.DBG_CONSOLE)
                FBTrace.sysout("consoleInjector.table; EXCEPTION " + err, err);
        }
        finally
        {
            Firebug.stringCropLength = prevValue;
            delete this.columns;
        }
    },

    /**
     * Analyse data and return dynamically created list of columns.
     * @param {Object} data
     */
    getHeaderColumns: function(data)
    {
        // Get the first row in the object.
        var firstRow;
        for (var p in data)
        {
            firstRow = data[p];
            break;
        }

        if (typeof(firstRow) != "object")
            return [{label: "Object Properties"}]; //xxxHonza: localization

        // Put together a column property, label and type (type for default sorting logic).
        var header = [];
        for (var p in firstRow)
        {
            var value = firstRow[p];
            header.push({
                property: p,
                label: p,
                alphaValue: (typeof(value) != "number")
            });
        }

        return header;
    },
});

// ************************************************************************************************
}});
<|endoftext|>