**************************
Vector2 math functions
*************************
510073
function forceAtlas2Worker() {
    var vec2 = {
        create: function() {
            return new Float32Array(2);
        },
        dist: function(a, b) {
            var x = b[0] - a[0];
            var y = b[1] - a[1];
            return Math.sqrt(x*x + y*y);
        },
        len: function(a) {
            var x = a[0];
            var y = a[1];
            return Math.sqrt(x*x + y*y);
        },
        scaleAndAdd: function(out, a, b, scale) {
            out[0] = a[0] + b[0] * scale;
            out[1] = a[1] + b[1] * scale;
            return out;
        },
        scale: function(out, a, b) {
            out[0] = a[0] * b;
            out[1] = a[1] * b;
            return out;
        },
        add: function(out, a, b) {
            out[0] = a[0] + b[0];
            out[1] = a[1] + b[1];
            return out;
        },
        sub: function(out, a, b) {
            out[0] = a[0] - b[0];
            out[1] = a[1] - b[1];
            return out;
        },
        normalize: function(out, a) {
            var x = a[0];
            var y = a[1];
            var len = x*x + y*y;
            if (len > 0) {
                //TODO: evaluate use of glm_invsqrt here?
                len = 1 / Math.sqrt(len);
                out[0] = a[0] * len;
                out[1] = a[1] * len;
            }
            return out;
        },
        negate: function(out, a) {
            out[0] = -a[0];
            out[1] = -a[1];
            return out;
        },
        copy: function(out, a) {
            out[0] = a[0];
            out[1] = a[1];
            return out;
        },
        set: function(out, x, y) {
            out[0] = x;
            out[1] = y;
            return out;
        }
    }

    /****************************
     * Class: Region
     ***************************/

    function Region() {

        this.subRegions = [];

        this.nSubRegions = 0;

        this.node = null;

        this.mass = 0;

        this.centerOfMass = null;

        this.bbox = new Float32Array(4);

        this.size = 0;
    }

    var regionProto = Region.prototype;

    // Reset before update
    regionProto.beforeUpdate = function() {
        for (var i = 0; i < this.nSubRegions; i++) {
            this.subRegions[i].beforeUpdate();
        }
        this.mass = 0;
        if (this.centerOfMass) {
            this.centerOfMass[0] = 0;
            this.centerOfMass[1] = 0;
        }
        this.nSubRegions = 0;
        this.node = null;
    };
    // Clear after update
    regionProto.afterUpdate = function() {
        this.subRegions.length = this.nSubRegions;
        for (var i = 0; i < this.nSubRegions; i++) {
            this.subRegions[i].afterUpdate();
        }
    };

    regionProto.addNode = function(node) {
        if (this.nSubRegions === 0) {
            if (this.node == null) {
                this.node = node;
                return;
            }
            // Already have node, subdivide self.
            else {
                this._addNodeToSubRegion(this.node);
                this.node = null;
            }
        }
        this._addNodeToSubRegion(node);

        this._updateCenterOfMass(node);
    };

    regionProto.findSubRegion = function(x, y) {
        for (var i = 0; i < this.nSubRegions; i++) {
            var region = this.subRegions[i];
            if (region.contain(x, y)) {
                return region;
            }
        }
    };

    regionProto.contain = function(x, y) {
        return this.bbox[0] <= x
            && this.bbox[2] >= x
            && this.bbox[1] <= y
            && this.bbox[3] >= y;
    };

    regionProto.setBBox = function(minX, minY, maxX, maxY) {
        // Min
        this.bbox[0] = minX;
        this.bbox[1] = minY;
        // Max
        this.bbox[2] = maxX;
        this.bbox[3] = maxY;

        this.size = (maxX - minX + maxY - minY) / 2;
    };

    regionProto._newSubRegion = function() {
        var subRegion = this.subRegions[this.nSubRegions];
        if (!subRegion) {
            subRegion = new Region();
            this.subRegions[this.nSubRegions] = subRegion;
        }
        this.nSubRegions++;
        return subRegion;
    };

    regionProto._addNodeToSubRegion = function(node) {
        var subRegion = this.findSubRegion(node.position[0], node.position[1]);
        var bbox = this.bbox;
        if (!subRegion) {
            var cx = (bbox[0] + bbox[2]) / 2;
            var cy = (bbox[1] + bbox[3]) / 2;
            var w = (bbox[2] - bbox[0]) / 2;
            var h = (bbox[3] - bbox[1]) / 2;

            var xi = node.position[0] >= cx ? 1 : 0;
            var yi = node.position[1] >= cy ? 1 : 0;

            var subRegion = this._newSubRegion();
            // Min
            subRegion.setBBox(
                // Min
                xi * w + bbox[0],
                yi * h + bbox[1],
                // Max
                (xi + 1) * w + bbox[0],
                (yi + 1) * h + bbox[1]
            );
        }

        subRegion.addNode(node);
    };

    regionProto._updateCenterOfMass = function(node) {
        // Incrementally update
        if (this.centerOfMass == null) {
            this.centerOfMass = new Float32Array(2);
        }
        var x = this.centerOfMass[0] * this.mass;
        var y = this.centerOfMass[1] * this.mass;
        x += node.position[0] * node.mass;
        y += node.position[1] * node.mass;
        this.mass += node.mass;
        this.centerOfMass[0] = x / this.mass;
        this.centerOfMass[1] = y / this.mass;
    };

    /****************************
     * Class: Graph Node
     ***************************/
    function GraphNode() {
        this.position = new Float32Array(2);

        this.force = vec2.create();
        this.forcePrev = vec2.create();

        // If repulsionByDegree is true
        //  mass = inDegree + outDegree + 1
        // Else
        //  mass is manually set
        this.mass = 1;

        this.inDegree = 0;
        this.outDegree = 0;

        // Optional
        // this.size = 1;
    }

    /****************************
     * Class: Graph Edge
     ***************************/
    function GraphEdge(source, target) {
        this.source = source;
        this.target = target;

        this.weight = 1;
    }

    /****************************
     * Class: ForceStlas2
     ***************************/
    function ForceAtlas2() {
        //-------------
        // Configs

        // If auto settings is true
        //  barnesHutOptimize,
        //  barnesHutTheta,
        //  scaling,
        //  jitterTolerence
        // Will be set by the system automatically
        //  preventOverlap will be set false
        //  if node size is not given
        this.autoSettings = true;

        // Barnes Hut
        // http://arborjs.org/docs/barnes-hut
        this.barnesHutOptimize = true;
        this.barnesHutTheta = 1.5;

        // Force Atlas2 Configs
        this.repulsionByDegree = true;

        this.linLogMode = false;

        this.strongGravityMode = false;
        this.gravity = 1.0;

        this.scaling = 1.0;

        this.edgeWeightInfluence = 1.0;
        this.jitterTolerence = 0.1;

        // TODO
        this.preventOverlap = false;
        this.dissuadeHubs = false;

        //
        this.rootRegion = new Region();
        this.rootRegion.centerOfMass = vec2.create();

        this.nodes = [];

        this.edges = [];

        this.bbox = new Float32Array(4);

        this.gravityCenter = null;

        this._massArr = null;

        this._swingingArr = null;

        this._sizeArr = null;

        this._globalSpeed = 0;
    }

    var forceAtlas2Proto = ForceAtlas2.prototype;

    forceAtlas2Proto.initNodes = function(positionArr, massArr, sizeArr) {
        var nNodes = massArr.length;
        this.nodes.length = 0;
        var haveSize = typeof(sizeArr) != 'undefined';
        for (var i = 0; i < nNodes; i++) {
            var node = new GraphNode();
            node.position[0] = positionArr[i * 2];
            node.position[1] = positionArr[i * 2 + 1];
            node.mass = massArr[i];
            if (haveSize) {
                node.size = sizeArr[i];
            }
            this.nodes.push(node);
        }

        this._massArr = massArr;
        this._swingingArr = new Float32Array(nNodes);

        if (haveSize) {
            this._sizeArr = sizeArr;
        }
    };

    forceAtlas2Proto.initEdges = function(edgeArr, edgeWeightArr) {
        var nEdges = edgeArr.length / 2;
        this.edges.length = 0;
        for (var i = 0; i < nEdges; i++) {
            var sIdx = edgeArr[i * 2];
            var tIdx = edgeArr[i * 2 + 1];
            var sNode = this.nodes[sIdx];
            var tNode = this.nodes[tIdx];

            if (!sNode || !tNode) {
                console.error('Node not exists, try initNodes before initEdges');
                return;
            }
            sNode.outDegree++;
            tNode.inDegree++;
            var edge = new GraphEdge(sNode, tNode);

            if (edgeWeightArr) {
                edge.weight = edgeWeightArr[i];
            }

            this.edges.push(edge);
        }
    }

    forceAtlas2Proto.updateSettings = function() {
        if (this.repulsionByDegree) {
            for (var i = 0; i < this.nodes.length; i++) {
                var node = this.nodes[i];
                node.mass = node.inDegree + node.outDegree + 1;
            }
        }
        else {
            for (var i = 0; i < this.nodes.length; i++) {
                var node = this.nodes[i];
                node.mass = this._massArr[i];
            }
        }
    };

    forceAtlas2Proto.update = function() {
        var nNodes = this.nodes.length;

        this.updateSettings();

        this.updateBBox();

        // Update region
        if (this.barnesHutOptimize) {
            this.rootRegion.setBBox(
                this.bbox[0], this.bbox[1],
                this.bbox[2], this.bbox[3]
            );

            this.rootRegion.beforeUpdate();
            for (var i = 0; i < nNodes; i++) {
                this.rootRegion.addNode(this.nodes[i]);
            }
            this.rootRegion.afterUpdate();
        }

        // Reset forces
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            vec2.copy(node.forcePrev, node.force);
            vec2.set(node.force, 0, 0);
        }

        // Compute forces
        // Repulsion
        for (var i = 0; i < nNodes; i++) {
            var na = this.nodes[i];
            if (this.barnesHutOptimize) {
                this.applyRegionToNodeRepulsion(this.rootRegion, na);
            }
            else {
                for (var j = i + 1; j < nNodes; j++) {
                    var nb = this.nodes[j];
                    this.applyNodeToNodeRepulsion(na, nb, false);
                }
            }

            // Gravity
            if (this.gravity > 0) {
                if (this.strongGravityMode) {
                    this.applyNodeStrongGravity(na);
                }
                else {
                    this.applyNodeGravity(na);
                }
            }
        }

        // Attraction
        for (var i = 0; i < this.edges.length; i++) {
            this.applyEdgeAttraction(this.edges[i]);
        }

        // Handle swinging
        var swingWeightedSum = 0;
        var tractionWeightedSum = 0;
        var tmp = vec2.create();
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            var swing = vec2.dist(node.force, node.forcePrev);
            swingWeightedSum += swing * node.mass;

            vec2.add(tmp, node.force, node.forcePrev);
            var traction = vec2.len(tmp) * 0.5;
            tractionWeightedSum += traction * node.mass;

            // Save the value for using later
            this._swingingArr[i] = swing;
        }
        var globalSpeed = this.jitterTolerence * this.jitterTolerence
                        * tractionWeightedSum / swingWeightedSum;
        // NB: During our tests we observed that an excessive rise of the global speed could have a negative impact.
        // That’s why we limited the increase of global speed s(t)(G) to 50% of the previous step s(t−1)(G).
        if (this._globalSpeed > 0) {
            globalSpeed = Math.min(globalSpeed / this._globalSpeed, 1.5) * this._globalSpeed;
        }
        this._globalSpeed = globalSpeed;

        // Apply forces
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            var swing = this._swingingArr[i];

            var speed = 0.1 * globalSpeed / (1 + globalSpeed * Math.sqrt(swing));

            // Additional constraint to prevent local speed gets too high
            var df = vec2.len(node.force);
            if (df > 0) {
                speed = Math.min(df * speed, 10) / df;
                vec2.scaleAndAdd(node.position, node.position, node.force, speed);
            }
        }
    };

    forceAtlas2Proto.applyRegionToNodeRepulsion = (function() {
        var v = vec2.create();
        return function applyRegionToNodeRepulsion(region, node) {
            if (region.node) { // Region is a leaf
                this.applyNodeToNodeRepulsion(region.node, node, true);
            }
            else {
                vec2.sub(v, node.position, region.centerOfMass);
                var d2 = v[0] * v[0] + v[1] * v[1];
                if (d2 > this.barnesHutTheta * region.size * region.size) {
                    var factor = this.scaling * node.mass * region.mass / d2;
                    vec2.scaleAndAdd(node.force, node.force, v, factor);
                }
                else {
                    for (var i = 0; i < region.nSubRegions; i++) {
                        this.applyRegionToNodeRepulsion(region.subRegions[i], node);
                    }
                }
            }
        }
    })();

    forceAtlas2Proto.applyNodeToNodeRepulsion = (function() {
        var v = vec2.create();
        return function applyNodeToNodeRepulsion(na, nb, oneWay) {
            if (na == nb) {
                return;
            }
            vec2.sub(v, na.position, nb.position);
            var d2 = v[0] * v[0] + v[1] * v[1];

            // PENDING
            if (d2 === 0) {
                return;
            }

            var factor;
            if (this.preventOverlap) {
                var d = Math.sqrt(d2);
                d = d - na.size - nb.size;
                if (d > 0) {
                    factor = this.scaling * na.mass * nb.mass / (d * d);
                }
                else if (d < 0) {
                    // A stronger repulsion if overlap
                    factor = this.scaling * 100 * na.mass * nb.mass;
                }
                else {
                    // No repulsion
                    return;
                }
            }
            else {
                // Divide factor by an extra `d` to normalize the `v`
                factor = this.scaling * na.mass * nb.mass / d2;
            }

            vec2.scaleAndAdd(na.force, na.force, v, factor);
            vec2.scaleAndAdd(nb.force, nb.force, v, -factor);
        }
    })();

    forceAtlas2Proto.applyEdgeAttraction = (function() {
        var v = vec2.create();
        return function applyEdgeAttraction(edge) {
            var na = edge.source;
            var nb = edge.target;

            vec2.sub(v, na.position, nb.position);
            var d = vec2.len(v);

            var w;
            if (this.edgeWeightInfluence === 0) {
                w = 1;
            }
            else if (this.edgeWeightInfluence === 1) {
                w = edge.weight;
            }
            else {
                w = Math.pow(edge.weight, this.edgeWeightInfluence);
            }

            var factor;

            if (this.preventOverlap) {
                d = d - na.size - nb.size;
                if (d <= 0) {
                    // No attraction
                    return;
                }
            }

            if (this.linLogMode) {
                // Divide factor by an extra `d` to normalize the `v`
                factor = - w * Math.log(d + 1) / (d + 1);
            }
            else {
                factor = - w;
            }
            vec2.scaleAndAdd(na.force, na.force, v, factor);
            vec2.scaleAndAdd(nb.force, nb.force, v, -factor);
        }
    })();

    forceAtlas2Proto.applyNodeGravity = (function() {
        var v = vec2.create();
        return function(node) {
            vec2.sub(v, this.gravityCenter, node.position);
            var d = vec2.len(v);
            vec2.scaleAndAdd(node.force, node.force, v, this.gravity * node.mass / (d + 1));
        }
    })();

    forceAtlas2Proto.applyNodeStrongGravity = (function() {
        var v = vec2.create();
        return function(node) {
            vec2.sub(v, this.gravityCenter, node.position);
            vec2.scaleAndAdd(node.force, node.force, v, this.gravity * node.mass);
        }
    })();

    forceAtlas2Proto.updateBBox = function() {
        var minX = Infinity;
        var minY = Infinity;
        var maxX = -Infinity;
        var maxY = -Infinity;
        for (var i = 0; i < this.nodes.length; i++) {
            var pos = this.nodes[i].position;
            minX = Math.min(minX, pos[0]);
            minY = Math.min(minY, pos[1]);
            maxX = Math.max(maxX, pos[0]);
            maxY = Math.max(maxY, pos[1]);
        }
        this.bbox[0] = minX;
        this.bbox[1] = minY;
        this.bbox[2] = maxX;
        this.bbox[3] = maxY;
    };

    forceAtlas2Proto.getGlobalSpeed = function () {
        return this._globalSpeed;
    }

    /****************************
     * Main process
     ***************************/

    var forceAtlas2 = null;

    self.onmessage = function(e) {
        switch(e.data.cmd) {
            case 'init':
                forceAtlas2 = new ForceAtlas2();
                forceAtlas2.initNodes(e.data.nodesPosition, e.data.nodesMass, e.data.nodesSize);
                forceAtlas2.initEdges(e.data.edges, e.data.edgesWeight);
                break;
            case 'updateConfig':
                if (forceAtlas2) {
                    for (var name in e.data.config) {
                        forceAtlas2[name] = e.data.config[name];
                    }
                }
                break;
            case 'update':
                var steps = e.data.steps;
                if (forceAtlas2) {
                    for (var i = 0; i < steps; i++) {
                        forceAtlas2.update();
                    }

                    var nNodes = forceAtlas2.nodes.length;
                    var positionArr = new Float32Array(nNodes * 2);
                    // Callback
                    for (var i = 0; i < nNodes; i++) {
                        var node = forceAtlas2.nodes[i];
                        positionArr[i * 2] = node.position[0];
                        positionArr[i * 2 + 1] = node.position[1];
                    }
                    self.postMessage({
                        buffer: positionArr.buffer,
                        globalSpeed: forceAtlas2.getGlobalSpeed()
                    }, [positionArr.buffer]);
                }
                else {
                    // Not initialzied yet
                    var emptyArr = new Float32Array();
                    // Post transfer object
                    self.postMessage({
                        buffer: emptyArr.buffer,
                        globalSpeed: forceAtlas2.getGlobalSpeed()
                    }, [emptyArr.buffer]);
                }
                break;
        }
    }
}
967185
function _Vector3(x, y, z) {
  if(!x) x = 0;
  if(!y) y = 0;
  if(!z) z = 0;

  var values = [x, y, z];
  Vector.apply(this, [3, values]);

  readonly(this, "x", x);
  readonly(this, "y", y);
  readonly(this, "z", z);
  readonly(this, "homogeneous", _getHomogeneous(this));
  readonly(this, "vector4", _getVector4(this));
}
78751
function vectorParams (options, input) {
  if (!input && typeof options === 'string') {
    options = { input: options }
  }
  options = options || {}
  let params = Object.assign({}, defaultsVectorParams, options)
  params.input = input || params.input
  return params
}
929085
public static double[] normalizeL2(double[] vector) {
		// compute vector 2-norm
		double norm2 = 0;
		for (int i = 0; i < vector.length; i++) {
			norm2 += vector[i] * vector[i];
		}
		norm2 = (double) Math.sqrt(norm2);

		if (norm2 == 0) {
			Arrays.fill(vector, 1);
		} else {
			for (int i = 0; i < vector.length; i++) {
				vector[i] = vector[i] / norm2;
			}
		}
		return vector;
	}
396630
function ( vectorA, vectorB, vectorC ) {

		var s, a, b, c,
			tmp = THREE.GeometryUtils.__v1;

		tmp.sub( vectorA, vectorB );
		a = tmp.length();

		tmp.sub( vectorA, vectorC );
		b = tmp.length();

		tmp.sub( vectorB, vectorC );
		c = tmp.length();

		s = 0.5 * ( a + b + c );

		return Math.sqrt( s * ( s - a ) * ( s - b ) * ( s - c ) );

	}
967536
function (x, y, v) {
            var tileX = Math.floor(x),
                tileY = Math.floor(y);
            var ret = v || new me.Vector2d();

            if (this.staggerX) {
                ret.y = tileY * (this.tileheight + this.sidelengthy);
                if (this.doStaggerX(tileX)) {
                    ret.y += this.rowheight;
                }
                ret.x = tileX * this.columnwidth;
            } else {
                ret.x = tileX * (this.tilewidth + this.sidelengthx);
                if (this.doStaggerY(tileY)) {
                    ret.x += this.columnwidth;
                }
                ret.y = tileY * this.rowheight;
            }

            return ret;
        }
627811
function(v) {
            var v0 = v.x;
            var v1 = v.y;
            var v2 = 0;
            var v3 = 1;
            var x = v0 * this.elements[0] + v1 * this.elements[1] + v2 * this.elements[2] + v3 * this.elements[3];
            var y = v0 * this.elements[4] + v1 * this.elements[5] + v2 * this.elements[6] + v3 * this.elements[7];
            var z = v0 * this.elements[8] + v1 * this.elements[9] + v2 * this.elements[10] + v3 * this.elements[11];
            var w = v0 * this.elements[12] + v1 * this.elements[13] + v2 * this.elements[14] + v3 * this.elements[15];
            // scale such that fourth element becomes 1:
            if (w != 1) {
                var invw = 1.0 / w;
                x *= invw;
                y *= invw;
                z *= invw;
            }
            return new CSG.Vector2D(x, y);
        }
617916
def vectorize(fn):
    

    @functools.wraps(fn)
    def vectorized_function(values, *vargs, **kwargs):
        return [fn(value, *vargs, **kwargs) for value in values]

    return vectorized_function
423757
function vector_char(x,y,c) {
   c = c.charCodeAt(0);
   c -= 32;
   if(c<0||c>=95) return { width: 0, segments: [] };

   var off = c*112;
   var n = simplexFont[off++];
   var w = simplexFont[off++];
   var l = [];
   var segs = [];
   
   for(var i=0; i<n; i++) {
      var xp = simplexFont[off+i*2];
      var yp = simplexFont[off+i*2+1];
      if(xp==-1&&yp==-1) {
         segs.push(l); l = [];
      } else {
         l.push([xp+x,yp+y]);
      }
   }                
   if(l.length) segs.push(l);
   return { width: w, segments: segs };
}
128684
function(fn) {
            	var elements = [];
            	this.each(function(x, i) {
            	    elements.push(fn(x, i));
            	});
            	return Vector.create(elements);
                }
42139
function(x0, y0, r1, r2, angle, largeArcFlag, sweepFlag, x, y)
	{
		x -= x0;
		y -= y0;
		
        if (r1 === 0 || r2 === 0) 
        {
        	return result;
        }
        
        var fS = sweepFlag;
        var psai = angle;
        r1 = Math.abs(r1);
        r2 = Math.abs(r2);
        var ctx = -x / 2;
        var cty = -y / 2;
        var cpsi = Math.cos(psai * Math.PI / 180);
        var spsi = Math.sin(psai * Math.PI / 180);
        var rxd = cpsi * ctx + spsi * cty;
        var ryd = -1 * spsi * ctx + cpsi * cty;
        var rxdd = rxd * rxd;
        var rydd = ryd * ryd;
        var r1x = r1 * r1;
        var r2y = r2 * r2;
        var lamda = rxdd / r1x + rydd / r2y;
        var sds;
        
        if (lamda > 1) 
        {
        	r1 = Math.sqrt(lamda) * r1;
        	r2 = Math.sqrt(lamda) * r2;
        	sds = 0;
        }  
        else
        {
        	var seif = 1;
            
        	if (largeArcFlag === fS) 
        	{
        		seif = -1;
        	}
            
        	sds = seif * Math.sqrt((r1x * r2y - r1x * rydd - r2y * rxdd) / (r1x * rydd + r2y * rxdd));
        }
        
        var txd = sds * r1 * ryd / r2;
        var tyd = -1 * sds * r2 * rxd / r1;
        var tx = cpsi * txd - spsi * tyd + x / 2;
        var ty = spsi * txd + cpsi * tyd + y / 2;
        var rad = Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1) - Math.atan2(0, 1);
        var s1 = (rad >= 0) ? rad : 2 * Math.PI + rad;
        rad = Math.atan2((-ryd - tyd) / r2, (-rxd - txd) / r1) - Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1);
        var dr = (rad >= 0) ? rad : 2 * Math.PI + rad;
        
        if (fS == 0 && dr > 0) 
        {
        	dr -= 2 * Math.PI;
        }
        else if (fS != 0 && dr < 0) 
        {
        	dr += 2 * Math.PI;
        }
        
        var sse = dr * 2 / Math.PI;
        var seg = Math.ceil(sse < 0 ? -1 * sse : sse);
        var segr = dr / seg;
        var t = 8/3 * Math.sin(segr / 4) * Math.sin(segr / 4) / Math.sin(segr / 2);
        var cpsir1 = cpsi * r1;
        var cpsir2 = cpsi * r2;
        var spsir1 = spsi * r1;
        var spsir2 = spsi * r2;
        var mc = Math.cos(s1);
        var ms = Math.sin(s1);
        var x2 = -t * (cpsir1 * ms + spsir2 * mc);
        var y2 = -t * (spsir1 * ms - cpsir2 * mc);
        var x3 = 0;
        var y3 = 0;

		var result = [];
        
        for (var n = 0; n < seg; ++n) 
        {
            s1 += segr;
            mc = Math.cos(s1);
            ms = Math.sin(s1);
            
            x3 = cpsir1 * mc - spsir2 * ms + tx;
            y3 = spsir1 * mc + cpsir2 * ms + ty;
            var dx = -t * (cpsir1 * ms + spsir2 * mc);
            var dy = -t * (spsir1 * ms - cpsir2 * mc);
            
            // CurveTo updates x0, y0 so need to restore it
            var index = n * 6;
            result[index] = Number(x2 + x0);
            result[index + 1] = Number(y2 + y0);
            result[index + 2] = Number(x3 - dx + x0);
            result[index + 3] = Number(y3 - dy + y0);
            result[index + 4] = Number(x3 + x0);
            result[index + 5] = Number(y3 + y0);
            
			x2 = x3 + dx;
            y2 = y3 + dy;
        }
        
        return result;
	}
1160956
function(a,b,d){
	var o, dir;
	if(arguments.length == 3){
		Vec2D.apply(this,[a,b]);
		this.dir = d.getNormalized();
	} else if(arguments.length == 2){
		Vec2D.apply(this,[a]);
		this.dir = b.getNormalized();
	} else if(arguments.length === 0){
		Vec2D.apply(this);
		this.dir = Vec2D.Y_AXIS.copy();
	}
}
873190
function(vector) {
            	var B = vector.elements || vector;
            	if (this.elements.length != 3 || B.length != 3) { return null; }
            	var A = this.elements;
            	return Vector.create([
            	    (A[1] * B[2]) - (A[2] * B[1]),
            	    (A[2] * B[0]) - (A[0] * B[2]),
            	    (A[0] * B[1]) - (A[1] * B[0])
            	]);
                }
637390
function(v) {
            var v0 = v._x;
            var v1 = v._y;
            var v2 = v._z;
            var v3 = 1;
            var x = v0 * this.elements[0] + v1 * this.elements[1] + v2 * this.elements[2] + v3 * this.elements[3];
            var y = v0 * this.elements[4] + v1 * this.elements[5] + v2 * this.elements[6] + v3 * this.elements[7];
            var z = v0 * this.elements[8] + v1 * this.elements[9] + v2 * this.elements[10] + v3 * this.elements[11];
            var w = v0 * this.elements[12] + v1 * this.elements[13] + v2 * this.elements[14] + v3 * this.elements[15];
            // scale such that fourth element becomes 1:
            if (w != 1) {
                var invw = 1.0 / w;
                x *= invw;
                y *= invw;
                z *= invw;
            }
            return new CSG.Vector3D(x, y, z);
        }
327430
public static function dot(Vector $vector1, Vector $vector2) : float {
        $count = count($vector1);
        $value = 0;
        for ($i=0;$i<$count;$i++) {
            $value += ($vector1[$i] * $vector2[$i]);
        }
        return $value;
    }
1352829
private HashSet<Integer> vector2set(int y[]) {
        HashSet<Integer> Y = new HashSet<Integer>();
        for (int j = 0; j < y.length; j++) {
            if (y[j] > 0) {
                Y.add(j);
            }
        }
        return Y;
    }
265996
public Vector2f mul(float x, float y, Vector2f dest) {
        dest.x = this.x * x;
        dest.y = this.y * y;
        return dest;
    }