<commit_before>/**
 * @author mr.doob / http://mrdoob.com/
 */

THREE.Ray = function ( origin, direction, range ) {

	this.origin = origin || new THREE.Vector3();
	this.direction = direction || new THREE.Vector3();
	this.range = range || -1;

	var precision = 0.0001;

	this.setPrecision = function ( value ) {

		precision = value;

	};

	var a = new THREE.Vector3();
	var b = new THREE.Vector3();
	var c = new THREE.Vector3();
	var d = new THREE.Vector3();

	var originCopy = new THREE.Vector3();
	var directionCopy = new THREE.Vector3();

	var vector = new THREE.Vector3();
	var normal = new THREE.Vector3();
	var intersectPoint = new THREE.Vector3()

	var descSort = function ( a, b ) {

			return a.distance - b.distance;

	};

	this.intersectObject = function ( object ) {

		var intersect, intersects = [];

		if ( object instanceof THREE.Particle ) {

			var distance;

			// Checking range, note that distance may be actually greater then this.range,
			// because we also consider object.scale.x

			if ( this.range >= 0 ) {
				distance = vector.sub( this.origin, object.matrixWorld.getPosition() ).length();
				if ( distance > object.scale.x + this.range ) return [];
			}

			distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );

			if ( distance > object.scale.x ) {

				return [];

			}

			intersect = {

				distance: distance,
				point: object.position,
				face: null,
				object: object

			};

			intersects.push( intersect );

		} else if ( object instanceof THREE.Mesh ) {

			// Checking boundingSphere
			var scale = THREE.Frustum.__v1.set( object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length() );
			var scaledRadius = object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) );
			var distance;

			// Checking distance to origin
			if (this.range >= 0) {

				distance = vector.sub( object.matrixWorld.getPosition(), this.origin ).length();
				if ( distance > scaledRadius + this.range ) return intersects;

			}

			// Checking distance to ray

			distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );

			if ( distance > scaledRadius) {

				return intersects;

			}

			// Checking faces

			var f, fl, face, dot, scalar,
			rangeSq = this.range*this.range,
			geometry = object.geometry,
			vertices = geometry.vertices,
			objMatrix;

			object.matrixRotationWorld.extractRotation( object.matrixWorld );

			for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {

				face = geometry.faces[ f ];

				originCopy.copy( this.origin );
				directionCopy.copy( this.direction );

				objMatrix = object.matrixWorld;

				// determine if ray intersects the plane of the face
				// note: this works regardless of the direction of the face normal

				vector = objMatrix.multiplyVector3( vector.copy( face.centroid ) ).subSelf( originCopy );
				normal = object.matrixRotationWorld.multiplyVector3( normal.copy( face.normal ) );
				dot = directionCopy.dot( normal );

				// bail if ray and plane are parallel

				if ( Math.abs( dot ) < precision ) continue;

				// calc distance to plane

				scalar = normal.dot( vector ) / dot;

				// if negative distance, then plane is behind ray

				if ( scalar < 0 ) continue;

				if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) {

					intersectPoint.add( originCopy, directionCopy.multiplyScalar( scalar ) );

					// Check for range
					if ( ( this.range >= 0 ) && ( vector.sub( this.origin, intersectPoint ).lengthSq() > rangeSq ) ) continue;

					if ( face instanceof THREE.Face3 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );

						if ( pointInFace3( intersectPoint, a, b, c ) ) {

							intersect = {

								distance: originCopy.distanceTo( intersectPoint ),
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					} else if ( face instanceof THREE.Face4 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );
						d = objMatrix.multiplyVector3( d.copy( vertices[ face.d ] ) );

						if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {

							intersect = {

								distance: originCopy.distanceTo( intersectPoint ),
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					}

				}

			}

		}

		intersects.sort( descSort );

		return intersects;

	}

	this.intersectObjects = function ( objects ) {

		var intersects = [];

		for ( var i = 0, l = objects.length; i < l; i ++ ) {

			Array.prototype.push.apply( intersects, this.intersectObject( objects[ i ] ) );

		}

		intersects.sort( descSort );

		return intersects;

	};

	var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
	var dot, intersect, distance;

	function distanceFromIntersection( origin, direction, position ) {

		v0.sub( position, origin );
		dot = v0.dot( direction );

		intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
		distance = position.distanceTo( intersect );

		return distance;

	}

	// http://www.blackpawn.com/texts/pointinpoly/default.html

	var dot00, dot01, dot02, dot11, dot12, invDenom, u, v;

	function pointInFace3( p, a, b, c ) {

		v0.sub( c, a );
		v1.sub( b, a );
		v2.sub( p, a );

		dot00 = v0.dot( v0 );
		dot01 = v0.dot( v1 );
		dot02 = v0.dot( v2 );
		dot11 = v1.dot( v1 );
		dot12 = v1.dot( v2 );

		invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
		u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
		v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;

		return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );

	}

};
<commit_msg>implemented near/far<commit_after>/**
 * @author mr.doob / http://mrdoob.com/
 */

THREE.Ray = function ( origin, direction, near, far ) {

	this.origin = origin || new THREE.Vector3();
	this.direction = direction || new THREE.Vector3();
	this.near = near || 0;
	this.far = far || Infinity;

	var precision = 0.0001;

	this.setPrecision = function ( value ) {

		precision = value;

	};

	var a = new THREE.Vector3();
	var b = new THREE.Vector3();
	var c = new THREE.Vector3();
	var d = new THREE.Vector3();

	var originCopy = new THREE.Vector3();
	var directionCopy = new THREE.Vector3();

	var vector = new THREE.Vector3();
	var normal = new THREE.Vector3();
	var intersectPoint = new THREE.Vector3()

	var descSort = function ( a, b ) {

			return a.distance - b.distance;

	};

	this.intersectObject = function ( object ) {

		var intersect, intersects = [];

		if ( object instanceof THREE.Particle ) {

			var distance;

			// Checking range, note that distance may be actually greater then this.range,
			// because we also consider object.scale.x

			if ( this.far < Infinity || this.near > 0 ) {
				distance = vector.sub(this.origin, object.matrixWorld.getPosition()).length();
				if ( distance > object.scale.x + this.far ) return [];
				if ( distance < -object.scale.x + this.near ) return [];
			}

			distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );

			if ( distance > object.scale.x ) {

				return [];

			}

			intersect = {

				distance: distance,
				point: object.position,
				face: null,
				object: object

			};

			intersects.push( intersect );

		} else if ( object instanceof THREE.Mesh ) {

			// Checking boundingSphere
			var scale = THREE.Frustum.__v1.set( object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length() );
			var scaledRadius = object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) );
			var distance;

			// Checking distance to origin
			if ( this.far < Infinity || this.near > 0 ) {

				distance = vector.sub( object.matrixWorld.getPosition(), this.origin ).length();
				if ( distance > scaledRadius + this.far ) return intersects;
				if ( distance < -scaledRadius + this.near ) return intersects;

			}

			// Checking distance to ray

			distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );

			if ( distance > scaledRadius) {

				return intersects;

			}

			// Checking faces

			var f, fl, face, dot, scalar,
			rangeSq = this.range*this.range,
			geometry = object.geometry,
			vertices = geometry.vertices,
			objMatrix;

			object.matrixRotationWorld.extractRotation( object.matrixWorld );

			for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {

				face = geometry.faces[ f ];

				originCopy.copy( this.origin );
				directionCopy.copy( this.direction );

				objMatrix = object.matrixWorld;

				// determine if ray intersects the plane of the face
				// note: this works regardless of the direction of the face normal

				vector = objMatrix.multiplyVector3( vector.copy( face.centroid ) ).subSelf( originCopy );
				normal = object.matrixRotationWorld.multiplyVector3( normal.copy( face.normal ) );
				dot = directionCopy.dot( normal );

				// bail if ray and plane are parallel

				if ( Math.abs( dot ) < precision ) continue;

				// calc distance to plane

				scalar = normal.dot( vector ) / dot;

				// if negative distance, then plane is behind ray

				if ( scalar < 0 ) continue;

				if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) {

					intersectPoint.add( originCopy, directionCopy.multiplyScalar( scalar ) );

					// Checking distance to origin (would be calculated anyway)
					distance = originCopy.distanceTo( intersectPoint );
					if ( distance > this.far ) continue;
					if ( distance < this.near ) continue;

					if ( face instanceof THREE.Face3 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );

						if ( pointInFace3( intersectPoint, a, b, c ) ) {

							intersect = {

								distance: distance,
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					} else if ( face instanceof THREE.Face4 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );
						d = objMatrix.multiplyVector3( d.copy( vertices[ face.d ] ) );

						if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {

							intersect = {

								distance: distance,
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					}

				}

			}

		}

		intersects.sort( descSort );

		return intersects;

	}

	this.intersectObjects = function ( objects ) {

		var intersects = [];

		for ( var i = 0, l = objects.length; i < l; i ++ ) {

			Array.prototype.push.apply( intersects, this.intersectObject( objects[ i ] ) );

		}

		intersects.sort( descSort );

		return intersects;

	};

	var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
	var dot, intersect, distance;

	function distanceFromIntersection( origin, direction, position ) {

		v0.sub( position, origin );
		dot = v0.dot( direction );

		intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
		distance = position.distanceTo( intersect );

		return distance;

	}

	// http://www.blackpawn.com/texts/pointinpoly/default.html

	var dot00, dot01, dot02, dot11, dot12, invDenom, u, v;

	function pointInFace3( p, a, b, c ) {

		v0.sub( c, a );
		v1.sub( b, a );
		v2.sub( p, a );

		dot00 = v0.dot( v0 );
		dot01 = v0.dot( v1 );
		dot02 = v0.dot( v2 );
		dot11 = v1.dot( v1 );
		dot12 = v1.dot( v2 );

		invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
		u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
		v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;

		return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );

	}

};
<|endoftext|>


<commit_before>/**
 * @author mr.doob / http://mrdoob.com/
 */

THREE.Ray = function ( origin, direction ) {

	this.origin = origin || new THREE.Vector3();
	this.direction = direction || new THREE.Vector3();

	this.intersectScene = function ( scene ) {

		return this.intersectObjects( scene.children );

	};

	this.intersectObjects = function ( objects ) {

		var i, l, object,
		intersects = [];

		for ( i = 0, l = objects.length; i < l; i ++ ) {

			Array.prototype.push.apply( intersects, this.intersectObject( objects[ i ] ) );

		}

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

		return intersects;

	};

	var a = new THREE.Vector3();
	var b = new THREE.Vector3();
	var c = new THREE.Vector3();
	var d = new THREE.Vector3();

	var originCopy = new THREE.Vector3();
	var directionCopy = new THREE.Vector3();

	var vector = new THREE.Vector3();
	var normal = new THREE.Vector3();
	var intersectPoint = new THREE.Vector3()

	this.intersectObject = function ( object ) {

		var intersect, intersects = [];

		for ( var i = 0, l = object.children.length; i < l; i ++ ) {

			Array.prototype.push.apply( intersects, this.intersectObject( object.children[ i ] ) );

		}

		if ( object instanceof THREE.Particle ) {

			var distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );

			if ( distance > object.scale.x ) {

				return [];

			}

			intersect = {

				distance: distance,
				point: object.position,
				face: null,
				object: object

			};

			intersects.push( intersect );

		} else if ( object instanceof THREE.Mesh ) {

			// Checking boundingSphere

			var distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
			var scale = THREE.Frustum.__v1.set( object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length() );

			if ( distance > object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) ) ) {

				return intersects;

			}

			// Checking faces

			var f, fl, face, dot, scalar,
			geometry = object.geometry,
			vertices = geometry.vertices,
			objMatrix;

			object.matrixRotationWorld.extractRotation( object.matrixWorld );

			for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {

				face = geometry.faces[ f ];

				originCopy.copy( this.origin );
				directionCopy.copy( this.direction );

				objMatrix = object.matrixWorld;

				// determine if ray intersects the plane of the face
				// note: this works regardless of the direction of the face normal

				vector = objMatrix.multiplyVector3( vector.copy( face.centroid ) ).subSelf( originCopy );
				normal = object.matrixRotationWorld.multiplyVector3( normal.copy( face.normal ) );
				dot = directionCopy.dot( normal );

				// bail if ray and plane are parallel

				if ( Math.abs( dot ) < 0.0001 ) continue;

				// calc distance to plane

				scalar = normal.dot( vector ) / dot;

				// if negative distance, then plane is behind ray

				if ( scalar < 0 ) continue;

				if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) {

					intersectPoint.add( originCopy, directionCopy.multiplyScalar( scalar ) );

					if ( face instanceof THREE.Face3 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ].position ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ].position ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ].position ) );

						if ( pointInFace3( intersectPoint, a, b, c ) ) {

							intersect = {

								distance: originCopy.distanceTo( intersectPoint ),
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					} else if ( face instanceof THREE.Face4 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ].position ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ].position ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ].position ) );
						d = objMatrix.multiplyVector3( d.copy( vertices[ face.d ].position ) );

						if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {

							intersect = {

								distance: originCopy.distanceTo( intersectPoint ),
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					}

				}

			}

		}

		return intersects;

	}

	var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
	var dot, intersect, distance;

	function distanceFromIntersection( origin, direction, position ) {

		v0.sub( position, origin );
		dot = v0.dot( direction );

		intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
		distance = position.distanceTo( intersect );

		return distance;

	}

	// http://www.blackpawn.com/texts/pointinpoly/default.html

	var dot00, dot01, dot02, dot11, dot12, invDenom, u, v;

	function pointInFace3( p, a, b, c ) {

		v0.sub( c, a );
		v1.sub( b, a );
		v2.sub( p, a );

		dot00 = v0.dot( v0 );
		dot01 = v0.dot( v1 );
		dot02 = v0.dot( v2 );
		dot11 = v1.dot( v1 );
		dot12 = v1.dot( v2 );

		invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
		u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
		v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;

		return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );

	}

};
<commit_msg>Removed hierarchy support in Ray. Removed .intersectScene() to avoid disappointment.<commit_after>/**
 * @author mr.doob / http://mrdoob.com/
 */

THREE.Ray = function ( origin, direction ) {

	this.origin = origin || new THREE.Vector3();
	this.direction = direction || new THREE.Vector3();

	this.intersectObjects = function ( objects ) {

		var i, l, object,
		intersects = [];

		for ( i = 0, l = objects.length; i < l; i ++ ) {

			Array.prototype.push.apply( intersects, this.intersectObject( objects[ i ] ) );

		}

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

		return intersects;

	};

	var a = new THREE.Vector3();
	var b = new THREE.Vector3();
	var c = new THREE.Vector3();
	var d = new THREE.Vector3();

	var originCopy = new THREE.Vector3();
	var directionCopy = new THREE.Vector3();

	var vector = new THREE.Vector3();
	var normal = new THREE.Vector3();
	var intersectPoint = new THREE.Vector3()

	this.intersectObject = function ( object ) {

		var intersect, intersects = [];

		if ( object instanceof THREE.Particle ) {

			var distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );

			if ( distance > object.scale.x ) {

				return [];

			}

			intersect = {

				distance: distance,
				point: object.position,
				face: null,
				object: object

			};

			intersects.push( intersect );

		} else if ( object instanceof THREE.Mesh ) {

			// Checking boundingSphere

			var distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
			var scale = THREE.Frustum.__v1.set( object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length() );

			if ( distance > object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) ) ) {

				return intersects;

			}

			// Checking faces

			var f, fl, face, dot, scalar,
			geometry = object.geometry,
			vertices = geometry.vertices,
			objMatrix;

			object.matrixRotationWorld.extractRotation( object.matrixWorld );

			for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {

				face = geometry.faces[ f ];

				originCopy.copy( this.origin );
				directionCopy.copy( this.direction );

				objMatrix = object.matrixWorld;

				// determine if ray intersects the plane of the face
				// note: this works regardless of the direction of the face normal

				vector = objMatrix.multiplyVector3( vector.copy( face.centroid ) ).subSelf( originCopy );
				normal = object.matrixRotationWorld.multiplyVector3( normal.copy( face.normal ) );
				dot = directionCopy.dot( normal );

				// bail if ray and plane are parallel

				if ( Math.abs( dot ) < 0.0001 ) continue;

				// calc distance to plane

				scalar = normal.dot( vector ) / dot;

				// if negative distance, then plane is behind ray

				if ( scalar < 0 ) continue;

				if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) {

					intersectPoint.add( originCopy, directionCopy.multiplyScalar( scalar ) );

					if ( face instanceof THREE.Face3 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ].position ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ].position ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ].position ) );

						if ( pointInFace3( intersectPoint, a, b, c ) ) {

							intersect = {

								distance: originCopy.distanceTo( intersectPoint ),
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					} else if ( face instanceof THREE.Face4 ) {

						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ].position ) );
						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ].position ) );
						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ].position ) );
						d = objMatrix.multiplyVector3( d.copy( vertices[ face.d ].position ) );

						if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {

							intersect = {

								distance: originCopy.distanceTo( intersectPoint ),
								point: intersectPoint.clone(),
								face: face,
								object: object

							};

							intersects.push( intersect );

						}

					}

				}

			}

		}

		return intersects;

	}

	var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
	var dot, intersect, distance;

	function distanceFromIntersection( origin, direction, position ) {

		v0.sub( position, origin );
		dot = v0.dot( direction );

		intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
		distance = position.distanceTo( intersect );

		return distance;

	}

	// http://www.blackpawn.com/texts/pointinpoly/default.html

	var dot00, dot01, dot02, dot11, dot12, invDenom, u, v;

	function pointInFace3( p, a, b, c ) {

		v0.sub( c, a );
		v1.sub( b, a );
		v2.sub( p, a );

		dot00 = v0.dot( v0 );
		dot01 = v0.dot( v1 );
		dot02 = v0.dot( v2 );
		dot11 = v1.dot( v1 );
		dot12 = v1.dot( v2 );

		invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
		u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
		v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;

		return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );

	}

};
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const nodemailer = require('nodemailer');
const mg = require('nodemailer-mailgun-transport');
const config = require('./config');
const log = require('./log').log;

/**
 * Send an e-mail representing an error message.
 * @param {string} level The level, as a string
 * @param {string} message The string to e-mail
 */
function logMailer(level, message) {

	let mailOptions = {
		from: config.mailer.from,
		to: config.mailer.to,
		subject: `[OED ${config.mailer.org}] Open Energy Dashboard ${level}`,
		text: message
	};

	let transporter;
	if (config.mailer.method === 'none') {
		return;
	} else if (config.mailer.method === 'mailgun') {
		transporter = nodemailer.createTransport(mg({
			auth: {
				api_key: config.mailer.credential,
				domain: config.mailer.ident
			}
		}));
	} else if (config.mailer.method === 'gmail') {
		transporter = nodemailer.createTransport({
			service: 'gmail',
			auth: {
				user: config.mailer.ident,
				pass: config.mailer.credential
			}
		});
	} else {
		// tslint:disable-next-line no-console
		console.error(`Unable to send e-mail due to unknown mailer method ${config.mailer.method}`, skipMail = true);
		return;
	}

	transporter.sendMail(mailOptions, (err, info) => {
		if (err) {
			// tslint:disable-next-line no-console
			console.error(`\t[EMAIL NOT SENT]: ${err.message}`);
		} else {
			// tslint:disable-next-line no-console
			console.log(`\t[EMAIL SENT]: ${info.response}`);
		}
	});
}

module.exports = logMailer;
<commit_msg>Used log instead of console)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const nodemailer = require('nodemailer');
const mg = require('nodemailer-mailgun-transport');
const config = require('./config');
const { log } = require('./log');

/**
 * Send an e-mail representing an error message.
 * @param {string} level The level, as a string
 * @param {string} message The string to e-mail
 */
function logMailer(level, message) {

	let mailOptions = {
		from: config.mailer.from,
		to: config.mailer.to,
		subject: `[OED ${config.mailer.org}] Open Energy Dashboard ${level}`,
		text: message
	};

	let transporter;
	if (config.mailer.method === 'none') {
		return;
	} else if (config.mailer.method === 'mailgun') {
		transporter = nodemailer.createTransport(mg({
			auth: {
				api_key: config.mailer.credential,
				domain: config.mailer.ident
			}
		}));
	} else if (config.mailer.method === 'gmail') {
		transporter = nodemailer.createTransport({
			service: 'gmail',
			auth: {
				user: config.mailer.ident,
				pass: config.mailer.credential
			}
		});
	} else {
		// tslint:disable-next-line no-console
		log.error(`Unable to send e-mail due to unknown mailer method ${config.mailer.method}`, true);
		return;
	}

	transporter.sendMail(mailOptions, (err, info) => {
		if (err) {
			// tslint:disable-next-line no-console
			console.error(`\t[EMAIL NOT SENT]: ${err.message}`);
		} else {
			// tslint:disable-next-line no-console
			console.log(`\t[EMAIL SENT]: ${info.response}`);
		}
	});
}

module.exports = logMailer;
<|endoftext|>


<commit_before>const express = require("express");
const compression = require("compression");
const debug = require("debug")("app:http");

const A_LONG_TIME = 1 /* year */ * 365 * 24 * 60 * 60;

const app = express();

app.use(compression());

app.use((req, res, next) => {
  if (req.query.v) {
    res.append("Cache-Control", `max-age=${A_LONG_TIME}`);
  }
  if (req.path == "/scripts/service-worker.js")
    res.append("Service-Worker-Allowed", "/");
  next();
});

app.use(express.static(`${__dirname}/../../dist/browser`));

const httpPort = process.env.PORT || 80;
app.listen(httpPort);
debug(`Listening on http://localhost:${httpPort}`);
<commit_msg>Ensure the service worker is never cached<commit_after>const express = require("express");
const compression = require("compression");
const debug = require("debug")("app:http");

const A_LONG_TIME = 1 /* year */ * 365 * 24 * 60 * 60;

const app = express();

app.use(compression());

app.use((req, res, next) => {
  if (req.query.v) {
    res.append("Cache-Control", `max-age=${A_LONG_TIME}`);
  }
  if (req.path == "/scripts/service-worker.js") {
    res.append("Service-Worker-Allowed", "/");
    res.append("Cache-Control", "max-age=0"); // See https://developers.google.com/web/updates/2018/06/fresher-sw
  }
  next();
});

app.use(express.static(`${__dirname}/../../dist/browser`));

const httpPort = process.env.PORT || 80;
app.listen(httpPort);
debug(`Listening on http://localhost:${httpPort}`);
<|endoftext|>


<commit_before>/**
 * @author    Labs64 <netlicensing@labs64.com>
 * @license   Apache-2.0
 * @link      http://netlicensing.io
 * @copyright 2017 Labs64 NetLicensing
 */

//namespace
var NetLicensing  = NetLicensing  || {};

NetLicensing.Service = (function () {
    var instance;

    function createInstance() {
        var instance = {};

        var __httpXHR = {};

        instance.getLastHttpRequestInfo = function () {
            return Object.assign({}, __httpXHR)
        };
        /**
         * Helper method for performing GET request to NetLicensing API services. Finds and returns first suitable item with
         * type resultType from the response.
         *
         * Context for the NetLicensing API call
         * @param context
         *
         * the REST URL template
         * @param urlTemplate
         *
         * The REST query parameters values. May be null if there are no parameters.
         * @param queryParams
         *
         * the type of the result
         * @param resultType
         *
         * @returns {Promise}
         */
        instance.get = function (context, urlTemplate, queryParams, resultType) {
            return this.request(context, 'get', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    return (!instance.__has(httpXHR.response, 'items.item.0'))
                        ? null
                        : instance.__getEntity(resultType, instance.__get(httpXHR.response, 'items.item.0'));
                });
        };

        /**
         * Helper method for performing GET request to NetLicensing API service that returns page of items with type
         * resultType.
         *
         * context for the NetLicensing API call
         * @param context
         *
         * the REST URL template
         * @param urlTemplate
         *
         * The REST query parameters values. May be null if there are no parameters.
         * @param queryParams
         *
         * the type of the result
         * @param resultType
         *
         *
         * @returns {Promise}
         */
        instance.list = function (context, urlTemplate, queryParams, resultType) {
            return this.request(context, 'get', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    var entities = [],
                        items = instance.__has(httpXHR.response, 'items.item')
                            ? instance.__get(httpXHR.response, 'items.item')
                            : [],
                        length = items.length;

                    for (var i = 0; i < length; i++) {
                        entities.push(instance.__getEntity(resultType, items[i]));
                    }

                    return entities;
                });
        };

        /**
         * Helper method for performing POST request to NetLicensing API services. Finds and returns first suitable item
         * with type resultType from the response.
         *
         * context for the NetLicensing API call
         * @param context
         *
         * the REST URL template
         * @param urlTemplate
         *
         * The REST query parameters values. May be null if there are no parameters.
         * @param queryParams
         *
         * he type of the result
         * @param resultType
         *
         * @returns {Promise}
         */
        instance.post = function (context, urlTemplate, queryParams, resultType) {
            return this.request(context, 'post', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    return (!instance.__has(httpXHR.response, 'items.item.0'))
                        ? null
                        : instance.__getEntity(resultType, instance.__get(httpXHR.response, 'items.item.0'));
                });
        };

        /**
         *
         * @param context
         * @param urlTemplate
         * @param queryParams
         * @returns {Promise}
         */
        instance.delete = function (context, urlTemplate, queryParams) {
            return this.request(context, 'delete', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    return (httpXHR.status == 204);
                });
        };

        /**
         * Send request to NetLicensing  RestApi
         * @param context
         * @param method
         * @param urlTemplate
         * @param queryParams
         */
        instance.request = function (context, method, urlTemplate, queryParams) {

            if (!(context instanceof NetLicensing.Context)) throw new TypeError('context must be an instance of NetLicensing.Context');

            urlTemplate = String(urlTemplate);
            queryParams = queryParams || {};

            if (!urlTemplate) throw new TypeError('Url template must be specified');

            //validate http method
            this.__validateMethod(method);

            //validate context
            this.__validateBaseUrl(context);

            var restUrl = context.getBaseUrl() + '/' + urlTemplate;

            restUrl = restUrl.replace(/([^:]\/)\/+/g, "$1");

            //validate baseUrl +  urlTemplate
            this.__validateRestUrl(restUrl);

            //configure
            var headers = {Accept: 'application/json'};

            switch (context.getSecurityMode()) {
                case NetLicensing.Context.BASIC_AUTHENTICATION:
                    if (!context.getUsername()) throw new Error('Missing parameter "username"');
                    if (!context.getPassword()) throw new Error('Missing parameter "password"');

                    headers['Authorization'] = 'Basic ' + btoa(context.getUsername() + ':' + context.getPassword());
                    break;
                case NetLicensing.Context.APIKEY_IDENTIFICATION:
                    if (!context.getApiKey()) throw new Error('Missing parameter "apiKey"');

                    headers['Authorization'] = 'Basic ' + btoa('apiKey:' + context.getApiKey());
                    break;
                default:
                    throw new Error('Unknown security mode');
                    break;
            }

            return new NetLicensing.HttpRequest().send({
                url: restUrl,
                method: method,
                headers: headers,
                data: queryParams,
            }).then(function (httpXHR) {
                return __httpXHR = httpXHR;
            }).catch(function (httpXHR) {
                __httpXHR = httpXHR;
                var reasonPhrase = httpXHR.response.infos.info[0].value || 'Unknown';
                throw new Error('Unsupported response status code ' + httpXHR.status + ': ' + reasonPhrase);
            });
        };

        /**
         * Validate http method
         * @param method
         * @private
         */
        instance.__validateMethod = function (method) {
            if (['get', 'post', 'delete'].indexOf(method.toLowerCase()) < 0) {
                throw new Error('Invalid request type:' + method + ', allowed requests types: GET, POST, DELETE.');
            }
        };

        instance.__isValidUrl = function (url) {
            var pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
                '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name
                '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
                '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
                '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
                '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator

            return pattern.test(url);
        };

        instance.__validateBaseUrl = function (context) {
            if (!context.getBaseUrl(null)) {
                throw new Error('Base url must be specified');
            }

            if (!this.__isValidUrl(String(context.getBaseUrl()))) {
                throw new Error('Base url "' + context.getBaseUrl() + '" is not a valid URL');
            }
        };

        instance.__validateRestUrl = function (restUrl) {
            if (!this.__isValidUrl(String(restUrl))) {
                throw new Error('Rest url "' + restUrl + '" is not a valid URL');
            }
        };

        instance.__has = function (obj, key) {
            return key.split(".").every(function (x) {
                if (typeof obj != "object" || obj === null || !x in obj) return false;
                obj = obj[x];
                return true;
            });
        };

        instance.__get = function (obj, key) {
            return key.split(".").reduce(function (o, x) {
                return (typeof o == "undefined" || o === null) ? o : o[x];
            }, obj);
        };

        instance.__getEntity = function (resultType, item) {
            var properties = item.property || null;
            var lists = item.list || null;

            if (!resultType) return item;

            var entity = new resultType();

            if (!(entity instanceof NetLicensing.BaseEntity)) {
                throw new Error('Invalid entity ' + resultType + ', entity must be instanceof NetLicensing.BaseEntity');
            }

            var propertiesLength = properties.length;

            for (var p = 0; p < propertiesLength; p++) {
                entity.setProperty(properties[p].name, properties[p].value)
            }

            if (lists) {
                var listsLength = lists.length;
                for (var l = 0; l < listsLength; l++) {
                    var name = lists[l].name;
                    var setListMethod = '__setList' + name.charAt(0).toUpperCase() + name.substr(1, name.length - 1);
                    var setListsMethod = '__setLists';

                    if (typeof entity[setListMethod] !== 'function' && typeof entity[setListsMethod] !== 'function') {
                        console.warn('Methods: ' + setListMethod + ',' + setListsMethod + ' not found in ' + item.type + ' for list property ' + name);
                        continue;
                    }

                    var listProperty = lists[l].property || null;

                    if (typeof entity[setListMethod] === 'function') {
                        entity[setListMethod](listProperty);
                        continue;
                    }

                    if (typeof entity[setListsMethod] === 'function') {
                        entity[setListsMethod](name, listProperty);
                    }
                }
            }

            return entity;
        };

        Object.freeze(instance);

        return instance;
    }

    return {
        getInstance: function () {
            if (!instance) instance = createInstance();
            return instance;
        }
    };
})();<commit_msg>Remove btoa() function<commit_after>/**
 * @author    Labs64 <netlicensing@labs64.com>
 * @license   Apache-2.0
 * @link      http://netlicensing.io
 * @copyright 2017 Labs64 NetLicensing
 */

//namespace
var NetLicensing = NetLicensing || {};

NetLicensing.Service = (function () {
    var instance;

    function createInstance() {
        var instance = {};

        var __httpXHR = {};

        var Base64 = {
            _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
            encode: function (e) {
                var t = "";
                var n, r, i, s, o, u, a;
                var f = 0;
                e = Base64._utf8_encode(e);
                while (f < e.length) {
                    n = e.charCodeAt(f++);
                    r = e.charCodeAt(f++);
                    i = e.charCodeAt(f++);
                    s = n >> 2;
                    o = (n & 3) << 4 | r >> 4;
                    u = (r & 15) << 2 | i >> 6;
                    a = i & 63;
                    if (isNaN(r)) {
                        u = a = 64
                    } else if (isNaN(i)) {
                        a = 64
                    }
                    t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
                }
                return t
            },
            decode: function (e) {
                var t = "";
                var n, r, i;
                var s, o, u, a;
                var f = 0;
                e = e.replace(/[^A-Za-z0-9+/=]/g, "");
                while (f < e.length) {
                    s = this._keyStr.indexOf(e.charAt(f++));
                    o = this._keyStr.indexOf(e.charAt(f++));
                    u = this._keyStr.indexOf(e.charAt(f++));
                    a = this._keyStr.indexOf(e.charAt(f++));
                    n = s << 2 | o >> 4;
                    r = (o & 15) << 4 | u >> 2;
                    i = (u & 3) << 6 | a;
                    t = t + String.fromCharCode(n);
                    if (u != 64) {
                        t = t + String.fromCharCode(r)
                    }
                    if (a != 64) {
                        t = t + String.fromCharCode(i)
                    }
                }
                t = Base64._utf8_decode(t);
                return t
            },
            _utf8_encode: function (e) {
                e = e.replace(/rn/g, "n");
                var t = "";
                for (var n = 0; n < e.length; n++) {
                    var r = e.charCodeAt(n);
                    if (r < 128) {
                        t += String.fromCharCode(r)
                    } else if (r > 127 && r < 2048) {
                        t += String.fromCharCode(r >> 6 | 192);
                        t += String.fromCharCode(r & 63 | 128)
                    } else {
                        t += String.fromCharCode(r >> 12 | 224);
                        t += String.fromCharCode(r >> 6 & 63 | 128);
                        t += String.fromCharCode(r & 63 | 128)
                    }
                }
                return t
            },
            _utf8_decode: function (e) {
                var t = "";
                var n = 0;
                var r = c1 = c2 = 0;
                while (n < e.length) {
                    r = e.charCodeAt(n);
                    if (r < 128) {
                        t += String.fromCharCode(r);
                        n++
                    } else if (r > 191 && r < 224) {
                        c2 = e.charCodeAt(n + 1);
                        t += String.fromCharCode((r & 31) << 6 | c2 & 63);
                        n += 2
                    } else {
                        c2 = e.charCodeAt(n + 1);
                        c3 = e.charCodeAt(n + 2);
                        t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
                        n += 3
                    }
                }
                return t
            }
        };

        instance.getLastHttpRequestInfo = function () {
            return Object.assign({}, __httpXHR)
        };
        /**
         * Helper method for performing GET request to NetLicensing API services. Finds and returns first suitable item with
         * type resultType from the response.
         *
         * Context for the NetLicensing API call
         * @param context
         *
         * the REST URL template
         * @param urlTemplate
         *
         * The REST query parameters values. May be null if there are no parameters.
         * @param queryParams
         *
         * the type of the result
         * @param resultType
         *
         * @returns {Promise}
         */
        instance.get = function (context, urlTemplate, queryParams, resultType) {
            return this.request(context, 'get', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    return (!instance.__has(httpXHR.response, 'items.item.0'))
                        ? null
                        : instance.__getEntity(resultType, instance.__get(httpXHR.response, 'items.item.0'));
                });
        };

        /**
         * Helper method for performing GET request to NetLicensing API service that returns page of items with type
         * resultType.
         *
         * context for the NetLicensing API call
         * @param context
         *
         * the REST URL template
         * @param urlTemplate
         *
         * The REST query parameters values. May be null if there are no parameters.
         * @param queryParams
         *
         * the type of the result
         * @param resultType
         *
         *
         * @returns {Promise}
         */
        instance.list = function (context, urlTemplate, queryParams, resultType) {
            return this.request(context, 'get', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    var entities = [],
                        items = instance.__has(httpXHR.response, 'items.item')
                            ? instance.__get(httpXHR.response, 'items.item')
                            : [],
                        length = items.length;

                    for (var i = 0; i < length; i++) {
                        entities.push(instance.__getEntity(resultType, items[i]));
                    }

                    return entities;
                });
        };

        /**
         * Helper method for performing POST request to NetLicensing API services. Finds and returns first suitable item
         * with type resultType from the response.
         *
         * context for the NetLicensing API call
         * @param context
         *
         * the REST URL template
         * @param urlTemplate
         *
         * The REST query parameters values. May be null if there are no parameters.
         * @param queryParams
         *
         * he type of the result
         * @param resultType
         *
         * @returns {Promise}
         */
        instance.post = function (context, urlTemplate, queryParams, resultType) {
            return this.request(context, 'post', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    return (!instance.__has(httpXHR.response, 'items.item.0'))
                        ? null
                        : instance.__getEntity(resultType, instance.__get(httpXHR.response, 'items.item.0'));
                });
        };

        /**
         *
         * @param context
         * @param urlTemplate
         * @param queryParams
         * @returns {Promise}
         */
        instance.delete = function (context, urlTemplate, queryParams) {
            return this.request(context, 'delete', urlTemplate, queryParams)
                .then(function (httpXHR) {
                    return (httpXHR.status == 204);
                });
        };

        /**
         * Send request to NetLicensing  RestApi
         * @param context
         * @param method
         * @param urlTemplate
         * @param queryParams
         */
        instance.request = function (context, method, urlTemplate, queryParams) {

            if (!(context instanceof NetLicensing.Context)) throw new TypeError('context must be an instance of NetLicensing.Context');

            urlTemplate = String(urlTemplate);
            queryParams = queryParams || {};

            if (!urlTemplate) throw new TypeError('Url template must be specified');

            //validate http method
            this.__validateMethod(method);

            //validate context
            this.__validateBaseUrl(context);

            var restUrl = context.getBaseUrl() + '/' + urlTemplate;

            restUrl = restUrl.replace(/([^:]\/)\/+/g, "$1");

            //validate baseUrl +  urlTemplate
            this.__validateRestUrl(restUrl);

            //configure
            var headers = {Accept: 'application/json'};

            switch (context.getSecurityMode()) {
                case NetLicensing.Context.BASIC_AUTHENTICATION:
                    if (!context.getUsername()) throw new Error('Missing parameter "username"');
                    if (!context.getPassword()) throw new Error('Missing parameter "password"');

                    headers['Authorization'] = 'Basic ' + Base64.encode(context.getUsername() + ':' + context.getPassword());
                    break;
                case NetLicensing.Context.APIKEY_IDENTIFICATION:
                    if (!context.getApiKey()) throw new Error('Missing parameter "apiKey"');

                    headers['Authorization'] = 'Basic ' + Base64.encode('apiKey:' + context.getApiKey());
                    break;
                default:
                    throw new Error('Unknown security mode');
                    break;
            }

            return new NetLicensing.HttpRequest().send({
                url: restUrl,
                method: method,
                headers: headers,
                data: queryParams,
            }).then(function (httpXHR) {
                return __httpXHR = httpXHR;
            }).catch(function (httpXHR) {
                __httpXHR = httpXHR;
                var reasonPhrase = httpXHR.response.infos.info[0].value || 'Unknown';
                throw new Error('Unsupported response status code ' + httpXHR.status + ': ' + reasonPhrase);
            });
        };

        /**
         * Validate http method
         * @param method
         * @private
         */
        instance.__validateMethod = function (method) {
            if (['get', 'post', 'delete'].indexOf(method.toLowerCase()) < 0) {
                throw new Error('Invalid request type:' + method + ', allowed requests types: GET, POST, DELETE.');
            }
        };

        instance.__isValidUrl = function (url) {
            var pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
                '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name
                '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
                '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
                '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
                '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator

            return pattern.test(url);
        };

        instance.__validateBaseUrl = function (context) {
            if (!context.getBaseUrl(null)) {
                throw new Error('Base url must be specified');
            }

            if (!this.__isValidUrl(String(context.getBaseUrl()))) {
                throw new Error('Base url "' + context.getBaseUrl() + '" is not a valid URL');
            }
        };

        instance.__validateRestUrl = function (restUrl) {
            if (!this.__isValidUrl(String(restUrl))) {
                throw new Error('Rest url "' + restUrl + '" is not a valid URL');
            }
        };

        instance.__has = function (obj, key) {
            return key.split(".").every(function (x) {
                if (typeof obj != "object" || obj === null || !x in obj) return false;
                obj = obj[x];
                return true;
            });
        };

        instance.__get = function (obj, key) {
            return key.split(".").reduce(function (o, x) {
                return (typeof o == "undefined" || o === null) ? o : o[x];
            }, obj);
        };

        instance.__getEntity = function (resultType, item) {
            var properties = item.property || null;
            var lists = item.list || null;

            if (!resultType) return item;

            var entity = new resultType();

            if (!(entity instanceof NetLicensing.BaseEntity)) {
                throw new Error('Invalid entity ' + resultType + ', entity must be instanceof NetLicensing.BaseEntity');
            }

            var propertiesLength = properties.length;

            for (var p = 0; p < propertiesLength; p++) {
                entity.setProperty(properties[p].name, properties[p].value)
            }

            if (lists) {
                var listsLength = lists.length;
                for (var l = 0; l < listsLength; l++) {
                    var name = lists[l].name;
                    var setListMethod = '__setList' + name.charAt(0).toUpperCase() + name.substr(1, name.length - 1);
                    var setListsMethod = '__setLists';

                    if (typeof entity[setListMethod] !== 'function' && typeof entity[setListsMethod] !== 'function') {
                        console.warn('Methods: ' + setListMethod + ',' + setListsMethod + ' not found in ' + item.type + ' for list property ' + name);
                        continue;
                    }

                    var listProperty = lists[l].property || null;

                    if (typeof entity[setListMethod] === 'function') {
                        entity[setListMethod](listProperty);
                        continue;
                    }

                    if (typeof entity[setListsMethod] === 'function') {
                        entity[setListsMethod](name, listProperty);
                    }
                }
            }

            return entity;
        };

        Object.freeze(instance);

        return instance;
    }

    return {
        getInstance: function () {
            if (!instance) instance = createInstance();
            return instance;
        }
    };
})();<|endoftext|>


<commit_before>(function() {
    'use strict';

    function TypeMapSvc(AreaChart, BarChart, LineChart, ColumnChart, PieChart, XyChart, TimeChart) {
        var types = {
            piechart: PieChart,
            areachart: AreaChart,
            barchart: BarChart,
            linechart: LineChart,
            combochart: LineChart,
            columnchart: ColumnChart,
            xychart: XyChart,
            timechart: TimeChart
        };

        this.getClass = function(name) {
            return types[name.toLowerCase()];
        };
    }

    angular.module('widgets')
        .service('TypeMap', ['AreaChart', 'BarChart', 'LineChart', 'ColumnChart', 'PieChart', 'XyChart', 'TimeChart', TypeMapSvc]);

})();<commit_msg>added class<commit_after>(function() {
    'use strict';

    function TypeMapSvc(AreaChart, BarChart, LineChart, ColumnChart, PieChart, XyChart, TimeChart, PivotWidget, TextWidget) {
        var types = {
            piechart: {
                class: PieChart,
                type: "chart"
            },
            areachart: {
                class: AreaChart,
                type: "chart"
            },
            barchart: {
                class: BarChart,
                type: "chart"
            },
            barchartstacked: {
                class: BarChart,
                type: "chart"
            },
            linechart: {
                class: LineChart,
                type: "chart"
            },
            combochart: {
                class: LineChart,
                type: "chart"
            },
            columnchart: {
                class: ColumnChart,
                type: "chart"
            },
            xychart: {
                class: XyChart,
                type: "chart"
            },
            timechart: {
                class: TimeChart,
                type: "chart"
            },
            pivot: {
                class: PivotWidget,
                type: "pivot"
            },
            textmeter: {
                class: TextWidget,
                type: "text"
            }
        };

        this.getClass = function(name) {
            if (!types[name.toLowerCase()]) return undefined;
            return types[name.toLowerCase()].class;
        };

        this.getType = function(name) {
            if (!types[name.toLowerCase()]) return undefined;
            return types[name.toLowerCase()].type;
        };
    }

    angular.module('widgets')
        .service('TypeMap', ['AreaChart', 'BarChart', 'LineChart', 'ColumnChart', 'PieChart', 'XyChart', 'TimeChart', 'PivotWidget', 'TextWidget', TypeMapSvc]);

})();<|endoftext|>


<commit_before>/*
  Criteria Class
  Handles all the dirty SQL work
*/
Snake.Criteria = function () {
  this.select = [];
  this.from = [];
  this.join = [];
  this.where = {
    and: [],
    params: []
  };
  this.order = [];
  this.limit = false;
  this.offset = false;
  this.group = [];
};

Snake.Criteria.prototype = {
  selectors: {
    NOT_EQUAL: "<>",
    EQUAL: "=",
    GREATER_THAN: ">",
    LESS_THAN: "<",
    GREATER_EQUAL: ">=",
    LESS_EQUAL: "<=",
    ISNULL: "IS NULL",
    ISNOTNULL: "IS NOT NULL",
    LIKE: "LIKE",
    NOTLIKE: "NOT LIKE",
    "IN": "IN",
    NOTIN: "NOT IN"
  },

  joins: {
    LEFT_JOIN: "LEFT JOIN",
    RIGHT_JOIN: "RIGHT_JOIN",
    INNER_JOIN: "INNER_JOIN"
  },

  addSelectColumn: function (field) {
    var table_field = field.split(".");

    this.select.push(field);
    this.from.push(table_field[0]);
  },

  add: function (field, value, selector) {
    var i = 0
      , or = []
      , where = "";

    // check if value (2nd param) is a selector
    if (value in this.selectors) {
      selector = this.selectors[value];

    // use the selector specified
    } else {
      selector = this.selectors[selector] || this.selectors.EQUAL;
    }

    // handles IS NULL || IS NOT NULL
    if (selector === this.selectors.ISNULL || selector === this.selectors.ISNOTNULL) {
      where = "#{field} #{selector}".interpose({
        field: field,
        selector: selector
      });

      this.where.and.push(where);

    // all other queries
    } else {

      // handles Or || IN || NOT IN
      if (Snake.is_array(field) && Snake.is_array(value)) {
        for (i = 0; i < field.length; i = i + 1) {
          or.push("?");
        }

        // IN || NOT IN
        if (selector === this.selectors.IN || selector === this.selectors.NOTIN) {
          where = "#{field} #{selector} (#{rsIn})".interpose({
            field: field[i],
            selector: selector,
            rsIn: q
          });

        // Or
        } else {

          for (i = 0; i < field.length; i = i + 1) {
            where = "#{field} #{selector} ?".interpose({
              field: field[i],
              selector: selector
            });
            or.push(where);
          }

          this.where.and.push(or);
        }

        // push the params into an Array
        for (i = 0; i < value.length; i = i + 1) {
          this.where.params.push(value[i]);
        }

      // handles And
      } else {
        // TODO - if it's the same column and the selector is EQUAL, perform an or

        where = "#{field} #{selector} ?".interpose({
          field: field,
          selector: selector
        });

        this.where.and.push(where);
        this.where.params.push(value);
      }

    }
  },

  addJoin: function (join1, join2, join_method) {
    join_method = this.joins[join_method] || this.joins.LEFT_JOIN;

    var db1 = join1.split(".")
      , db2 = join2.split(".")
      , table1 = db1[0]
      , field1 = db1[1]
      , table2 = db2[0]
      , field2 = db2[1];

    this.join.push({
      method: join_method,
      from: {
        table: table1,
        field: field1
      },
      to: {
        table: table2,
        field: field2
      }
    });
  },

  addDescendingOrderByColumn: function (column) {
    if (!this.order.in_array(column)) {
      this.order.push(column + " DESC");
    }
  },

  addAscendingOrderByColumn: function (column) {
    if (!this.order.in_array(column)) {
      this.order.push(column + " ASC");
    }
  },

  setLimit: function (limit) {
    limit = limit || false;

    if (limit) {
      this.limit = limit;
    }
  },

  setOffset: function (offset) {
    offset = offset || false;

    if (offset) {
      this.offset = offset;
    }
  },

  executeCount: function (peer, callback) {
    this.select.push("COUNT(*) AS count");
    this.from.push(peer.tableName);
    this.buildQuery("SELECT", peer, callback);
  },

  executeSelect: function (peer, callback) {
    this.buildQuery("SELECT", peer, callback);
  },

  buildQuery: function (operation, peer, onSuccess, onFailure) {
    // INSERT
    if (operation === "INSERT") {
/*
      var values = []
        , q = []
        , i = 0
        , val = null
        , sql = "";

      for (i = 0; i < peer.columns.length; i = i + 1) {
        val = model[peer.columns[i]] || null;

        if (peer.columns[i] === 'created_at' && val === null) {
          val = Date.now();
        }

        values.push(val);
        q.push("?");
      }

      sql = "INSERT INTO '#{table}' (#{columns}) VALUES (#{q})".interpose({
        table: peer.tableName,
        columns: peer.columns,
        q: q
      });
*/

    // SELECT || UPDATE || DELETE
    } else {

      var i = 0
        , sql = ""
        , field = null
        , from = null
        , where = null
        , params = null;

      // add select columns
      if (this.select.length === 0) {
        for (i = 0; i < peer.columns.length; i = i + 1) {
          this.select.push(peer.tableName + "." + peer.columns[i]);
        }
      }

      // add the from
      if (this.from.length === 0) {
        for (i = 0; i < this.select.length; i = i + 1) {
          field = this.select[i];

          from = field.split(".");
          // tables to select from
          if (!this.from.in_array(from[0])) {
            this.from.push(from[0]);
          }
        }
      }

      // build select statement
      sql = "SELECT #{select} FROM #{from}".interpose({
        select: this.select,
        from: this.from
      });

      // joins if any
      if (this.join.length > 0) {
        for (i = 0; i < this.join.length; i = i + 1) {
          sql = sql + " #{method} #{table} ON #{reference} = #{table}.#{key}".interpose({
            method: this.join[i].method,
            reference: this.join[i].from.table + "." + this.join[i].from.field,
            table: this.join[i].to.table,
            key: this.join[i].to.field
          });
        }
      }

      // where
      if (this.where.and.length > 0) {
        for (i = 0; i < this.where.and.length; i = i + 1) {
          if (Snake.is_array(this.where.and[i])) {
            this.where.and[i] = "(" + this.where.and[i].join(" OR ") + ")";
          }
        }

        where = this.where.and.join(" AND ");

        sql = sql + " WHERE " + where;
        params = this.where.params;
      }

      // order by
      if (this.order.length > 0) {
        sql = sql + " ORDER BY #{order}".interpose({ order: this.order });
      }

      // limiter
      if (this.limit) {
        if (this.offset) {
          sql = sql + " LIMIT #{offset}, #{limit}".interpose({ offset: this.offset, limit: this.limit });
        } else {
          sql = sql + " LIMIT #{limit}".interpose({ limit: this.limit });
        }
      }

    }

    if (Snake.debug === true) {
      onSuccess(sql, params);
    }
  }
};

"Criteria" in Snake.global || (Snake.global.Criteria = Snake.Criteria);
<commit_msg>better query building<commit_after>/*
  Criteria Class
  Handles all the dirty SQL work
*/
Snake.Criteria = function () {
  this.select = [];
  this.from = [];
  this.join = [];
  this.where = {
    and: [],
    params: []
  };
  this.order = [];
  this.limit = false;
  this.offset = false;
  this.group = [];
};

Snake.Criteria.prototype = {
  selectors: {
    NOT_EQUAL: "<>",
    EQUAL: "=",
    GREATER_THAN: ">",
    LESS_THAN: "<",
    GREATER_EQUAL: ">=",
    LESS_EQUAL: "<=",
    ISNULL: "IS NULL",
    ISNOTNULL: "IS NOT NULL",
    LIKE: "LIKE",
    NOTLIKE: "NOT LIKE",
    "IN": "IN",
    NOTIN: "NOT IN"
  },

  joins: {
    LEFT_JOIN: "LEFT JOIN",
    RIGHT_JOIN: "RIGHT_JOIN",
    INNER_JOIN: "INNER_JOIN"
  },

  addSelectColumn: function (field) {
    var table_field = field.split(".");

    this.select.push(field);
    this.from.push(table_field[0]);
  },

  add: function (field, value, selector) {
    var i = 0
      , or = []
      , where = "";

    // check if value (2nd param) is a selector
    if (value in this.selectors) {
      selector = this.selectors[value];

    // use the selector specified
    } else {
      selector = this.selectors[selector] || this.selectors.EQUAL;
    }

    // handles IS NULL || IS NOT NULL
    if (selector === this.selectors.ISNULL || selector === this.selectors.ISNOTNULL) {
      where = "#{field} #{selector}".interpose({
        field: field,
        selector: selector
      });

      this.where.and.push(where);

    // all other queries
    } else {

      // handles Or || IN || NOT IN
      if (Snake.is_array(field) && Snake.is_array(value)) {
        for (i = 0; i < field.length; i = i + 1) {
          or.push("?");
        }

        // IN || NOT IN
        if (selector === this.selectors.IN || selector === this.selectors.NOTIN) {
          where = "#{field} #{selector} (#{rsIn})".interpose({
            field: field[i],
            selector: selector,
            rsIn: q
          });

        // Or
        } else {

          for (i = 0; i < field.length; i = i + 1) {
            where = "#{field} #{selector} ?".interpose({
              field: field[i],
              selector: selector
            });
            or.push(where);
          }

          this.where.and.push(or);
        }

        // push the params into an Array
        for (i = 0; i < value.length; i = i + 1) {
          this.where.params.push(value[i]);
        }

      // handles And
      } else {
        // TODO - if it's the same column and the selector is EQUAL, perform an or

        where = "#{field} #{selector} ?".interpose({
          field: field,
          selector: selector
        });

        this.where.and.push(where);
        this.where.params.push(value);
      }

    }
  },

  addJoin: function (join1, join2, join_method) {
    join_method = this.joins[join_method] || this.joins.LEFT_JOIN;

    var db1 = join1.split(".")
      , db2 = join2.split(".")
      , table1 = db1[0]
      , field1 = db1[1]
      , table2 = db2[0]
      , field2 = db2[1];

    this.join.push({
      method: join_method,
      from: {
        table: table1,
        field: field1
      },
      to: {
        table: table2,
        field: field2
      }
    });
  },

  addDescendingOrderByColumn: function (column) {
    if (!this.order.in_array(column)) {
      this.order.push(column + " DESC");
    }
  },

  addAscendingOrderByColumn: function (column) {
    if (!this.order.in_array(column)) {
      this.order.push(column + " ASC");
    }
  },

  setLimit: function (limit) {
    limit = limit || false;

    if (limit) {
      this.limit = limit;
    }
  },

  setOffset: function (offset) {
    offset = offset || false;

    if (offset) {
      this.offset = offset;
    }
  },

  executeCount: function (peer, callback) {
    this.select.push("COUNT(*) AS count");
    this.from.push(peer.tableName);
    this.buildQuery("SELECT", peer, callback);
  },

  executeSelect: function (peer, callback) {
    this.buildQuery("SELECT", peer, callback);
  },

  buildQuery: function (operation, peer, onSuccess, onFailure) {
    // INSERT
    if (operation === "INSERT") {
/*
      var values = []
        , q = []
        , i = 0
        , val = null
        , sql = "";

      for (i = 0; i < peer.columns.length; i = i + 1) {
        val = model[peer.columns[i]] || null;

        if (peer.columns[i] === 'created_at' && val === null) {
          val = Date.now();
        }

        values.push(val);
        q.push("?");
      }

      sql = "INSERT INTO '#{table}' (#{columns}) VALUES (#{q})".interpose({
        table: peer.tableName,
        columns: peer.columns,
        q: q
      });
*/

    // SELECT || UPDATE || DELETE
    } else {

      var i = 0
        , sql = ""
        , field = null
        , from = null
        , where = null
        , params = null;

      // add select columns
      if (this.select.length === 0) {
        for (i = 0; i < peer.columns.length; i = i + 1) {
          this.select.push(peer.tableName + "." + peer.columns[i]);
        }
      }

      // add the from
      if (this.from.length === 0) {
        for (i = 0; i < this.select.length; i = i + 1) {
          field = this.select[i];

          from = field.split(".");
          // tables to select from
          if (!this.from.in_array(from[0])) {
            this.from.push(from[0]);
          }
        }
      }

      var interposableObj = {};

      // build select statement
      sql = "SELECT #{select} FROM #{from}";
      interposableObj.select = this.select;
      interposableObj.from = this.from;

      // joins if any
      if (this.join.length > 0) {
        for (i = 0; i < this.join.length; i = i + 1) {
          sql = sql + " #{method} #{table} ON #{reference} = #{table}.#{key}".interpose({
            method: this.join[i].method,
            reference: this.join[i].from.table + "." + this.join[i].from.field,
            table: this.join[i].to.table,
            key: this.join[i].to.field
          });
        }
      }

      // where
      if (this.where.and.length > 0) {
        for (i = 0; i < this.where.and.length; i = i + 1) {
          if (Snake.is_array(this.where.and[i])) {
            this.where.and[i] = "(" + this.where.and[i].join(" OR ") + ")";
          }
        }

        where = this.where.and.join(" AND ");

        sql = sql + " WHERE " + where;
        params = this.where.params;
      }

      // order by
      if (this.order.length > 0) {
        sql = sql + " ORDER BY #{order}";
        interposableObj.order = this.order;
      }

      // limiter
      if (this.limit) {
        if (this.offset) {
          sql = sql + " LIMIT #{offset}, #{limit}";
          interposableObj.offset = this.offset;
        } else {
          sql = sql + " LIMIT #{limit}";
        }

        interposableObj.limit = this.limit;
      }

      sql = sql.interpose(interposableObj);
    }

    if (Snake.debug === true) {
      onSuccess(sql, params);
    }

  }
};

"Criteria" in Snake.global || (Snake.global.Criteria = Snake.Criteria);
<|endoftext|>


<commit_before>import childProcess from 'child_process'
import fs from 'fs'
import https from 'https'
import mongoose from 'mongoose'
import schedule from 'node-schedule'
import winston from 'winston'
import { version } from '../../package.json'

// Holds the last commit that was synchronized
let lastCommit  =  ''

let db = {}

db.update = (collection) => {
  let url = `https://raw.githubusercontent.com/cobalt-uoft/datasets/master/${collection}.json`
  https.get(url, res => {
    let filePath = `.cobalt_data/${collection}.json`
    let stream = fs.createWriteStream(filePath, {'flags': 'w'})

    res.on('data', chunk => {
      stream.write(chunk)
    })

    res.on('end', () => {
      stream.end()

      mongoose.connection.db.collection(collection).remove(function(e, count) {
        if (e) {
          return winston.warn(`Could not import ${collection} to MongoDB.`, e)
        }

        let shell = childProcess.spawn('mongoimport', [
          '-d', 'cobalt',
          '-c', collection,
          '--file', filePath
        ])

        shell.on('close', code => {
          if (code == 0) {
            winston.info(`Synced ${collection}.`)

            // TODO clean this up
            if (collection === 'athletics') {
              let cmd = 'mongo cobalt --eval "db.athletics.find().forEach(doc=>{doc.date=new Date(doc.date);doc.events.forEach((_,i)=>{doc.events[i].start_time=new Date(doc.events[i].start_time);doc.events[i].end_time=new Date(doc.events[i].end_time)});db.athletics.save(doc)});"'
              childProcess.exec(cmd, error => {
                if (!error) {
                  winston.info(`Updated dates for ${collection}.`)
                } else {
                  winston.warn(`Could not update date values for ${collection}.`)
                }
              })
            }
          } else {
            winston.warn(`Could not import ${collection} to MongoDB. \
              The 'mongoexport' command left us with exit code ${code}.`)
          }
        })
      })
    })

  }).on('error', e => {
    winston.warn('Could not update database, online datasets are \
      currently inaccessible.', e)
  })
}

db.sync = () => {
  db.update('buildings')
  db.update('food')
  db.update('textbooks')
  db.update('courses')
  db.update('athletics')
}

db.check = (callback) => {
  let options  =  {
    host: 'api.github.com',
    port: 443,
    path: '/repos/cobalt-uoft/datasets/git/refs/heads/master',
    headers: {'user-agent': `cobalt-uoft/${version}`}
  }

  https.get(options, res  => {
    let data = ''

    res.on('data', chunk => {
      data += chunk
    })

    res.on('end', () => {
      data = JSON.parse(data)

      // Compare the last commit hash to the current one
      if (data.object.sha == lastCommit) return

      lastCommit = data.object.sha

      // Execute the callback
      if (callback) callback()
    })
  })
}

db.syncCron = () => {
  // Make data directory if it doesn't exist
  try {
    fs.statSync('.cobalt_data')
  } catch(e) {
    fs.mkdirSync('.cobalt_data')
  }

  // Perform sync on startup
  db.sync()

  // Schedule checking for sync every hour
  schedule.scheduleJob('0 * * * *', () => {
    db.check(() => { db.sync() })
  })
}

export default db
<commit_msg>Update post import date conversion<commit_after>import childProcess from 'child_process'
import fs from 'fs'
import https from 'https'
import mongoose from 'mongoose'
import schedule from 'node-schedule'
import winston from 'winston'
import { version } from '../../package.json'

// Holds the last commit that was synchronized
let lastCommit  =  ''

let db = {}

db.update = (collection) => {
  let url = `https://raw.githubusercontent.com/cobalt-uoft/datasets/master/${collection}.json`
  https.get(url, res => {
    let filePath = `.cobalt_data/${collection}.json`
    let stream = fs.createWriteStream(filePath, {'flags': 'w'})

    res.on('data', chunk => {
      stream.write(chunk)
    })

    res.on('end', () => {
      stream.end()

      mongoose.connection.db.collection(collection).remove(function(e, count) {
        if (e) {
          return winston.warn(`Could not import ${collection} to MongoDB.`, e)
        }

        let shell = childProcess.spawn('mongoimport', [
          '-d', 'cobalt',
          '-c', collection,
          '--file', filePath
        ])

        shell.on('close', code => {
          if (code == 0) {
            winston.info(`Synced ${collection}.`)

            // TODO clean this up
            if (['athletics', 'exams'].indexOf(collection) > -1) {
              let cmd = `db.${collection}.find().forEach(doc=>{doc.date=new Date(doc.date);db.${collection}.save(doc)});`

              childProcess.exec(`mongo cobalt --eval "${cmd}"`, error => {
                if (!error) {
                  winston.info(`Updated dates for ${collection}.`)
                } else {
                  winston.warn(`Could not update date values for ${collection}.`)
                }
              })
            }
          } else {
            winston.warn(`Could not import ${collection} to MongoDB. \
              The 'mongoexport' command left us with exit code ${code}.`)
          }
        })
      })
    })

  }).on('error', e => {
    winston.warn('Could not update database, online datasets are \
      currently inaccessible.', e)
  })
}

db.sync = () => {
  db.update('buildings')
  db.update('food')
  db.update('textbooks')
  db.update('courses')
  db.update('athletics')
}

db.check = (callback) => {
  let options  =  {
    host: 'api.github.com',
    port: 443,
    path: '/repos/cobalt-uoft/datasets/git/refs/heads/master',
    headers: {'user-agent': `cobalt-uoft/${version}`}
  }

  https.get(options, res  => {
    let data = ''

    res.on('data', chunk => {
      data += chunk
    })

    res.on('end', () => {
      data = JSON.parse(data)

      // Compare the last commit hash to the current one
      if (data.object.sha == lastCommit) return

      lastCommit = data.object.sha

      // Execute the callback
      if (callback) callback()
    })
  })
}

db.syncCron = () => {
  // Make data directory if it doesn't exist
  try {
    fs.statSync('.cobalt_data')
  } catch(e) {
    fs.mkdirSync('.cobalt_data')
  }

  // Perform sync on startup
  db.sync()

  // Schedule checking for sync every hour
  schedule.scheduleJob('0 * * * *', () => {
    db.check(() => { db.sync() })
  })
}

export default db
<|endoftext|>


<commit_before>L.Icon = L.Class.extend({
	iconUrl: L.ROOT_URL + 'images/marker.png',
	shadowUrl: L.ROOT_URL + 'images/marker-shadow.png',

	//iconSize: new L.Point(24, 37),
	//shadowSize: new L.Point(42, 37),

	iconAnchor: new L.Point(13, 41),
	popupAnchor: new L.Point(0, -33),

	initialize: function(iconUrl) {
		if (iconUrl) {
			this.iconUrl = iconUrl;
		}
	},

	createIcon: function() {
		return this._createImg('icon');
	},

	createShadow: function() {
		return this._createImg('shadow');
	},

	_createImg: function(name) {
		var img = L.DomUtil.create('img', 'leaflet-marker-' + name);

		img.src = this[name + 'Url'];

		if (this.iconAnchor) {
			img.style.marginLeft = (-this.iconAnchor.x) + 'px';
			img.style.marginTop = (-this.iconAnchor.y) + 'px';
		} else {
			L.DomEvent.addListener(img, 'load', this._setAnchorToCenter);
		}

		return img;
	},

	_setAnchorToCenter: function() {
		this.style.marginLeft = (-this.width/2) + 'px';
		this.style.marginTop = (-this.height/2) + 'px';
	}
});<commit_msg>fix markers in IE7 (you have to set the size explicitly for some reason)<commit_after>L.Icon = L.Class.extend({
	iconUrl: L.ROOT_URL + 'images/marker.png',
	shadowUrl: L.ROOT_URL + 'images/marker-shadow.png',

	iconSize: new L.Point(25, 41),
	shadowSize: new L.Point(41, 41),

	iconAnchor: new L.Point(13, 41),
	popupAnchor: new L.Point(0, -33),

	initialize: function(iconUrl) {
		if (iconUrl) {
			this.iconUrl = iconUrl;
		}
	},

	createIcon: function() {
		return this._createImg('icon');
	},

	createShadow: function() {
		return this._createImg('shadow');
	},

	_createImg: function(name) {
		var img = L.DomUtil.create('img', 'leaflet-marker-' + name),
			size = this[name + 'Size'],
			src = this[name + 'Url'];

		img.src = src;

		if (this.iconAnchor) {
			img.style.marginLeft = (-this.iconAnchor.x) + 'px';
			img.style.marginTop = (-this.iconAnchor.y) + 'px';
		} else {
			L.DomEvent.addListener(img, 'load', this._setAnchorToCenter);
		}

		if (size) {
			img.width = size.x;
			img.height = size.y;
		}

		return img;
	},

	_setAnchorToCenter: function() {
		this.style.marginLeft = (-this.width/2) + 'px';
		this.style.marginTop = (-this.height/2) + 'px';
	}
});<|endoftext|>


<commit_before>//>>excludeStart("exclude", pragmas.exclude);
define([ "shoestring" ], function(){
//>>excludeEnd("exclude");

	shoestring.fn.last = function(){
		return this.eq( this.length - 1 );
	};

//>>excludeStart("exclude", pragmas.exclude);
});
//>>excludeEnd("exclude");
<commit_msg>doc last<commit_after>//>>excludeStart("exclude", pragmas.exclude);
define([ "shoestring" ], function(){
//>>excludeEnd("exclude");

	/**
	 * Returns the last element of the set wrapped in a new `shoestring` object.
	 *
	 * @return shoestring
	 * @this shoestring
	 */
	shoestring.fn.last = function(){
		return this.eq( this.length - 1 );
	};

//>>excludeStart("exclude", pragmas.exclude);
});
//>>excludeEnd("exclude");
<|endoftext|>


<commit_before>(function (root, factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['yacollections'], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory(require('yacollections'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.yacollections);
    }
})(this,
function (collections) {
    'use strict';
    var idCounter = -1;

    function EventBus(options) {
        options = options || {};
        // getEventType(:Event):EventType
        var getEventType = options.getEventType || function (event) {
            if (typeof event === undefined || event === null)
                throw new Error('Event must be defined not null value');
            return event.type || event.constructor || typeof event || 'UNKNOWN';
        };
        var eventTypeMap = new collections.Map(options);

        /**
         * EventBus# on(EventType, Handler):StopFn
         */
        this.on = function (eventType, handler) {
            var listeners = getListenersList(eventType);
            var length = listeners.push(handler);
            var index = length - 1;
            return function () {
                listeners.remove(handler);
                cleanUpEventType(eventType, listeners);
            };
        };

        this.once = function (eventType, handler) {
            var stopFn = null;
            var eb = this;
            var newHandler = function (event, callback) {
                handler.apply(eb, arguments);
                if(stopFn) stopFn();
            };
            stopFn = this.on(eventType, newHandler);
            return stopFn;
        };

        var propagate, currentEvent;
        this.emit = function (event, callback) {
            var eventType = getEventType(event);
            var listeners = eventTypeMap.get(eventType) || [];
            currentEvent = event;
            propagate = true;
            for (var i = 0; i < listeners.length && propagate; i++) {
                listeners[i].apply(this, arguments);
            }

        };

        var eventbus = this;
        /**
         * emits the event to every register listener, waiting for it to finish before invoking the next one.
         * In case an error is returned the invokation of the rest of the handlers is stopped and the error is returned to the callback.
         * In case there are no registered listners the callback is invoked with null, [] to indicate that the operation is complete and no errors or data were returned.
         */
        this.emitWait = function (event, callback) {
            var eventType = getEventType(event);
            var listeners = eventTypeMap.get(eventType) || [];
            currentEvent = event;
            propagate = true;
            var i = -1;
            var res = [];
            function next(err, data) {
                //handle error
                if (err) {
                    callback(err, null);
                    return;
                }
                //handle data
                if(typeof data !== 'undefined') {
                    res[i] = data;

                }
                //new iteration
                i += 1;
                if(i < listeners.length)
                    listeners[i].call(eventbus, event, next);
                else
                    callback(null, res);
            }
            next();
        };

        this.off = function (eventType) {
            eventTypeMap.remove(eventType);
        };

        this.cancel = function (event) {
            if (currentEvent === event) {
                propagate = false;
            }
        };

        function getListenersList(eventType) {
            var listeners = eventTypeMap.get(eventType);
            if (typeof listeners === 'undefined') {
                listeners = new collections.List();
                eventTypeMap.set(eventType, listeners);
            }
            return listeners;
        }

        function cleanUpEventType(eventType, listeners) {
            if (listeners.length === 0 && getListenersList(eventType) === listeners) {
                eventTypeMap.remove(eventType);
            }
        }
    }

    return EventBus;
});<commit_msg>I should really pay more attention to the UMD wrapper<commit_after>(function (root, factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['yacollections'], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory(require('yacollections'));
    } else {
        // Browser globals (root is window)
        root.EventBus = factory(root.yacollections);
    }
})(this,
function (collections) {
    'use strict';
    var idCounter = -1;

    function EventBus(options) {
        options = options || {};
        // getEventType(:Event):EventType
        var getEventType = options.getEventType || function (event) {
            if (typeof event === undefined || event === null)
                throw new Error('Event must be defined not null value');
            return event.type || event.constructor || typeof event || 'UNKNOWN';
        };
        var eventTypeMap = new collections.Map(options);

        /**
         * EventBus# on(EventType, Handler):StopFn
         */
        this.on = function (eventType, handler) {
            var listeners = getListenersList(eventType);
            var length = listeners.push(handler);
            var index = length - 1;
            return function () {
                listeners.remove(handler);
                cleanUpEventType(eventType, listeners);
            };
        };

        this.once = function (eventType, handler) {
            var stopFn = null;
            var eb = this;
            var newHandler = function (event, callback) {
                handler.apply(eb, arguments);
                if(stopFn) stopFn();
            };
            stopFn = this.on(eventType, newHandler);
            return stopFn;
        };

        var propagate, currentEvent;
        this.emit = function (event, callback) {
            var eventType = getEventType(event);
            var listeners = eventTypeMap.get(eventType) || [];
            currentEvent = event;
            propagate = true;
            for (var i = 0; i < listeners.length && propagate; i++) {
                listeners[i].apply(this, arguments);
            }

        };

        var eventbus = this;
        /**
         * emits the event to every register listener, waiting for it to finish before invoking the next one.
         * In case an error is returned the invokation of the rest of the handlers is stopped and the error is returned to the callback.
         * In case there are no registered listners the callback is invoked with null, [] to indicate that the operation is complete and no errors or data were returned.
         */
        this.emitWait = function (event, callback) {
            var eventType = getEventType(event);
            var listeners = eventTypeMap.get(eventType) || [];
            currentEvent = event;
            propagate = true;
            var i = -1;
            var res = [];
            function next(err, data) {
                //handle error
                if (err) {
                    callback(err, null);
                    return;
                }
                //handle data
                if(typeof data !== 'undefined') {
                    res[i] = data;

                }
                //new iteration
                i += 1;
                if(i < listeners.length)
                    listeners[i].call(eventbus, event, next);
                else
                    callback(null, res);
            }
            next();
        };

        this.off = function (eventType) {
            eventTypeMap.remove(eventType);
        };

        this.cancel = function (event) {
            if (currentEvent === event) {
                propagate = false;
            }
        };

        function getListenersList(eventType) {
            var listeners = eventTypeMap.get(eventType);
            if (typeof listeners === 'undefined') {
                listeners = new collections.List();
                eventTypeMap.set(eventType, listeners);
            }
            return listeners;
        }

        function cleanUpEventType(eventType, listeners) {
            if (listeners.length === 0 && getListenersList(eventType) === listeners) {
                eventTypeMap.remove(eventType);
            }
        }
    }

    return EventBus;
});<|endoftext|>