module.exports = Rect;
module.exports.trim = trimRect;
module.exports.merge = mergeRect;
module.exports.contains = containsRect;
module.exports.overlaps = overlapsRect;
module.exports.is = isRect;

function Rect(x, y, width, height) {
    if(x != undefined && typeof x != 'number') { throw new Error('x must be a number'); }
    if(y != undefined && typeof y != 'number') { throw new Error('y must be a number'); }
    if(width != undefined && typeof width != 'number') { throw new Error('width must be a number'); }
    if(height != undefined && typeof height != 'number') { throw new Error('height must be a number'); }
    var rect = {
        x: x || 0,
        y: y || 0,
        get cx() { return cx(rect); },
        set cx(value) { return cx(rect, value); },
        get cy() { return cy(rect); },
        set cy(value) { return cy(rect, value); },
        width: width || 0,
        height: height || 0
    };
    return rect;
}

function cx(rect, newCx) {
    var curCx = rect.x + (rect.width / 2);
    if(newCx != undefined) {
        rect.x += newCx - curCx;
    }
    return curCx;
}

function cy(rect, newCy) {
    var curCy = rect.y + (rect.height / 2);
    if(newCy != undefined) {
        rect.y += newCy - curCy;
    }
    return curCy;
}

function isRect(obj) {
    return (
        typeof obj.x == 'number' &&
        typeof obj.y == 'number' &&
        typeof obj.cx == 'number' &&
        typeof obj.cy == 'number' &&
        typeof obj.width == 'number' &&
        typeof obj.height == 'number'
    );
}

function mergeRect(rectA, rectB) {
    var x = rectA.x < rectB.x ? rectA.x : rectB.x;
    var y = rectA.y < rectB.y ? rectA.y : rectB.y;

    if(rectA.x + rectA.width > rectB.x + rectB.width) {
        var width = (rectA.x - x) + rectA.width;
    } else {
        var width = (rectB.x - x) + rectB.width;
    }
    if(rectA.y + rectA.height > rectB.y + rectB.height) {
        var height = (rectA.y - y) + rectA.height;
    } else {
        var height = (rectB.y - y) + rectB.height;
    }

    return Rect(x, y, width, height);
}

function trimRect(rectA, rectB) {
    var x = rectA.x > rectB.x ? rectA.x : rectB.x;
    var y = rectA.y > rectB.y ? rectA.y : rectB.y;

    if(rectA.x + rectA.width < rectB.x + rectB.width) {
        var width = (rectA.x - x) + rectA.width;
    } else {
        var width = (rectB.x - x) + rectB.width;
    }
    if(rectA.y + rectA.height < rectB.y + rectB.height) {
        var height = (rectA.y - y) + rectA.height;
    } else {
        var height = (rectB.y - y) + rectB.height;
    }

    return Rect(x, y, width, height);

}

function containsRect(rect, subjectRect) {
    return (
        subjectRect.x >= rect.x &&
        subjectRect.y >= rect.y &&
        subjectRect.x + subjectRect.width <= rect.x + rect.width &&
        subjectRect.y + subjectRect.height <= rect.y + rect.height
    );
}

function overlapsRect(rectA, rectB) {
    var x = false;
    var y = false;

    var ax = rectA.x;
    var axx = rectA.x + rectA.width - 1;
    var ay = rectA.y;
    var ayy = rectA.y + rectA.height - 1;

    var bx = rectB.x;
    var bxx = rectB.x + rectB.width - 1;
    var by = rectB.y;
    var byy = rectB.y + rectB.height - 1;

    return axx >= bx && ax <= bxx && ayy >= by && ay <= byy
}

@@ -682,576 +682,77 @@
     
-get cx() %7B return cx(rect); %7D,%0A        set cx(value) %7B return cx(rect, value); %7D,%0A        get cy() %7B return cy(rect); %7D,%0A        set cy(value) %7B return cy(rect, value); %7D,%0A        width: width %7C%7C 0,%0A        height: height %7C%7C 0%0A    %7D;%0A    return rect;%0A%7D%0A%0Afunction cx(rect, newCx) %7B%0A    var curCx = rect.x + (rect.width / 2);%0A    if(newCx != undefined) %7B%0A        rect.x += newCx - curCx;%0A    %7D%0A    return curCx;%0A%7D%0A%0Afunction cy(rect, newCy) %7B%0A    var curCy = rect.y + (rect.height / 2);%0A    if(newCy != undefined) %7B%0A        rect.y += newCy - curCy;%0A    %7D%0A    return curCy
+width: width %7C%7C 0,%0A        height: height %7C%7C 0%0A    %7D;%0A    return rect
 ;%0A%7D%0A
@@ -864,82 +864,8 @@
  &&%0A
-        typeof obj.cx == 'number' &&%0A        typeof obj.cy == 'number' &&%0A
     

Remove cx and cy from Rect in a trade for performance.