function _transposeInto(a, d) {
    for (var i = 0; i < 4; i += 1) {
        for (var j = 0; j < 4; j += 1) {
            d[i + j * 4] = a[j + i * 4];
        };
    };
};
function _transpose(a) {
    var d = new WebGLFloatArray(16);
    for (var i = 0; i < 4; i += 1) {
        for (var j = 0; j < 4; j += 1) {
            d[i + j * 4] = a[j + i * 4];
        };
    };
    return d;
};
function _mcopy(s,d) {
    d[ 0] = s[0];
    d[ 1] = s[1];
    d[ 2] = s[2];
    d[ 3] = s[3];
    d[ 4] = s[4];
    d[ 5] = s[5];
    d[ 6] = s[6];
    d[ 7] = s[7];
    d[ 8] = s[8];
    d[ 9] = s[9];
    d[10] = s[10];
    d[11] = s[11];
    d[12] = s[12];
    d[13] = s[13];
    d[14] = s[14];
    d[15] = s[15];
    return d;
};
function _matx(a, b, d) {
    var a11 = a[0];
    var a21 = a[1];
    var a31 = a[2];
    var a41 = a[3];
    var a12 = a[4];
    var a22 = a[5];
    var a32 = a[6];
    var a42 = a[7];
    var a13 = a[8];
    var a23 = a[9];
    var a33 = a[10];
    var a43 = a[11];
    var a14 = a[12];
    var a24 = a[13];
    var a34 = a[14];
    var a44 = a[15];
    var b11 = b[0];
    var b21 = b[1];
    var b31 = b[2];
    var b41 = b[3];
    var b12 = b[4];
    var b22 = b[5];
    var b32 = b[6];
    var b42 = b[7];
    var b13 = b[8];
    var b23 = b[9];
    var b33 = b[10];
    var b43 = b[11];
    var b14 = b[12];
    var b24 = b[13];
    var b34 = b[14];
    var b44 = b[15];
    d[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
    d[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
    d[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
    d[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
    d[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
    d[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
    d[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
    d[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
    d[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
    d[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
    d[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
    d[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
    d[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
    d[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
    d[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
    d[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
};
function _matx3(a, b, d) {
    var a11 = a[0];
    var a21 = a[1];
    var a31 = a[2];
    var a12 = a[4];
    var a22 = a[5];
    var a32 = a[6];
    var a13 = a[8];
    var a23 = a[9];
    var a33 = a[10];
    var a14 = a[12];
    var a24 = a[13];
    var a34 = a[14];
    var b11 = b[0];
    var b21 = b[1];
    var b31 = b[2];
    var b12 = b[4];
    var b22 = b[5];
    var b32 = b[6];
    var b13 = b[8];
    var b23 = b[9];
    var b33 = b[10];
    var b14 = b[12];
    var b24 = b[13];
    var b34 = b[14];
    d[0] = a11 * b11 + a12 * b21 + a13 * b31;
    d[4] = a11 * b12 + a12 * b22 + a13 * b32;
    d[8] = a11 * b13 + a12 * b23 + a13 * b33;
    d[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14;
    d[1] = a21 * b11 + a22 * b21 + a23 * b31;
    d[5] = a21 * b12 + a22 * b22 + a23 * b32;
    d[9] = a21 * b13 + a22 * b23 + a23 * b33;
    d[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24;
    d[2] = a31 * b11 + a32 * b21 + a33 * b31;
    d[6] = a31 * b12 + a32 * b22 + a33 * b32;
    d[10] = a31 * b13 + a32 * b23 + a33 * b33;
    d[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34;
    d[3] = 0;
    d[7] = 0;
    d[11] = 0;
    d[15] = 1;
};
function _matx3Ofs(a, b, d, o) {
    var a11 = a[0];
    var a21 = a[1];
    var a31 = a[2];
    var a12 = a[4];
    var a22 = a[5];
    var a32 = a[6];
    var a13 = a[8];
    var a23 = a[9];
    var a33 = a[10];
    var a14 = a[12];
    var a24 = a[13];
    var a34 = a[14];
    var b11 = b[0];
    var b21 = b[1];
    var b31 = b[2];
    var b12 = b[4];
    var b22 = b[5];
    var b32 = b[6];
    var b13 = b[8];
    var b23 = b[9];
    var b33 = b[10];
    var b14 = b[12];
    var b24 = b[13];
    var b34 = b[14];
    d[0 + o] = a11 * b11 + a12 * b21 + a13 * b31;
    d[4 + o] = a11 * b12 + a12 * b22 + a13 * b32;
    d[8 + o] = a11 * b13 + a12 * b23 + a13 * b33;
    d[12 + o] = a11 * b14 + a12 * b24 + a13 * b34 + a14;
    d[1 + o] = a21 * b11 + a22 * b21 + a23 * b31;
    d[5 + o] = a21 * b12 + a22 * b22 + a23 * b32;
    d[9 + o] = a21 * b13 + a22 * b23 + a23 * b33;
    d[13 + o] = a21 * b14 + a22 * b24 + a23 * b34 + a24;
    d[2 + o] = a31 * b11 + a32 * b21 + a33 * b31;
    d[6 + o] = a31 * b12 + a32 * b22 + a33 * b32;
    d[10 + o] = a31 * b13 + a32 * b23 + a33 * b33;
    d[14 + o] = a31 * b14 + a32 * b24 + a33 * b34 + a34;
    d[3 + o] = 0;
    d[7 + o] = 0;
    d[11 + o] = 0;
    d[15 + o] = 1;
};
function mat4(a) {
    //    var e = new Array(16);
    var e = new WebGLFloatArray(16);
    //var e = new WebGLFloatArray(a);
    var m = { "elements" : e, "opt" : null };
    for (var i = 0; i < 16; i += 1) {
        e[i] = a[i];
    };
    return m;
};
function mat4x(a) {
    var e = new WebGLFloatArray(16);
    var m = { "elements" : e, "opt" : null };
    _transposeInto(a, e);
    return m;
};
function _mat4i() {
    return new WebGLFloatArray([1.0, 0.0, 0.0, 0.0,
                                0.0, 1.0, 0.0, 0.0,
                                0.0, 0.0, 1.0, 0.0,
                                0.0, 0.0, 0.0, 1.0]);
};

function mat4i() {
    return mat4 (new WebGLFloatArray([1.0, 0.0, 0.0, 0.0,
                                      0.0, 1.0, 0.0, 0.0,
                                      0.0, 0.0, 1.0, 0.0,
                                      0.0, 0.0, 0.0, 1.0]));
};
function matMulInto(a, b, dest) {
    var ael = a.elements;
    var bel = b.elements;
    var del = dest.elements;
    var a11 = ael[0];
    var a21 = ael[1];
    var a31 = ael[2];
    var a41 = ael[3];
    var a12 = ael[4];
    var a22 = ael[5];
    var a32 = ael[6];
    var a42 = ael[7];
    var a13 = ael[8];
    var a23 = ael[9];
    var a33 = ael[10];
    var a43 = ael[11];
    var a14 = ael[12];
    var a24 = ael[13];
    var a34 = ael[14];
    var a44 = ael[15];
    var b11 = bel[0];
    var b21 = bel[1];
    var b31 = bel[2];
    var b41 = bel[3];
    var b12 = bel[4];
    var b22 = bel[5];
    var b32 = bel[6];
    var b42 = bel[7];
    var b13 = bel[8];
    var b23 = bel[9];
    var b33 = bel[10];
    var b43 = bel[11];
    var b14 = bel[12];
    var b24 = bel[13];
    var b34 = bel[14];
    var b44 = bel[15];
    del[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
    del[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
    del[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
    del[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
    del[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
    del[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
    del[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
    del[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
    del[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
    del[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
    del[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
    del[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
    del[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
    del[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
    del[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
    del[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
    return dest;
};
function _matMulInto(a, b, dest) {
    var ael = a.elements;
    var bel = b.elements;
    var a11 = ael[0];
    var a21 = ael[1];
    var a31 = ael[2];
    var a41 = ael[3];
    var a12 = ael[4];
    var a22 = ael[5];
    var a32 = ael[6];
    var a42 = ael[7];
    var a13 = ael[8];
    var a23 = ael[9];
    var a33 = ael[10];
    var a43 = ael[11];
    var a14 = ael[12];
    var a24 = ael[13];
    var a34 = ael[14];
    var a44 = ael[15];
    var b11 = bel[0];
    var b21 = bel[1];
    var b31 = bel[2];
    var b41 = bel[3];
    var b12 = bel[4];
    var b22 = bel[5];
    var b32 = bel[6];
    var b42 = bel[7];
    var b13 = bel[8];
    var b23 = bel[9];
    var b33 = bel[10];
    var b43 = bel[11];
    var b14 = bel[12];
    var b24 = bel[13];
    var b34 = bel[14];
    var b44 = bel[15];
    dest[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
    dest[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
    dest[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
    dest[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
    dest[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
    dest[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
    dest[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
    dest[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
    dest[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
    dest[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
    dest[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
    dest[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
    dest[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
    dest[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
    dest[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
    dest[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
    return dest;
};
function matMul(a, b) {
    var ael = a.elements;
    var bel = b.elements;
    var dest = mat4i();
    var del = dest.elements;
    var a11 = ael[0];
    var a21 = ael[1];
    var a31 = ael[2];
    var a41 = ael[3];
    var a12 = ael[4];
    var a22 = ael[5];
    var a32 = ael[6];
    var a42 = ael[7];
    var a13 = ael[8];
    var a23 = ael[9];
    var a33 = ael[10];
    var a43 = ael[11];
    var a14 = ael[12];
    var a24 = ael[13];
    var a34 = ael[14];
    var a44 = ael[15];
    var b11 = bel[0];
    var b21 = bel[1];
    var b31 = bel[2];
    var b41 = bel[3];
    var b12 = bel[4];
    var b22 = bel[5];
    var b32 = bel[6];
    var b42 = bel[7];
    var b13 = bel[8];
    var b23 = bel[9];
    var b33 = bel[10];
    var b43 = bel[11];
    var b14 = bel[12];
    var b24 = bel[13];
    var b34 = bel[14];
    var b44 = bel[15];
    del[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
    del[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
    del[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
    del[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
    del[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
    del[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
    del[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
    del[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
    del[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
    del[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
    del[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
    del[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
    del[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
    del[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
    del[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
    del[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
    return dest;
};
function _translationxquatIntoX(tx, ty, tz, qw, qx, qy, qz, d) {
    d[0] = (1.0 - 2.0 * (qy * qy + qz * qz));
    d[4] = 2.0 * (qx * qy - qz * qw);
    d[8] = 2.0 * (qx * qz + qy * qw);
    d[12] = 0;
    d[1] = 2.0 * (qx * qy + qz * qw);
    d[5] = (1.0 - 2.0 * (qx * qx + qz * qz));
    d[9] = 2.0 * (qy * qz - qx * qw);
    d[13] = 0;
    d[2] = 2.0 * (qx * qz - qy * qw);
    d[6] = 2.0 * (qy * qz + qx * qw);
    d[10] = (1.0 - 2.0 * (qx * qx + qy * qy));
    d[14] = 0;
    d[3] = tx * (1.0 - 2.0 * (qy * qy + qz * qz)) + ty * (2.0 * (qx * qy + qz * qw)) + tz * (2.0 * (qx * qz - qy * qw));
    d[7] = tx * (2.0 * (qx * qy - qz * qw)) + ty * (1.0 - 2.0 * (qx * qx + qz * qz)) + tz * (2.0 * (qy * qz + qx * qw));
    d[11] = tx * (2.0 * (qx * qz + qy * qw)) + ty * (2.0 * (qy * qz - qx * qw)) + tz * (1.0 - 2.0 * (qx * qx + qy * qy));
    d[15] = 1;
};
function _translationxquatInto(tx, ty, tz, qw, qx, qy, qz, d) {
    d[0] = (1.0 - 2.0 * (qy * qy + qz * qz));
    d[4] = 2.0 * (qx * qy + qz * qw);
    d[8] = 2.0 * (qx * qz - qy * qw);
    d[12] = tx;
    d[1] = 2.0 * (qx * qy - qz * qw);
    d[5] = (1.0 - 2.0 * (qx * qx + qz * qz));
    d[9] = 2.0 * (qy * qz + qx * qw);
    d[13] = ty;
    d[2] = 2.0 * (qx * qz + qy * qw);
    d[6] = 2.0 * (qy * qz - qx * qw);
    d[10] = (1.0 - 2.0 * (qx * qx + qy * qy));
    d[14] = tz;
    d[3] = 0;
    d[7] = 0;
    d[11] = 0;
    d[15] = 1;
};

function _translationxquatInto2(tx, ty, tz, qw, qx, qy, qz, d) {
    var qxx = qx * qx;
    var qxy = qx * qy;
    var qxz = qx * qz;
    var qxw = qx * qw;
    var qyx = qy * qx;
    var qyy = qy * qy;
    var qyz = qy * qz;
    var qyw = qy * qw;
    var qzx = qz * qx;
    var qzy = qz * qy;
    var qzz = qz * qz;
    var qzw = qz * qw;
    d[0] = (1.0 - 2.0 * (qyy + qzz));
    d[4] = 2.0 * (qxy + qzw);
    d[8] = 2.0 * (qxz - qyw);
    d[12] = tx;
    d[1] = 2.0 * (qxy - qzw);
    d[5] = (1.0 - 2.0 * (qxx + qzz));
    d[9] = 2.0 * (qyz + qxw);
    d[13] = ty;
    d[2] = 2.0 * (qxz + qyw);
    d[6] = 2.0 * (qyz - qxw);
    d[10] = (1.0 - 2.0 * (qxx + qyy));
    d[14] = tz;
    d[3] = 0;
    d[7] = 0;
    d[11] = 0;
    d[15] = 1;
};
function quatMat(q) {
    var w = q[0];
    var x = q[1];
    var y = q[2];
    var z = q[3];
    return mat4x([1.0 - 2.0 * (Math.pow(y, 2) + Math.pow(z, 2)), 2.0 * (x * y + z * w), 2.0 * (x * z - y * w), 0.0, 2.0 * (x * y - z * w), 1.0 - 2.0 * (Math.pow(x, 2) + Math.pow(z, 2)), 2.0 * (y * z + x * w), 0.0, 2.0 * (x * z + y * w), 2.0 * (y * z - x * w), 1.0 - 2.0 * (Math.pow(x, 2) + Math.pow(y, 2)), 0.0, 0.0, 0.0, 0.0, 1.0]);
};
function translationx(x, y, z) {
    var m = mat4i();
    (m.elements)[3] = x;
    (m.elements)[7] = y;
    (m.elements)[11] = z;
    return m;
};
function translation(x, y, z) {
    var m = mat4i();
    (m.elements)[12] = x;
    (m.elements)[13] = y;
    (m.elements)[14] = z;
    return m;
};
function rotation(aRadians, x, y, z) {
    var l = Math.sqrt(x * x + y * y + z * z);
    var nx = x / l;
    var ny = y / l;
    var nz = z / l;
    var c = Math.cos(aRadians);
    var s = Math.sin(aRadians);
    var oneMinusC = 1 - c;
    var xxc = nx * nx * oneMinusC;
    var xyc = nx * ny * oneMinusC;
    var xzc = nx * nz * oneMinusC;
    var yyc = ny * ny * oneMinusC;
    var yzc = ny * nz * oneMinusC;
    var zzc = nz * nz * oneMinusC;
    var xs = nx * s;
    var ys = ny * s;
    var zs = nz * s;
    return mat4x([xxc + c, xyc - zs, xzc + ys, 0, xyc + zs, yyc + c, yzc - xs, 0, xzc - ys, yzc + xs, zzc + c, 0, 0, 0, 0, 1]);
};
function ortho(left, right, bottom, top, near, far) {
    var rL = right - left;
    var _rplusl = -(right + left);
    var tB = top - bottom;
    var _tplusb = -(top + bottom);
    var nF = near - far;
    var fplusn = far + near;
    return mat4x([2 / rL, 0.0, 0.0, _rplusl / rL, 0.0, 2 / tB, 0.0, _tplusb / tB, 0.0, 0.0, 2 / nF, fplusn / nF, 0.0, 0.0, 0.0, 1.0]);
};
function frustum(left, right, bottom, top, near, far) {
    var _2n = 2.0 * near;
    var _2nf = _2n * far;
    var rL = right - left;
    var rplusl = right + left;
    var tB = top - bottom;
    var tplusb = top + bottom;
    var nF = near - far;
    var fplusn = far + near;
    return mat4(_transpose([_2n / rL, 0.0, rplusl / rL, 0.0, 0.0, _2n / tB, tplusb / tB, 0.0, 0.0, 0.0, fplusn / nF, _2nf / nF, 0.0, 0.0, -1.0, 0.0]));
};
function lookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) {
    var fx = centerX - eyeX;
    var fy = centerY - eyeY;
    var fz = centerZ - eyeZ;
    var fLen = Math.sqrt(fx * fx + fy * fy + fz * fz);
    var upLen = Math.sqrt(upX * upX + upY * upY + upZ * upZ);
    fx = fx / fLen;
    fy = fy / fLen;
    fz = fz / fLen;
    upX = upX / upLen;
    upY = upY / upLen;
    upZ = upZ / upLen;
    var sx = null;
    var sy = null;
    var sz = null;
    sx = fy * upZ - fz * upY;
    sy = fz * upX - fx * upZ;
    sz = fx * upY - fy * upX;
    var ux = null;
    var uy = null;
    var uz = null;
    ux = sy * fz - sz * fy;
    uy = sz * fx - sx * fz;
    uz = sx * fy - sy * fx;
    return matMul(mat4x([sx, sy, sz, 0.0, ux, uy, uz, 0.0, -fx, -fy, -fz, 0.0, 0.0, 0.0, 0.0, 1.0]), translation(-eyeX, -eyeY, -eyeZ));
};