<commit_before>import {
	DataTextureLoader,
	DataUtils,
	FloatType,
	HalfFloatType,
	LinearEncoding,
	LinearFilter,
	NearestFilter,
	RGBEEncoding,
	RGBEFormat,
	RGBFormat,
	UnsignedByteType
} from '../../../build/three.module.js';

// https://github.com/mrdoob/three.js/issues/5552
// http://en.wikipedia.org/wiki/RGBE_image_format

class RGBELoader extends DataTextureLoader {

	constructor( manager ) {

		super( manager );

		this.type = HalfFloatType;

	}

	// adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html

	parse( buffer ) {

		const
			/* return codes for rgbe routines */
			//RGBE_RETURN_SUCCESS = 0,
			RGBE_RETURN_FAILURE = - 1,

			/* default error routine.  change this to change error handling */
			rgbe_read_error = 1,
			rgbe_write_error = 2,
			rgbe_format_error = 3,
			rgbe_memory_error = 4,
			rgbe_error = function ( rgbe_error_code, msg ) {

				switch ( rgbe_error_code ) {

					case rgbe_read_error: console.error( 'THREE.RGBELoader Read Error: ' + ( msg || '' ) );
						break;
					case rgbe_write_error: console.error( 'THREE.RGBELoader Write Error: ' + ( msg || '' ) );
						break;
					case rgbe_format_error: console.error( 'THREE.RGBELoader Bad File Format: ' + ( msg || '' ) );
						break;
					default:
					case rgbe_memory_error: console.error( 'THREE.RGBELoader: Error: ' + ( msg || '' ) );

				}

				return RGBE_RETURN_FAILURE;

			},

			/* offsets to red, green, and blue components in a data (float) pixel */
			//RGBE_DATA_RED = 0,
			//RGBE_DATA_GREEN = 1,
			//RGBE_DATA_BLUE = 2,

			/* number of floats per pixel, use 4 since stored in rgba image format */
			//RGBE_DATA_SIZE = 4,

			/* flags indicating which fields in an rgbe_header_info are valid */
			RGBE_VALID_PROGRAMTYPE = 1,
			RGBE_VALID_FORMAT = 2,
			RGBE_VALID_DIMENSIONS = 4,

			NEWLINE = '\n',

			fgets = function ( buffer, lineLimit, consume ) {

				const chunkSize = 128;

				lineLimit = ! lineLimit ? 1024 : lineLimit;
				let p = buffer.pos,
					i = - 1, len = 0, s = '',
					chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );

				while ( ( 0 > ( i = chunk.indexOf( NEWLINE ) ) ) && ( len < lineLimit ) && ( p < buffer.byteLength ) ) {

					s += chunk; len += chunk.length;
					p += chunkSize;
					chunk += String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );

				}

				if ( - 1 < i ) {

					/*for (i=l-1; i>=0; i--) {
						byteCode = m.charCodeAt(i);
						if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++;
						else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2;
						if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate
					}*/
					if ( false !== consume ) buffer.pos += len + i + 1;
					return s + chunk.slice( 0, i );

				}

				return false;

			},

			/* minimal header reading.  modify if you want to parse more information */
			RGBE_ReadHeader = function ( buffer ) {

				// regexes to parse header info fields
				const magic_token_re = /^#\?(\S+)/,
					gamma_re = /^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/,
					exposure_re = /^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/,
					format_re = /^\s*FORMAT=(\S+)\s*$/,
					dimensions_re = /^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/,

					// RGBE format header struct
					header = {

						valid: 0, /* indicate which fields are valid */

						string: '', /* the actual header string */

						comments: '', /* comments found in header */

						programtype: 'RGBE', /* listed at beginning of file to identify it after "#?". defaults to "RGBE" */

						format: '', /* RGBE format, default 32-bit_rle_rgbe */

						gamma: 1.0, /* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */

						exposure: 1.0, /* a value of 1.0 in an image corresponds to <exposure> watts/steradian/m^2. defaults to 1.0 */

						width: 0, height: 0 /* image dimensions, width/height */

					};

				let line, match;

				if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) {

					return rgbe_error( rgbe_read_error, 'no header found' );

				}

				/* if you want to require the magic token then uncomment the next line */
				if ( ! ( match = line.match( magic_token_re ) ) ) {

					return rgbe_error( rgbe_format_error, 'bad initial token' );

				}

				header.valid |= RGBE_VALID_PROGRAMTYPE;
				header.programtype = match[ 1 ];
				header.string += line + '\n';

				while ( true ) {

					line = fgets( buffer );
					if ( false === line ) break;
					header.string += line + '\n';

					if ( '#' === line.charAt( 0 ) ) {

						header.comments += line + '\n';
						continue; // comment line

					}

					if ( match = line.match( gamma_re ) ) {

						header.gamma = parseFloat( match[ 1 ], 10 );

					}

					if ( match = line.match( exposure_re ) ) {

						header.exposure = parseFloat( match[ 1 ], 10 );

					}

					if ( match = line.match( format_re ) ) {

						header.valid |= RGBE_VALID_FORMAT;
						header.format = match[ 1 ];//'32-bit_rle_rgbe';

					}

					if ( match = line.match( dimensions_re ) ) {

						header.valid |= RGBE_VALID_DIMENSIONS;
						header.height = parseInt( match[ 1 ], 10 );
						header.width = parseInt( match[ 2 ], 10 );

					}

					if ( ( header.valid & RGBE_VALID_FORMAT ) && ( header.valid & RGBE_VALID_DIMENSIONS ) ) break;

				}

				if ( ! ( header.valid & RGBE_VALID_FORMAT ) ) {

					return rgbe_error( rgbe_format_error, 'missing format specifier' );

				}

				if ( ! ( header.valid & RGBE_VALID_DIMENSIONS ) ) {

					return rgbe_error( rgbe_format_error, 'missing image size specifier' );

				}

				return header;

			},

			RGBE_ReadPixels_RLE = function ( buffer, w, h ) {

				const scanline_width = w;

				if (
					// run length encoding is not allowed so read flat
					( ( scanline_width < 8 ) || ( scanline_width > 0x7fff ) ) ||
					// this file is not run length encoded
					( ( 2 !== buffer[ 0 ] ) || ( 2 !== buffer[ 1 ] ) || ( buffer[ 2 ] & 0x80 ) )
				) {

					// return the flat buffer
					return new Uint8Array( buffer );

				}

				if ( scanline_width !== ( ( buffer[ 2 ] << 8 ) | buffer[ 3 ] ) ) {

					return rgbe_error( rgbe_format_error, 'wrong scanline width' );

				}

				const data_rgba = new Uint8Array( 4 * w * h );

				if ( ! data_rgba.length ) {

					return rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' );

				}

				let offset = 0, pos = 0;

				const ptr_end = 4 * scanline_width;
				const rgbeStart = new Uint8Array( 4 );
				const scanline_buffer = new Uint8Array( ptr_end );
				let num_scanlines = h;

				// read in each successive scanline
				while ( ( num_scanlines > 0 ) && ( pos < buffer.byteLength ) ) {

					if ( pos + 4 > buffer.byteLength ) {

						return rgbe_error( rgbe_read_error );

					}

					rgbeStart[ 0 ] = buffer[ pos ++ ];
					rgbeStart[ 1 ] = buffer[ pos ++ ];
					rgbeStart[ 2 ] = buffer[ pos ++ ];
					rgbeStart[ 3 ] = buffer[ pos ++ ];

					if ( ( 2 != rgbeStart[ 0 ] ) || ( 2 != rgbeStart[ 1 ] ) || ( ( ( rgbeStart[ 2 ] << 8 ) | rgbeStart[ 3 ] ) != scanline_width ) ) {

						return rgbe_error( rgbe_format_error, 'bad rgbe scanline format' );

					}

					// read each of the four channels for the scanline into the buffer
					// first red, then green, then blue, then exponent
					let ptr = 0, count;

					while ( ( ptr < ptr_end ) && ( pos < buffer.byteLength ) ) {

						count = buffer[ pos ++ ];
						const isEncodedRun = count > 128;
						if ( isEncodedRun ) count -= 128;

						if ( ( 0 === count ) || ( ptr + count > ptr_end ) ) {

							return rgbe_error( rgbe_format_error, 'bad scanline data' );

						}

						if ( isEncodedRun ) {

							// a (encoded) run of the same value
							const byteValue = buffer[ pos ++ ];
							for ( let i = 0; i < count; i ++ ) {

								scanline_buffer[ ptr ++ ] = byteValue;

							}
							//ptr += count;

						} else {

							// a literal-run
							scanline_buffer.set( buffer.subarray( pos, pos + count ), ptr );
							ptr += count; pos += count;

						}

					}

					// now convert data from buffer into rgba
					// first red, then green, then blue, then exponent (alpha)
					const l = scanline_width; //scanline_buffer.byteLength;
					for ( let i = 0; i < l; i ++ ) {

						let off = 0;
						data_rgba[ offset ] = scanline_buffer[ i + off ];
						off += scanline_width; //1;
						data_rgba[ offset + 1 ] = scanline_buffer[ i + off ];
						off += scanline_width; //1;
						data_rgba[ offset + 2 ] = scanline_buffer[ i + off ];
						off += scanline_width; //1;
						data_rgba[ offset + 3 ] = scanline_buffer[ i + off ];
						offset += 4;

					}

					num_scanlines --;

				}

				return data_rgba;

			};

		const RGBEByteToRGBFloat = function ( sourceArray, sourceOffset, destArray, destOffset ) {

			const e = sourceArray[ sourceOffset + 3 ];
			const scale = Math.pow( 2.0, e - 128.0 ) / 255.0;

			destArray[ destOffset + 0 ] = sourceArray[ sourceOffset + 0 ] * scale;
			destArray[ destOffset + 1 ] = sourceArray[ sourceOffset + 1 ] * scale;
			destArray[ destOffset + 2 ] = sourceArray[ sourceOffset + 2 ] * scale;

		};

		const RGBEByteToRGBHalf = function ( sourceArray, sourceOffset, destArray, destOffset ) {

			const e = sourceArray[ sourceOffset + 3 ];
			const scale = Math.pow( 2.0, e - 128.0 ) / 255.0;

			destArray[ destOffset + 0 ] = DataUtils.toHalfFloat( sourceArray[ sourceOffset + 0 ] * scale );
			destArray[ destOffset + 1 ] = DataUtils.toHalfFloat( sourceArray[ sourceOffset + 1 ] * scale );
			destArray[ destOffset + 2 ] = DataUtils.toHalfFloat( sourceArray[ sourceOffset + 2 ] * scale );

		};

		const byteArray = new Uint8Array( buffer );
		byteArray.pos = 0;
		const rgbe_header_info = RGBE_ReadHeader( byteArray );

		if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {

			const w = rgbe_header_info.width,
				h = rgbe_header_info.height,
				image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h );

			if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {

				let data, format, type;
				let numElements;

				switch ( this.type ) {

					case UnsignedByteType:

						data = image_rgba_data;
						format = RGBEFormat; // handled as THREE.RGBAFormat in shaders
						type = UnsignedByteType;
						break;

					case FloatType:

						numElements = ( image_rgba_data.length / 4 ) * 3;
						const floatArray = new Float32Array( numElements );

						for ( let j = 0; j < numElements; j ++ ) {

							RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 3 );

						}

						data = floatArray;
						format = RGBFormat;
						type = FloatType;
						break;

					case HalfFloatType:

						numElements = ( image_rgba_data.length / 4 ) * 3;
						const halfArray = new Uint16Array( numElements );

						for ( let j = 0; j < numElements; j ++ ) {

							RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 3 );

						}

						data = halfArray;
						format = RGBFormat;
						type = HalfFloatType;
						break;

					default:

						console.error( 'THREE.RGBELoader: unsupported type: ', this.type );
						break;

				}

				return {
					width: w, height: h,
					data: data,
					header: rgbe_header_info.string,
					gamma: rgbe_header_info.gamma,
					exposure: rgbe_header_info.exposure,
					format: format,
					type: type
				};

			}

		}

		return null;

	}

	setDataType( value ) {

		this.type = value;
		return this;

	}

	load( url, onLoad, onProgress, onError ) {

		function onLoadCallback( texture, texData ) {

			switch ( texture.type ) {

				case UnsignedByteType:

					texture.encoding = RGBEEncoding;
					texture.minFilter = NearestFilter;
					texture.magFilter = NearestFilter;
					texture.generateMipmaps = false;
					texture.flipY = true;
					break;

				case FloatType:

					texture.encoding = LinearEncoding;
					texture.minFilter = LinearFilter;
					texture.magFilter = LinearFilter;
					texture.generateMipmaps = false;
					texture.flipY = true;
					break;

				case HalfFloatType:

					texture.encoding = LinearEncoding;
					texture.minFilter = LinearFilter;
					texture.magFilter = LinearFilter;
					texture.generateMipmaps = false;
					texture.flipY = true;
					break;

			}

			if ( onLoad ) onLoad( texture, texData );

		}

		return super.load( url, onLoadCallback, onProgress, onError );

	}

}

export { RGBELoader };
<commit_msg>RGBELoader: Clean up.<commit_after>import {
	DataTextureLoader,
	DataUtils,
	FloatType,
	HalfFloatType,
	LinearEncoding,
	LinearFilter,
	NearestFilter,
	RGBEEncoding,
	RGBEFormat,
	RGBFormat,
	UnsignedByteType
} from '../../../build/three.module.js';

// https://github.com/mrdoob/three.js/issues/5552
// http://en.wikipedia.org/wiki/RGBE_image_format

class RGBELoader extends DataTextureLoader {

	constructor( manager ) {

		super( manager );

		this.type = HalfFloatType;

	}

	// adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html

	parse( buffer ) {

		const
			/* return codes for rgbe routines */
			//RGBE_RETURN_SUCCESS = 0,
			RGBE_RETURN_FAILURE = - 1,

			/* default error routine.  change this to change error handling */
			rgbe_read_error = 1,
			rgbe_write_error = 2,
			rgbe_format_error = 3,
			rgbe_memory_error = 4,
			rgbe_error = function ( rgbe_error_code, msg ) {

				switch ( rgbe_error_code ) {

					case rgbe_read_error: console.error( 'THREE.RGBELoader Read Error: ' + ( msg || '' ) );
						break;
					case rgbe_write_error: console.error( 'THREE.RGBELoader Write Error: ' + ( msg || '' ) );
						break;
					case rgbe_format_error: console.error( 'THREE.RGBELoader Bad File Format: ' + ( msg || '' ) );
						break;
					default:
					case rgbe_memory_error: console.error( 'THREE.RGBELoader: Error: ' + ( msg || '' ) );

				}

				return RGBE_RETURN_FAILURE;

			},

			/* offsets to red, green, and blue components in a data (float) pixel */
			//RGBE_DATA_RED = 0,
			//RGBE_DATA_GREEN = 1,
			//RGBE_DATA_BLUE = 2,

			/* number of floats per pixel, use 4 since stored in rgba image format */
			//RGBE_DATA_SIZE = 4,

			/* flags indicating which fields in an rgbe_header_info are valid */
			RGBE_VALID_PROGRAMTYPE = 1,
			RGBE_VALID_FORMAT = 2,
			RGBE_VALID_DIMENSIONS = 4,

			NEWLINE = '\n',

			fgets = function ( buffer, lineLimit, consume ) {

				const chunkSize = 128;

				lineLimit = ! lineLimit ? 1024 : lineLimit;
				let p = buffer.pos,
					i = - 1, len = 0, s = '',
					chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );

				while ( ( 0 > ( i = chunk.indexOf( NEWLINE ) ) ) && ( len < lineLimit ) && ( p < buffer.byteLength ) ) {

					s += chunk; len += chunk.length;
					p += chunkSize;
					chunk += String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );

				}

				if ( - 1 < i ) {

					/*for (i=l-1; i>=0; i--) {
						byteCode = m.charCodeAt(i);
						if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++;
						else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2;
						if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate
					}*/
					if ( false !== consume ) buffer.pos += len + i + 1;
					return s + chunk.slice( 0, i );

				}

				return false;

			},

			/* minimal header reading.  modify if you want to parse more information */
			RGBE_ReadHeader = function ( buffer ) {

				// regexes to parse header info fields
				const magic_token_re = /^#\?(\S+)/,
					gamma_re = /^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/,
					exposure_re = /^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/,
					format_re = /^\s*FORMAT=(\S+)\s*$/,
					dimensions_re = /^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/,

					// RGBE format header struct
					header = {

						valid: 0, /* indicate which fields are valid */

						string: '', /* the actual header string */

						comments: '', /* comments found in header */

						programtype: 'RGBE', /* listed at beginning of file to identify it after "#?". defaults to "RGBE" */

						format: '', /* RGBE format, default 32-bit_rle_rgbe */

						gamma: 1.0, /* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */

						exposure: 1.0, /* a value of 1.0 in an image corresponds to <exposure> watts/steradian/m^2. defaults to 1.0 */

						width: 0, height: 0 /* image dimensions, width/height */

					};

				let line, match;

				if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) {

					return rgbe_error( rgbe_read_error, 'no header found' );

				}

				/* if you want to require the magic token then uncomment the next line */
				if ( ! ( match = line.match( magic_token_re ) ) ) {

					return rgbe_error( rgbe_format_error, 'bad initial token' );

				}

				header.valid |= RGBE_VALID_PROGRAMTYPE;
				header.programtype = match[ 1 ];
				header.string += line + '\n';

				while ( true ) {

					line = fgets( buffer );
					if ( false === line ) break;
					header.string += line + '\n';

					if ( '#' === line.charAt( 0 ) ) {

						header.comments += line + '\n';
						continue; // comment line

					}

					if ( match = line.match( gamma_re ) ) {

						header.gamma = parseFloat( match[ 1 ], 10 );

					}

					if ( match = line.match( exposure_re ) ) {

						header.exposure = parseFloat( match[ 1 ], 10 );

					}

					if ( match = line.match( format_re ) ) {

						header.valid |= RGBE_VALID_FORMAT;
						header.format = match[ 1 ];//'32-bit_rle_rgbe';

					}

					if ( match = line.match( dimensions_re ) ) {

						header.valid |= RGBE_VALID_DIMENSIONS;
						header.height = parseInt( match[ 1 ], 10 );
						header.width = parseInt( match[ 2 ], 10 );

					}

					if ( ( header.valid & RGBE_VALID_FORMAT ) && ( header.valid & RGBE_VALID_DIMENSIONS ) ) break;

				}

				if ( ! ( header.valid & RGBE_VALID_FORMAT ) ) {

					return rgbe_error( rgbe_format_error, 'missing format specifier' );

				}

				if ( ! ( header.valid & RGBE_VALID_DIMENSIONS ) ) {

					return rgbe_error( rgbe_format_error, 'missing image size specifier' );

				}

				return header;

			},

			RGBE_ReadPixels_RLE = function ( buffer, w, h ) {

				const scanline_width = w;

				if (
					// run length encoding is not allowed so read flat
					( ( scanline_width < 8 ) || ( scanline_width > 0x7fff ) ) ||
					// this file is not run length encoded
					( ( 2 !== buffer[ 0 ] ) || ( 2 !== buffer[ 1 ] ) || ( buffer[ 2 ] & 0x80 ) )
				) {

					// return the flat buffer
					return new Uint8Array( buffer );

				}

				if ( scanline_width !== ( ( buffer[ 2 ] << 8 ) | buffer[ 3 ] ) ) {

					return rgbe_error( rgbe_format_error, 'wrong scanline width' );

				}

				const data_rgba = new Uint8Array( 4 * w * h );

				if ( ! data_rgba.length ) {

					return rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' );

				}

				let offset = 0, pos = 0;

				const ptr_end = 4 * scanline_width;
				const rgbeStart = new Uint8Array( 4 );
				const scanline_buffer = new Uint8Array( ptr_end );
				let num_scanlines = h;

				// read in each successive scanline
				while ( ( num_scanlines > 0 ) && ( pos < buffer.byteLength ) ) {

					if ( pos + 4 > buffer.byteLength ) {

						return rgbe_error( rgbe_read_error );

					}

					rgbeStart[ 0 ] = buffer[ pos ++ ];
					rgbeStart[ 1 ] = buffer[ pos ++ ];
					rgbeStart[ 2 ] = buffer[ pos ++ ];
					rgbeStart[ 3 ] = buffer[ pos ++ ];

					if ( ( 2 != rgbeStart[ 0 ] ) || ( 2 != rgbeStart[ 1 ] ) || ( ( ( rgbeStart[ 2 ] << 8 ) | rgbeStart[ 3 ] ) != scanline_width ) ) {

						return rgbe_error( rgbe_format_error, 'bad rgbe scanline format' );

					}

					// read each of the four channels for the scanline into the buffer
					// first red, then green, then blue, then exponent
					let ptr = 0, count;

					while ( ( ptr < ptr_end ) && ( pos < buffer.byteLength ) ) {

						count = buffer[ pos ++ ];
						const isEncodedRun = count > 128;
						if ( isEncodedRun ) count -= 128;

						if ( ( 0 === count ) || ( ptr + count > ptr_end ) ) {

							return rgbe_error( rgbe_format_error, 'bad scanline data' );

						}

						if ( isEncodedRun ) {

							// a (encoded) run of the same value
							const byteValue = buffer[ pos ++ ];
							for ( let i = 0; i < count; i ++ ) {

								scanline_buffer[ ptr ++ ] = byteValue;

							}
							//ptr += count;

						} else {

							// a literal-run
							scanline_buffer.set( buffer.subarray( pos, pos + count ), ptr );
							ptr += count; pos += count;

						}

					}

					// now convert data from buffer into rgba
					// first red, then green, then blue, then exponent (alpha)
					const l = scanline_width; //scanline_buffer.byteLength;
					for ( let i = 0; i < l; i ++ ) {

						let off = 0;
						data_rgba[ offset ] = scanline_buffer[ i + off ];
						off += scanline_width; //1;
						data_rgba[ offset + 1 ] = scanline_buffer[ i + off ];
						off += scanline_width; //1;
						data_rgba[ offset + 2 ] = scanline_buffer[ i + off ];
						off += scanline_width; //1;
						data_rgba[ offset + 3 ] = scanline_buffer[ i + off ];
						offset += 4;

					}

					num_scanlines --;

				}

				return data_rgba;

			};

		const RGBEByteToRGBFloat = function ( sourceArray, sourceOffset, destArray, destOffset ) {

			const e = sourceArray[ sourceOffset + 3 ];
			const scale = Math.pow( 2.0, e - 128.0 ) / 255.0;

			destArray[ destOffset + 0 ] = sourceArray[ sourceOffset + 0 ] * scale;
			destArray[ destOffset + 1 ] = sourceArray[ sourceOffset + 1 ] * scale;
			destArray[ destOffset + 2 ] = sourceArray[ sourceOffset + 2 ] * scale;

		};

		const RGBEByteToRGBHalf = function ( sourceArray, sourceOffset, destArray, destOffset ) {

			const e = sourceArray[ sourceOffset + 3 ];
			const scale = Math.pow( 2.0, e - 128.0 ) / 255.0;

			destArray[ destOffset + 0 ] = DataUtils.toHalfFloat( sourceArray[ sourceOffset + 0 ] * scale );
			destArray[ destOffset + 1 ] = DataUtils.toHalfFloat( sourceArray[ sourceOffset + 1 ] * scale );
			destArray[ destOffset + 2 ] = DataUtils.toHalfFloat( sourceArray[ sourceOffset + 2 ] * scale );

		};

		const byteArray = new Uint8Array( buffer );
		byteArray.pos = 0;
		const rgbe_header_info = RGBE_ReadHeader( byteArray );

		if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {

			const w = rgbe_header_info.width,
				h = rgbe_header_info.height,
				image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h );

			if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {

				let data, format, type;
				let numElements;

				switch ( this.type ) {

					case UnsignedByteType:

						data = image_rgba_data;
						format = RGBEFormat; // handled as THREE.RGBAFormat in shaders
						type = UnsignedByteType;
						break;

					case FloatType:

						numElements = image_rgba_data.length / 4;
						const floatArray = new Float32Array( numElements * 3 );

						for ( let j = 0; j < numElements; j ++ ) {

							RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 3 );

						}

						data = floatArray;
						format = RGBFormat;
						type = FloatType;
						break;

					case HalfFloatType:

						numElements = image_rgba_data.length / 4;
						const halfArray = new Uint16Array( numElements * 3 );

						for ( let j = 0; j < numElements; j ++ ) {

							RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 3 );

						}

						data = halfArray;
						format = RGBFormat;
						type = HalfFloatType;
						break;

					default:

						console.error( 'THREE.RGBELoader: unsupported type: ', this.type );
						break;

				}

				return {
					width: w, height: h,
					data: data,
					header: rgbe_header_info.string,
					gamma: rgbe_header_info.gamma,
					exposure: rgbe_header_info.exposure,
					format: format,
					type: type
				};

			}

		}

		return null;

	}

	setDataType( value ) {

		this.type = value;
		return this;

	}

	load( url, onLoad, onProgress, onError ) {

		function onLoadCallback( texture, texData ) {

			switch ( texture.type ) {

				case UnsignedByteType:

					texture.encoding = RGBEEncoding;
					texture.minFilter = NearestFilter;
					texture.magFilter = NearestFilter;
					texture.generateMipmaps = false;
					texture.flipY = true;
					break;

				case FloatType:

					texture.encoding = LinearEncoding;
					texture.minFilter = LinearFilter;
					texture.magFilter = LinearFilter;
					texture.generateMipmaps = false;
					texture.flipY = true;
					break;

				case HalfFloatType:

					texture.encoding = LinearEncoding;
					texture.minFilter = LinearFilter;
					texture.magFilter = LinearFilter;
					texture.generateMipmaps = false;
					texture.flipY = true;
					break;

			}

			if ( onLoad ) onLoad( texture, texData );

		}

		return super.load( url, onLoadCallback, onProgress, onError );

	}

}

export { RGBELoader };
<|endoftext|>


<commit_before>var layout = (function () {
    var map = null;

    return {
        initMap : function () {
            var mapDet = {
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

            map = new google.maps.Map(document.getElementById('transitMap'), mapDet);
            return map;
        },

        initMarker : function (coords, hoverText) {
            hoverText = (typeof hoverText == 'undefined') ? 'Marker' : hoverText;
            var markerPos = new google.maps.LatLng(coords[0], coords[1]);

            var markerIcon = {
                path: google.maps.SymbolPath.CIRCLE,
                fillColor: 'black',
                fillOpacity: 0.8,
                scale: 4
            };

            var marker = {
                position: markerPos,
                title: hoverText,
                icon: markerIcon
            };

            marker = new google.maps.Marker(marker);
            return marker;
        },

        moveMarkers : function (markerSet, interval) {
            interval = (typeof interval == 'undefined') ? 1000 : interval;
            var transition = setInterval(
                    function () {
                        for (var counter = 0; counter < markerSet.length; counter++) {
                            for (var i = 0; i < markerSet.length; i++) {
                                var curPos = new google.maps.LatLng(markerSet[i].coordSet[counter][0],
                                    markerSet[i].coordSet[counter][1]);
                                markerSet[i].marker.position = curPos;
                                markerSet[i].marker.setMap(map);
                            }
                        }
                    },
                    interval);
        },

        constructMarkerSet : function (markers) {
            var markerSet = new Array();
            for (var counter = 0; counter < markers.length; counter++) {
                markerObj = layout.initMarker(markers[counter].coords[0], markers[counter].hoverText);
                coordList = markers[counter].coords.slice(1);

                markerSet.push({
                    marker: markerObj,
                    coordSet: coordList
                });
            }
            return markerSet;
        },

        overlayKml : function (kmlUrl) {
            var kmlOptions = {
                map: map
            };
            var kmlLayer = new google.maps.KmlLayer(kmlUrl, kmlOptions);
        },

        init : function (kmlUrl, markerList, interval) {
            google.maps.event.addDomListener(window, 'load',
                    function () {
                        map = layout.initMap();
                        layout.overlayKml(kmlUrl);
                        var markerSet = layout.constructMarkerSet(markerList);
                        layout.moveMarkers(markerSet, interval);
                    });
        }
    };
})();

var processRoute = (function () {
    return {
        parseXml : function (xmlUrl) {
            $.ajax({
                url: xmlUrl,
                dataType: 'xml',
                success : function (data) {
                    var xmlNode = $('Document', data);
                    var lines = new Array();
                    xmlNode.find('Placemark > LineString > coordinates').each(function () {
                        lines.push($(this).text());
                    });
                },
                error : function (data) {
                    console.log('Error');
                }
            });
        }
    };
})();
<commit_msg>Points json object<commit_after>var layout = (function () {
    var map = null;

    return {
        initMap : function () {
            var mapDet = {
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

            map = new google.maps.Map(document.getElementById('transitMap'), mapDet);
            return map;
        },

        initMarker : function (coords, hoverText) {
            hoverText = (typeof hoverText == 'undefined') ? 'Marker' : hoverText;
            var markerPos = new google.maps.LatLng(coords[0], coords[1]);

            var markerIcon = {
                path: google.maps.SymbolPath.CIRCLE,
                fillColor: 'black',
                fillOpacity: 0.8,
                scale: 4
            };

            var marker = {
                position: markerPos,
                title: hoverText,
                icon: markerIcon
            };

            marker = new google.maps.Marker(marker);
            return marker;
        },

        moveMarkers : function (markerSet, interval) {
            interval = (typeof interval == 'undefined') ? 1000 : interval;
            var transition = setInterval(
                    function () {
                        for (var counter = 0; counter < markerSet.length; counter++) {
                            for (var i = 0; i < markerSet.length; i++) {
                                var curPos = new google.maps.LatLng(markerSet[i].coordSet[counter][0],
                                    markerSet[i].coordSet[counter][1]);
                                markerSet[i].marker.position = curPos;
                                markerSet[i].marker.setMap(map);
                            }
                        }
                    },
                    interval);
        },

        constructMarkerSet : function (markers) {
            var markerSet = new Array();
            for (var counter = 0; counter < markers.length; counter++) {
                markerObj = layout.initMarker(markers[counter].coords[0], markers[counter].hoverText);
                coordList = markers[counter].coords.slice(1);

                markerSet.push({
                    marker: markerObj,
                    coordSet: coordList
                });
            }
            return markerSet;
        },

        overlayKml : function (kmlUrl) {
            var kmlOptions = {
                map: map
            };
            var kmlLayer = new google.maps.KmlLayer(kmlUrl, kmlOptions);
        },

        init : function (kmlUrl, markerList, interval) {
            google.maps.event.addDomListener(window, 'load',
                    function () {
                        map = layout.initMap();
                        layout.overlayKml(kmlUrl);
                        var markerSet = layout.constructMarkerSet(markerList);
                        layout.moveMarkers(markerSet, interval);
                    });
        }
    };
})();

var processRoute = (function () {
    return {
        parseXml : function (xmlUrl) {
            $.ajax({
                url: xmlUrl,
                dataType: 'xml',
                success : function (data) {
                    var xmlNode = $('Document', data);
                    var lines = new Array();
                    var points = {};

                    xmlNode.find('Placemark > LineString > coordinates').each(function () {
                        lines.push($(this).text());
                    });

                    xmlNode.find('Point').each(function () {
                        parentTag = $(this).closest('Placemark');
                        points[parentTag.find('name').text()] = parentTag.find('Point').text();
                    });
                },
                error : function (data) {
                    console.log('Error');
                }
            });
        }
    };
})();
<|endoftext|>


<commit_before>'use strict';

var generators = require('yeoman-generator');
var mkdirp = require('mkdirp');
var yosay = require('yosay');
var chalk = require('chalk');
var S = require('string');

module.exports = generators.Base.extend({
  _createProjectFileSystem: function() {
    var sourceRoot = this.sourceRoot();
    var componentRoot = this.componentRoot;
    var componentRawName = this.componentName;
    var componentName = S(componentRawName).capitalize().s;
    var templateContext = {
      componentName: componentName,
      componentRawName: componentRawName
    };
    var componentDir = componentRoot + '/' + componentRawName;
    mkdirp(componentRoot + '/' + componentRawName);

    this.fs.copyTpl(sourceRoot + '/_package.json', componentDir + '/package.json', templateContext);
    this.fs.copyTpl(sourceRoot + '/ComponentPage.js', componentDir + '/' + componentRawName + '.js', templateContext);
    this.fs.copyTpl(sourceRoot + '/ComponentPage.scss', componentDir + '/' + componentRawName + '.scss', templateContext);
  },

  constructor: function() {
    generators.Base.apply(this, arguments);

    this.argument('componentName', {
      required: true,
      type: String,
      desc: 'Name of the component',
    });

    this.argument('componentRoot', {
      required: true,
      type: String,
      desc: 'Root of the component',
    });

    this.log('Creating module ' + this.componentName + '.');
  },

  initializing: function() {
    var message = chalk.bgBlack.bold('\nWelcome to React-Vertical Project\n') + chalk.underline('JS React/Flux Compiler\n');
    this.log(yosay(message));
  },

  configuring: function() {
    this.config.save();
  },

  writing: function() {
    this._createProjectFileSystem();
  },
});
<commit_msg>added raw as option, or not as default<commit_after>'use strict';

var generators = require('yeoman-generator');
var mkdirp = require('mkdirp');
var yosay = require('yosay');
var chalk = require('chalk');
var S = require('string');

module.exports = generators.Base.extend({
  _createProjectFileSystem: function() {
    var sourceRoot = this.sourceRoot();
    var componentRoot = this.componentRoot;
    var componentName = S(this.componentName).capitalize().s;
    var componentRawName = this.options.raw ? this.componentName : componentName;
    var templateContext = {
      componentName: componentName,
      componentRawName: componentRawName
    };
    var componentDir = componentRoot + '/' + componentRawName;
    mkdirp(componentRoot + '/' + componentRawName);

    this.fs.copyTpl(sourceRoot + '/_package.json', componentDir + '/package.json', templateContext);
    this.fs.copyTpl(sourceRoot + '/ComponentPage.js', componentDir + '/' + componentRawName + '.js', templateContext);
    this.fs.copyTpl(sourceRoot + '/ComponentPage.scss', componentDir + '/' + componentRawName + '.scss', templateContext);
  },

  constructor: function() {
    generators.Base.apply(this, arguments);

    this.argument('componentName', {
      required: true,
      type: String,
      desc: 'Name of the component',
    });

    this.argument('componentRoot', {
      required: true,
      type: String,
      desc: 'Root of the component',
    });

    this.option('raw');

    this.log('Creating module ' + this.componentName + '.');
  },

  initializing: function() {
    var message = chalk.bgBlack.bold('\nWelcome to React-Vertical Project\n') + chalk.underline('JS React/Flux Compiler\n');
    this.log(yosay(message));
  },

  configuring: function() {
    this.config.save();
  },

  writing: function() {
    this._createProjectFileSystem();
  },
});
<|endoftext|>


<commit_before>module.exports = {
  "globals": {
    "ts-jest": {
      "tsConfigFile": "src/tsconfig.spec.json"
    },
    "__TRANSFORM_HTML__": true
  },
  "transform": {
    "^.+\\.(ts|js|html)$": "<rootDir>/node_modules/jest-preset-angular/preprocessor.js",
    "^.+\\.js$": "babel-jest"
  },
  "testMatch": [
    "**/__tests__/**/*.+(ts|js)?(x)",
    "**/+(*.)+(spec|test).+(ts|js)?(x)"
  ],
  "moduleFileExtensions": [
    "ts",
    "js",
    "html",
    "json"
  ],
  "moduleNameMapper": {
    "#app/(.*)": "<rootDir>/src/app/$1"
  },
  "transformIgnorePatterns": [
    "node_modules/(?!@ngrx|ng2-truncate)"
  ],
  "snapshotSerializers": [
    "<rootDir>/node_modules/jest-preset-angular/AngularSnapshotSerializer.js",
    "<rootDir>/node_modules/jest-preset-angular/HTMLCommentSerializer.js"
  ],
  "preset": "jest-preset-angular",
  "setupTestFrameworkScriptFile": "<rootDir>/src/test.ts"
};
<commit_msg>chore(jest): remove config file from coverage report<commit_after>module.exports = {
  "globals": {
    "ts-jest": {
      "tsConfigFile": "src/tsconfig.spec.json"
    },
    "__TRANSFORM_HTML__": true
  },
  "transform": {
    "^.+\\.(ts|js|html)$": "<rootDir>/node_modules/jest-preset-angular/preprocessor.js",
    "^.+\\.js$": "babel-jest"
  },
  "testMatch": [
    "**/__tests__/**/*.+(ts|js)?(x)",
    "**/+(*.)+(spec|test).+(ts|js)?(x)"
  ],
  "moduleFileExtensions": [
    "ts",
    "js",
    "html",
    "json"
  ],
  "moduleNameMapper": {
    "#app/(.*)": "<rootDir>/src/app/$1"
  },
  "transformIgnorePatterns": [
    "node_modules/(?!@ngrx|ng2-truncate)"
  ],
  "snapshotSerializers": [
    "<rootDir>/node_modules/jest-preset-angular/AngularSnapshotSerializer.js",
    "<rootDir>/node_modules/jest-preset-angular/HTMLCommentSerializer.js"
  ],
  "preset": "jest-preset-angular",
  "setupTestFrameworkScriptFile": "<rootDir>/src/test.ts",
  "coveragePathIgnorePatterns": [
    "/node_modules/",
    "<rootDir>/src/test.ts"
  ]
};
<|endoftext|>


<commit_before>/**
 * @file if 指令节点类
 * @author errorrik(errorrik@gmail.com)
 */

var each = require('../util/each');
var guid = require('../util/guid');
var insertBefore = require('../browser/insert-before');
var evalExpr = require('../runtime/eval-expr');
var NodeType = require('./node-type');
var rinseCondANode = require('./rinse-cond-anode');
var createNode = require('./create-node');
var createReverseNode = require('./create-reverse-node');
var nodeOwnCreateStump = require('./node-own-create-stump');
var elementUpdateChildren = require('./element-update-children');
var nodeOwnSimpleDispose = require('./node-own-simple-dispose');

/**
 * if 指令节点类
 *
 * @param {Object} aNode 抽象节点
 * @param {Component} owner 所属组件环境
 * @param {Model=} scope 所属数据环境
 * @param {Node} parent 父亲节点
 * @param {DOMChildrenWalker?} reverseWalker 子元素遍历对象
 */
function IfNode(aNode, owner, scope, parent, reverseWalker) {
    this.aNode = aNode;
    this.owner = owner;
    this.scope = scope;
    this.parent = parent;
    this.parentComponent = parent.nodeType === NodeType.CMPT
        ? parent
        : parent.parentComponent;

    this.id = guid();
    this.children = [];

    this.cond = this.aNode.directives['if'].value; // eslint-disable-line dot-notation

    // #[begin] reverse
    if (reverseWalker) {
        if (evalExpr(this.cond, this.scope, this.owner)) {
            this.elseIndex = -1;
            this.children[0] = createReverseNode(
                rinseCondANode(aNode),
                reverseWalker,
                this
            );
        }
        else {
            var me = this;
            each(aNode.elses, function (elseANode, index) {
                var elif = elseANode.directives.elif;

                if (!elif || elif && evalExpr(elif.value, me.scope, me.owner)) {
                    me.elseIndex = index;
                    me.children[0] = createReverseNode(
                        rinseCondANode(elseANode),
                        reverseWalker,
                        me
                    );
                    return false;
                }
            });
        }

        this._create();
        insertBefore(this.el, reverseWalker.target, reverseWalker.current);
    }
    // #[end]
}

IfNode.prototype.nodeType = NodeType.IF;

IfNode.prototype._create = nodeOwnCreateStump;
IfNode.prototype.dispose = nodeOwnSimpleDispose;

IfNode.prototype.attach = function (parentEl, beforeEl) {
    var me = this;
    var elseIndex;
    var child;

    if (evalExpr(this.cond, this.scope, this.owner)) {
        child = createNode(rinseCondANode(this.aNode), this);
        elseIndex = -1;
    }
    else {
        each(this.aNode.elses, function (elseANode, index) {
            var elif = elseANode.directives.elif;

            if (!elif || elif && evalExpr(elif.value, me.scope, me.owner)) {
                child = createNode(rinseCondANode(elseANode), me);
                elseIndex = index;
                return false;
            }
        });
    }

    if (child) {
        this.children[0] = child;
        child.attach(parentEl, beforeEl);
        this.elseIndex = elseIndex;
    }

    this._create();
    insertBefore(this.el, parentEl, beforeEl);
};

/**
 * 视图更新函数
 *
 * @param {Array} changes 数据变化信息
 */
IfNode.prototype._update = function (changes) {
    var me = this;
    var childANode = this.aNode;
    var elseIndex;

    if (evalExpr(this.cond, this.scope, this.owner)) {
        elseIndex = -1;
    }
    else {
        each(this.aNode.elses, function (elseANode, index) {
            var elif = elseANode.directives.elif;

            if (elif && evalExpr(elif.value, me.scope, me.owner) || !elif) {
                elseIndex = index;
                childANode = elseANode;
                return false;
            }
        });
    }

    if (elseIndex === this.elseIndex) {
        elementUpdateChildren(this, changes);
    }
    else {
        var child = this.children[0];
        this.children = [];
        if (child) {
            child._ondisposed = newChild;
            child.dispose();
        }
        else {
            newChild();
        }

        this.elseIndex = elseIndex;
    }

    function newChild() {
        if (typeof elseIndex !== 'undefined') {
            (me.children[0] = createNode(rinseCondANode(childANode), me))
                .attach(me.el.parentNode, me.el);
        }
    }
};

exports = module.exports = IfNode;
<commit_msg>add comment<commit_after>/**
 * @file if 指令节点类
 * @author errorrik(errorrik@gmail.com)
 */

var each = require('../util/each');
var guid = require('../util/guid');
var insertBefore = require('../browser/insert-before');
var evalExpr = require('../runtime/eval-expr');
var NodeType = require('./node-type');
var rinseCondANode = require('./rinse-cond-anode');
var createNode = require('./create-node');
var createReverseNode = require('./create-reverse-node');
var nodeOwnCreateStump = require('./node-own-create-stump');
var elementUpdateChildren = require('./element-update-children');
var nodeOwnSimpleDispose = require('./node-own-simple-dispose');

/**
 * if 指令节点类
 *
 * @param {Object} aNode 抽象节点
 * @param {Component} owner 所属组件环境
 * @param {Model=} scope 所属数据环境
 * @param {Node} parent 父亲节点
 * @param {DOMChildrenWalker?} reverseWalker 子元素遍历对象
 */
function IfNode(aNode, owner, scope, parent, reverseWalker) {
    this.aNode = aNode;
    this.owner = owner;
    this.scope = scope;
    this.parent = parent;
    this.parentComponent = parent.nodeType === NodeType.CMPT
        ? parent
        : parent.parentComponent;

    this.id = guid();
    this.children = [];

    this.cond = this.aNode.directives['if'].value; // eslint-disable-line dot-notation

    // #[begin] reverse
    if (reverseWalker) {
        if (evalExpr(this.cond, this.scope, this.owner)) {
            this.elseIndex = -1;
            this.children[0] = createReverseNode(
                rinseCondANode(aNode),
                reverseWalker,
                this
            );
        }
        else {
            var me = this;
            each(aNode.elses, function (elseANode, index) {
                var elif = elseANode.directives.elif;

                if (!elif || elif && evalExpr(elif.value, me.scope, me.owner)) {
                    me.elseIndex = index;
                    me.children[0] = createReverseNode(
                        rinseCondANode(elseANode),
                        reverseWalker,
                        me
                    );
                    return false;
                }
            });
        }

        this._create();
        insertBefore(this.el, reverseWalker.target, reverseWalker.current);
    }
    // #[end]
}

IfNode.prototype.nodeType = NodeType.IF;

IfNode.prototype._create = nodeOwnCreateStump;
IfNode.prototype.dispose = nodeOwnSimpleDispose;

/**
 * attach到页面
 *
 * @param {HTMLElement} parentEl 要添加到的父元素
 * @param {HTMLElement＝} beforeEl 要添加到哪个元素之前
 */
IfNode.prototype.attach = function (parentEl, beforeEl) {
    var me = this;
    var elseIndex;
    var child;

    if (evalExpr(this.cond, this.scope, this.owner)) {
        child = createNode(rinseCondANode(this.aNode), this);
        elseIndex = -1;
    }
    else {
        each(this.aNode.elses, function (elseANode, index) {
            var elif = elseANode.directives.elif;

            if (!elif || elif && evalExpr(elif.value, me.scope, me.owner)) {
                child = createNode(rinseCondANode(elseANode), me);
                elseIndex = index;
                return false;
            }
        });
    }

    if (child) {
        this.children[0] = child;
        child.attach(parentEl, beforeEl);
        this.elseIndex = elseIndex;
    }

    this._create();
    insertBefore(this.el, parentEl, beforeEl);
};

/**
 * 视图更新函数
 *
 * @param {Array} changes 数据变化信息
 */
IfNode.prototype._update = function (changes) {
    var me = this;
    var childANode = this.aNode;
    var elseIndex;

    if (evalExpr(this.cond, this.scope, this.owner)) {
        elseIndex = -1;
    }
    else {
        each(this.aNode.elses, function (elseANode, index) {
            var elif = elseANode.directives.elif;

            if (elif && evalExpr(elif.value, me.scope, me.owner) || !elif) {
                elseIndex = index;
                childANode = elseANode;
                return false;
            }
        });
    }

    if (elseIndex === this.elseIndex) {
        elementUpdateChildren(this, changes);
    }
    else {
        var child = this.children[0];
        this.children = [];
        if (child) {
            child._ondisposed = newChild;
            child.dispose();
        }
        else {
            newChild();
        }

        this.elseIndex = elseIndex;
    }

    function newChild() {
        if (typeof elseIndex !== 'undefined') {
            (me.children[0] = createNode(rinseCondANode(childANode), me))
                .attach(me.el.parentNode, me.el);
        }
    }
};

exports = module.exports = IfNode;
<|endoftext|>


<commit_before>/*global define*/

define([
	'jquery',
	'underscore',
	'handlebars',
	'loomutils/router',
	'epoxy',
	'loomutils/helpers/loader',
	'loomutils/helpers/route-callback',
	'loomutils/models/view'
], function ($, _, Handlebars, router, Epoxy, Loader, RouteCallback, ViewModel) {

	'use strict';

	var V = Epoxy.View.extend({

		/**
		 * Reference to the router
		 * @type {Object}
		 */
		router: router,

		/**
		 * Loader helper
		 * @type {Object}
		 */
		_loader: {},

		/**
		 * Model holds state info we want to be able to trigger events on
		 * @type {Model}
		 */
		viewModel: undefined,

		/**
		 * Default template
		 * @type {Function}
		 */
		template: Handlebars.compile(''),

		/**
		 * Child views
		 * @type {Array}
		 */
		children: [],

		/**
		 * Routes
		 * @type {Object}
		 */
		routes: {},

		/**
		 * Event listeners on objects
		 * @type {Object}
		 */
		listeners: {},

		/**
		 * Initialize
		 */
		initialize: function () {

			// New model instance
			this.viewModel = new ViewModel();

			// Listen to viewModel changes
			this.listenTo(this.viewModel, 'change:active', this.onActiveChange);
			this.listenTo(this.viewModel.get('children'), 'change:active', this.onChildActiveChange);

			// New loader instance
			this._setupLoader();

			// New child model instance
			this._setupChildrenCollection();

			// Add route listeners
			this._setupRoutes();

			// Add object listeners
			this._setupListeners();

			// Listen for load events
			this.on('loaderLoaded childrenLoaded', this.onComponentLoaded);

			// When we render, load the rendered content
			this.on('rendered', this.load);
		},

		/**
		 * Render the view
		 */
		render: function () {

			// Remove event bindings
			this.undelegateEvents();

			// Render the template
			this.$el.html('').append(this.template(this.getData()));

			// Readd events
			this.delegateEvents();

			// Render the children
			this.renderChildren();

			// Apply epoxy view bindings
			this.applyBindings();

			// Dispatch a rendered event
			this.viewModel.set('rendered', true);
			this.trigger('rendered');
		},

		/**
		 * Load assets and dispatch a load event when done
		 */
		load: function () {

			this._loader.addElement(this.$el);
			this._loader.load();
		},

		/**
		 * Route to one of the children
		 * @param {String} id
		 * @param {String} route
		 * @param {Object} params
		 */
		routeTo: function (id, route, params) {

			try {
				var view = this.getChild(id).get('view');
				view.routes[route].call(view, params);
			}
			catch (e) {
				console.log('Failed to route "' + route + '" on child "' + id + '"');
			}
		},

		/**
		 * Render child views
		 */
		renderChildren: function () {

			// Reset the number of children loaded
			this.viewModel.get('children').loadedCount = 0;

			// Loop through all of the children
			this.viewModel.get('children').each(this.renderChild, this);
		},

		/**
		 * Render a child view and append it
		 * @param {Object} child
		 */
		renderChild: function (child) {

			// Get the view
			var view = child.get('view'),
				target = child.get('target');

			// Render the child
			if (!child.get('rendered')) {
				view.render();
			}

			// If we're not loaded yet, wait to add the view until we are
			if (!child.get('loaded')) {
				return this.listenToOnce(child, 'loaded', this.renderChild);
			}

			// Place in the target area if we have one
			if (target) {

				// Are we supposed to replace the target?
				if (child.get('replace')) {
					this.$(target).replaceWith(view.$el);
				}
				else {
					this.$(target).append(view.$el);
				}
			}
			// Fallback placements
			else {

				// Get possible target areas
				var dataTarget = this.$('[data-child-area=' + view.id + ']'),
					childTarget = this.$('.children');

				// Place the child in the right area
				if (dataTarget.length) {
					dataTarget.append(view.$el);
				}
				else if (childTarget.length) {
					childTarget.append(view.$el);
				}
				else {
					this.$el.append(view.$el);
				}
			}
		},

		/**
		 * Get data from our collection or model
		 * @return {Mixed}
		 */
		getData: function () {

			if (this.collection) {
				return this.collection.toJSON();
			}
			else if (this.model) {
				return this.model.toJSON();
			}

			return {};
		},

		/**
		 * Get a child
		 * @param {String} id
		 */
		getChild: function (id) {

			var child = this.viewModel.get('children').get(id);

			return child;
		},

		/**
		 * Show the view
		 */
		show: function () {

			this.viewModel.set('active', true);
			this.$el.addClass('active');
			this.trigger('show');
		},

		/**
		 * Hide the view
		 */
		hide: function () {

			this.viewModel.set('active', false);
			this.$el.removeClass('active');
			this.hideChildren();
			this.trigger('hide');
		},

		/**
		 * Default
		 */
		showDefaultChild: function () {

			var child = this.viewModel.get('children').findWhere({default: true});

			if (child) {
				this.showChild(child);
			}
		},

		/**
		 * Show a child (and hide other) children in that role
		 * @param {Mixed} child
		 */
		showChild: function (id) {

			var child = typeof id !== 'object' ? this.getChild(id) : id;

			child.set('active', true);

			return child.get('view');
		},

		/**
		 * Hide all the children (called when we hide this view)
		 */
		hideChildren: function () {

			this.viewModel.get('children').each(function (child) {
				child.set('active', false);
			});
		},

		/**
		 * When we're done loading assets
		 */
		onLoaderLoaded: function () {

			this.viewModel.get('loadedComponents').loader =true;
			this.trigger('loaderLoaded', this);
		},

		/**
		 * When a child is done loading
		 */
		onChildLoaded: function () {

			this.viewModel.get('children').loadedCount++;

			if (this.viewModel.get('children').loadedCount === this.viewModel.get('children').length) {
				this.viewModel.get('loadedComponents').children = true;
				this.trigger('childrenLoaded', this);
			}
		},

		/**
		 * When any of the components are loaded
		 */
		onComponentLoaded: function () {

			if (_.contains(this.viewModel.get('loadedComponents'), false)) {
				return;
			}

			this.off('loaderLoaded childrenLoaded', this.onComponentLoaded);
			this.viewModel.set('loaded', true);
			this.trigger('loaded');
		},

		/**
		 * When the active viewModel changes
		 */
		onActiveChange: function (viewModel, active) {

			if (active) {
				return this.show();
			}

			this.hide();
		},

		/**
		 * When the active viewModel of a changes
		 */
		onChildActiveChange: function (viewModel, active) {

			// If the child became active, we need to
			// show this view as well
			if (active) {

				// First, hide other children in that region
				if (viewModel.get('role')) {

					var children = this.viewModel.get('children').where({role: viewModel.get('role')});
					_.each(children, function (c) {
						if (c !== viewModel) {
							c.get('view').hide();
						}
					});
				}

				// Show the current view
				this.show();
			}
		},

		/**
		 * Setup route listeners
		 */
		_setupRoutes: function () {

			_.each(this.routes, this._setupRoute, this);
		},

		/**
		 * Setup a route listener
		 * @param {Function} callback
		 * @param {String} route
		 */
		_setupRoute: function (callback, route) {

			// Before and after are not real routes
			if (route === 'before' || route === 'after') {
				return;
			}

			// Add an event to the router with the name of the route
			// and have it trigger an event with the name of the route
			// when that route is called.
			this.router.route(route, route);

			// Get before and after callbacks for the routes
			var beforeCallback = this.routes.before || function() {},
				afterCallback = this.routes.after || function() {};

			// Build the callback
			var routeCallback = new RouteCallback(route, _.bind(beforeCallback, this), _.bind(callback, this), _.bind(afterCallback, this));

			// Add the listener
			this.listenTo(this.router, 'route:' + route, routeCallback);
		},

		/**
		 * Setup listeners
		 */
		_setupListeners: function () {

			_.each(this.listeners, this._setupListenerGroup, this);
		},

		/**
		 * Setup a group of listeners
		 * @param {Object} group
		 * @param {String} name
		 */
		_setupListenerGroup: function (group, name) {

			var obj = name === 'this' ? this : this[name] || undefined;

			if (!obj) {
				return;
			}

			_.each(group, function (methodName, eventName) {
				this._setupListener(obj, eventName, methodName);
			}, this);
		},

		/**
		 * Setup a listener listener
		 * @param {Object} obj
		 * @param {String} eventName
		 * @param {String} methodName
		 */
		_setupListener: function (obj, eventName, methodName) {

			var callback = this[methodName] || undefined;

			if (!callback) {
				return;
			}

			this.listenTo(obj, eventName, callback);
		},

		/**
		 * Setup the asset loader
		 */
		_setupLoader: function () {

			this._loader = new Loader();
			this.listenTo(this._loader, 'loaded', this.onLoaderLoaded);
		},

		/**
		 * Setup the children collection based on the child array of definitions
		 */
		_setupChildrenCollection: function () {

			var childrenCollection = this.viewModel.get('children');

			// New collection listeners
			this.listenTo(childrenCollection, 'loaded', this.onChildLoaded);

			// If there are no children to load, trigger the loaded event now
			if (this.children.length === 0) {
				this.viewModel.get('loadedComponents').children = true;
				this.trigger('childrenLoaded', this);
			}

			// Loop through 'em all, let God sort 'em out
			_.each(this.children, childrenCollection.addFromDefinition, childrenCollection);
		},

		/**
		 * Go back a page
		 */
		back: function () {
			window.history.back();
		}
	});

	return V;
});<commit_msg>nested view called for wrong router<commit_after>/*global define*/

define([
	'jquery',
	'underscore',
	'handlebars',
	'router',
	'epoxy',
	'loomutils/helpers/loader',
	'loomutils/helpers/route-callback',
	'loomutils/models/view'
], function ($, _, Handlebars, router, Epoxy, Loader, RouteCallback, ViewModel) {

	'use strict';

	var V = Epoxy.View.extend({

		/**
		 * Reference to the router
		 * @type {Object}
		 */
		router: router,

		/**
		 * Loader helper
		 * @type {Object}
		 */
		_loader: {},

		/**
		 * Model holds state info we want to be able to trigger events on
		 * @type {Model}
		 */
		viewModel: undefined,

		/**
		 * Default template
		 * @type {Function}
		 */
		template: Handlebars.compile(''),

		/**
		 * Child views
		 * @type {Array}
		 */
		children: [],

		/**
		 * Routes
		 * @type {Object}
		 */
		routes: {},

		/**
		 * Event listeners on objects
		 * @type {Object}
		 */
		listeners: {},

		/**
		 * Initialize
		 */
		initialize: function () {

			// New model instance
			this.viewModel = new ViewModel();

			// Listen to viewModel changes
			this.listenTo(this.viewModel, 'change:active', this.onActiveChange);
			this.listenTo(this.viewModel.get('children'), 'change:active', this.onChildActiveChange);

			// New loader instance
			this._setupLoader();

			// New child model instance
			this._setupChildrenCollection();

			// Add route listeners
			this._setupRoutes();

			// Add object listeners
			this._setupListeners();

			// Listen for load events
			this.on('loaderLoaded childrenLoaded', this.onComponentLoaded);

			// When we render, load the rendered content
			this.on('rendered', this.load);
		},

		/**
		 * Render the view
		 */
		render: function () {

			// Remove event bindings
			this.undelegateEvents();

			// Render the template
			this.$el.html('').append(this.template(this.getData()));

			// Readd events
			this.delegateEvents();

			// Render the children
			this.renderChildren();

			// Apply epoxy view bindings
			this.applyBindings();

			// Dispatch a rendered event
			this.viewModel.set('rendered', true);
			this.trigger('rendered');
		},

		/**
		 * Load assets and dispatch a load event when done
		 */
		load: function () {

			this._loader.addElement(this.$el);
			this._loader.load();
		},

		/**
		 * Route to one of the children
		 * @param {String} id
		 * @param {String} route
		 * @param {Object} params
		 */
		routeTo: function (id, route, params) {

			try {
				var view = this.getChild(id).get('view');
				view.routes[route].call(view, params);
			}
			catch (e) {
				console.log('Failed to route "' + route + '" on child "' + id + '"');
			}
		},

		/**
		 * Render child views
		 */
		renderChildren: function () {

			// Reset the number of children loaded
			this.viewModel.get('children').loadedCount = 0;

			// Loop through all of the children
			this.viewModel.get('children').each(this.renderChild, this);
		},

		/**
		 * Render a child view and append it
		 * @param {Object} child
		 */
		renderChild: function (child) {

			// Get the view
			var view = child.get('view'),
				target = child.get('target');

			// Render the child
			if (!child.get('rendered')) {
				view.render();
			}

			// If we're not loaded yet, wait to add the view until we are
			if (!child.get('loaded')) {
				return this.listenToOnce(child, 'loaded', this.renderChild);
			}

			// Place in the target area if we have one
			if (target) {

				// Are we supposed to replace the target?
				if (child.get('replace')) {
					this.$(target).replaceWith(view.$el);
				}
				else {
					this.$(target).append(view.$el);
				}
			}
			// Fallback placements
			else {

				// Get possible target areas
				var dataTarget = this.$('[data-child-area=' + view.id + ']'),
					childTarget = this.$('.children');

				// Place the child in the right area
				if (dataTarget.length) {
					dataTarget.append(view.$el);
				}
				else if (childTarget.length) {
					childTarget.append(view.$el);
				}
				else {
					this.$el.append(view.$el);
				}
			}
		},

		/**
		 * Get data from our collection or model
		 * @return {Mixed}
		 */
		getData: function () {

			if (this.collection) {
				return this.collection.toJSON();
			}
			else if (this.model) {
				return this.model.toJSON();
			}

			return {};
		},

		/**
		 * Get a child
		 * @param {String} id
		 */
		getChild: function (id) {

			var child = this.viewModel.get('children').get(id);

			return child;
		},

		/**
		 * Show the view
		 */
		show: function () {

			this.viewModel.set('active', true);
			this.$el.addClass('active');
			this.trigger('show');
		},

		/**
		 * Hide the view
		 */
		hide: function () {

			this.viewModel.set('active', false);
			this.$el.removeClass('active');
			this.hideChildren();
			this.trigger('hide');
		},

		/**
		 * Default
		 */
		showDefaultChild: function () {

			var child = this.viewModel.get('children').findWhere({default: true});

			if (child) {
				this.showChild(child);
			}
		},

		/**
		 * Show a child (and hide other) children in that role
		 * @param {Mixed} child
		 */
		showChild: function (id) {

			var child = typeof id !== 'object' ? this.getChild(id) : id;

			child.set('active', true);

			return child.get('view');
		},

		/**
		 * Hide all the children (called when we hide this view)
		 */
		hideChildren: function () {

			this.viewModel.get('children').each(function (child) {
				child.set('active', false);
			});
		},

		/**
		 * When we're done loading assets
		 */
		onLoaderLoaded: function () {

			this.viewModel.get('loadedComponents').loader =true;
			this.trigger('loaderLoaded', this);
		},

		/**
		 * When a child is done loading
		 */
		onChildLoaded: function () {

			this.viewModel.get('children').loadedCount++;

			if (this.viewModel.get('children').loadedCount === this.viewModel.get('children').length) {
				this.viewModel.get('loadedComponents').children = true;
				this.trigger('childrenLoaded', this);
			}
		},

		/**
		 * When any of the components are loaded
		 */
		onComponentLoaded: function () {

			if (_.contains(this.viewModel.get('loadedComponents'), false)) {
				return;
			}

			this.off('loaderLoaded childrenLoaded', this.onComponentLoaded);
			this.viewModel.set('loaded', true);
			this.trigger('loaded');
		},

		/**
		 * When the active viewModel changes
		 */
		onActiveChange: function (viewModel, active) {

			if (active) {
				return this.show();
			}

			this.hide();
		},

		/**
		 * When the active viewModel of a changes
		 */
		onChildActiveChange: function (viewModel, active) {

			// If the child became active, we need to
			// show this view as well
			if (active) {

				// First, hide other children in that region
				if (viewModel.get('role')) {

					var children = this.viewModel.get('children').where({role: viewModel.get('role')});
					_.each(children, function (c) {
						if (c !== viewModel) {
							c.get('view').hide();
						}
					});
				}

				// Show the current view
				this.show();
			}
		},

		/**
		 * Setup route listeners
		 */
		_setupRoutes: function () {

			_.each(this.routes, this._setupRoute, this);
		},

		/**
		 * Setup a route listener
		 * @param {Function} callback
		 * @param {String} route
		 */
		_setupRoute: function (callback, route) {

			// Before and after are not real routes
			if (route === 'before' || route === 'after') {
				return;
			}

			// Add an event to the router with the name of the route
			// and have it trigger an event with the name of the route
			// when that route is called.
			this.router.route(route, route);

			// Get before and after callbacks for the routes
			var beforeCallback = this.routes.before || function() {},
				afterCallback = this.routes.after || function() {};

			// Build the callback
			var routeCallback = new RouteCallback(route, _.bind(beforeCallback, this), _.bind(callback, this), _.bind(afterCallback, this));

			// Add the listener
			this.listenTo(this.router, 'route:' + route, routeCallback);
		},

		/**
		 * Setup listeners
		 */
		_setupListeners: function () {

			_.each(this.listeners, this._setupListenerGroup, this);
		},

		/**
		 * Setup a group of listeners
		 * @param {Object} group
		 * @param {String} name
		 */
		_setupListenerGroup: function (group, name) {

			var obj = name === 'this' ? this : this[name] || undefined;

			if (!obj) {
				return;
			}

			_.each(group, function (methodName, eventName) {
				this._setupListener(obj, eventName, methodName);
			}, this);
		},

		/**
		 * Setup a listener listener
		 * @param {Object} obj
		 * @param {String} eventName
		 * @param {String} methodName
		 */
		_setupListener: function (obj, eventName, methodName) {

			var callback = this[methodName] || undefined;

			if (!callback) {
				return;
			}

			this.listenTo(obj, eventName, callback);
		},

		/**
		 * Setup the asset loader
		 */
		_setupLoader: function () {

			this._loader = new Loader();
			this.listenTo(this._loader, 'loaded', this.onLoaderLoaded);
		},

		/**
		 * Setup the children collection based on the child array of definitions
		 */
		_setupChildrenCollection: function () {

			var childrenCollection = this.viewModel.get('children');

			// New collection listeners
			this.listenTo(childrenCollection, 'loaded', this.onChildLoaded);

			// If there are no children to load, trigger the loaded event now
			if (this.children.length === 0) {
				this.viewModel.get('loadedComponents').children = true;
				this.trigger('childrenLoaded', this);
			}

			// Loop through 'em all, let God sort 'em out
			_.each(this.children, childrenCollection.addFromDefinition, childrenCollection);
		},

		/**
		 * Go back a page
		 */
		back: function () {
			window.history.back();
		}
	});

	return V;
});<|endoftext|>


<commit_before>
(function() {

// map zoom control
cdb.vis.Overlay.register('zoom', function(data) {

  var zoom = new cdb.geo.ui.Zoom({
    model: data.map,
    template: cdb.core.Template.compile(data.template)
  });

  return zoom.render();
});

// Tiles loader
cdb.vis.Overlay.register('loader', function(data) {

  var tilesLoader = new cdb.admin.TilesLoader({
    template: cdb.core.Template.compile(data.template)
  });

  return tilesLoader.render();
});

// Header to show informtion (title and description)
cdb.vis.Overlay.register('header', function(data, vis) {

  // Add the complete url for facebook and twitter
  if (location.href) {
    data.url = encodeURIComponent(location.href);
  }

  var template = cdb.core.Template.compile(
    data.template || "\
      {{#title}}
{{title}}
{{/title}}\
      {{#description}}
{{description}}
{{/description}}\
      {{#shareable}}
FT
{{/shareable}}\
    ",
    data.templateType || 'mustache'
  );

  var header = new cdb.geo.ui.Header({
    title: data.map.get('title'),
    description: data.map.get('description'),
    url: data.url,
    shareable: (data.shareable == "false" || !data.shareable) ? null : data.shareable,
    template: template
  });

  return header.render();
});

// infowindow
cdb.vis.Overlay.register('infowindow', function(data, vis) {

  var infowindowModel = new cdb.geo.ui.InfowindowModel({
    fields: data.fields
  });

  var templateType = data.templateType || 'mustache';

  var infowindow = new cdb.geo.ui.Infowindow({
     model: infowindowModel,
     mapView: vis.mapView,
     template: new cdb.core.Template({ template: data.template, type: templateType}).asFunction()
  });

  return infowindow;
});

// search content
cdb.vis.Overlay.register('search', function(data, vis) {

  var template = cdb.core.Template.compile(
    data.template || '\
      <form>\
        <input type="text" class="text" value="" />\
        <input type="submit" class="submit" value="" />\
      </form>\
    ',
    data.templateType || 'mustache'
  );

  var search = new cdb.geo.ui.Search({
    template: template,
    model: vis.map
  });

  return search.render();
});

})();
<commit_msg>two urls for embed map, one for public table and another for sharing, share_url<commit_after>
(function() {

// map zoom control
cdb.vis.Overlay.register('zoom', function(data) {

  var zoom = new cdb.geo.ui.Zoom({
    model: data.map,
    template: cdb.core.Template.compile(data.template)
  });

  return zoom.render();
});

// Tiles loader
cdb.vis.Overlay.register('loader', function(data) {

  var tilesLoader = new cdb.admin.TilesLoader({
    template: cdb.core.Template.compile(data.template)
  });

  return tilesLoader.render();
});

// Header to show informtion (title and description)
cdb.vis.Overlay.register('header', function(data, vis) {

  // Add the complete url for facebook and twitter
  if (location.href) {
    data.share_url = encodeURIComponent(location.href);
  } else {
    data.share_url = data.url;
  }

  var template = cdb.core.Template.compile(
    data.template || "\
      {{#title}}
{{title}}
{{/title}}\
      {{#description}}
{{description}}
{{/description}}\
      {{#shareable}}
FT
{{/shareable}}\
    ",
    data.templateType || 'mustache'
  );

  var header = new cdb.geo.ui.Header({
    title: data.map.get('title'),
    description: data.map.get('description'),
    url: data.url,
    share_url: data.share_url,
    shareable: (data.shareable == "false" || !data.shareable) ? null : data.shareable,
    template: template
  });

  return header.render();
});

// infowindow
cdb.vis.Overlay.register('infowindow', function(data, vis) {

  var infowindowModel = new cdb.geo.ui.InfowindowModel({
    fields: data.fields
  });

  var templateType = data.templateType || 'mustache';

  var infowindow = new cdb.geo.ui.Infowindow({
     model: infowindowModel,
     mapView: vis.mapView,
     template: new cdb.core.Template({ template: data.template, type: templateType}).asFunction()
  });

  return infowindow;
});

// search content
cdb.vis.Overlay.register('search', function(data, vis) {

  var template = cdb.core.Template.compile(
    data.template || '\
      <form>\
        <input type="text" class="text" value="" />\
        <input type="submit" class="submit" value="" />\
      </form>\
    ',
    data.templateType || 'mustache'
  );

  var search = new cdb.geo.ui.Search({
    template: template,
    model: vis.map
  });

  return search.render();
});

})();
<|endoftext|>


<commit_before>import {navigate} from '../services/navigation'
import {getDistance, getHeading} from '../helpers/geo'
export const GETTING_LOCATION = 'GETTING_LOCATION'
export const LOCATION_UPDATED = 'LOCATION_UPDATED'
export const GEO_ERROR = 'GEO_ERROR'
export const SET_TRIP = 'SET_TRIP'
export const START_TRIP = 'START_TRIP'

export const getLocation = () => {
  return (dispatch, getState) => {
    dispatch({
      type: GETTING_LOCATION,
    })
    const err = (msg) => {
      console.log("### ERROR")
      console.log(msg)
    }
    const success = (position) => {
      const {latitude, longitude, speed} = position.coords
      let newPosition = {
        type: LOCATION_UPDATED,
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
      }
      let prevLatitude = getState().get('geo').get('latitude')
      let prevLongitude = getState().get('geo').get('longitude')
      if (speed) {
        newPosition.speed = speed
      }
      if (prevLatitude && prevLongitude) {
        newPosition.heading = getHeading(latitude, longitude, prevLatitude, prevLongitude)
      }
      console.log(newPosition)
      dispatch(newPosition)
    }
    const watchPositionOptions = {
      enableHighAccuracy: true,
      timeout: 3000,
    }
    if (navigator.geolocation) {
      navigator.geolocation.watchPosition(success, err, watchPositionOptions)
    } else {
      dispatch({
        type: GEO_ERROR,
        message: 'No Geo Location Permissions',
      })
    }
  }
}

export const setTrip = (distance, duration, tripSteps) => {
  const heading = tripSteps[0].heading
  return (dispatch, getState) => {
    dispatch({
      type: SET_TRIP,
      distance,
      duration,
      tripSteps,
      heading: tripSteps[0].heading,
      destinationLoaded: true,
    })
  }
}

export const startTrip = () => {
  return (dispatch, getState) => {
    dispatch({
      type: START_TRIP,
    })
  }
}
<commit_msg>flip it up<commit_after>import {navigate} from '../services/navigation'
import {getDistance, getHeading} from '../helpers/geo'
export const GETTING_LOCATION = 'GETTING_LOCATION'
export const LOCATION_UPDATED = 'LOCATION_UPDATED'
export const GEO_ERROR = 'GEO_ERROR'
export const SET_TRIP = 'SET_TRIP'
export const START_TRIP = 'START_TRIP'

export const getLocation = () => {
  return (dispatch, getState) => {
    dispatch({
      type: GETTING_LOCATION,
    })
    const err = (msg) => {
      console.log("### ERROR")
      console.log(msg)
    }
    const success = (position) => {
      const {latitude, longitude, speed} = position.coords
      let newPosition = {
        type: LOCATION_UPDATED,
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
      }
      let prevLatitude = getState().get('geo').get('latitude')
      let prevLongitude = getState().get('geo').get('longitude')
      if (speed) {
        newPosition.speed = speed
      }
      if (prevLatitude && prevLongitude) {
        newPosition.heading = getHeading(prevLatitude, prevLongitude, latitude, longitude)
      }
      console.log(newPosition)
      dispatch(newPosition)
    }
    const watchPositionOptions = {
      enableHighAccuracy: true,
      timeout: 3000,
    }
    if (navigator.geolocation) {
      navigator.geolocation.watchPosition(success, err, watchPositionOptions)
    } else {
      dispatch({
        type: GEO_ERROR,
        message: 'No Geo Location Permissions',
      })
    }
  }
}

export const setTrip = (distance, duration, tripSteps) => {
  const heading = tripSteps[0].heading
  return (dispatch, getState) => {
    dispatch({
      type: SET_TRIP,
      distance,
      duration,
      tripSteps,
      heading: tripSteps[0].heading,
      destinationLoaded: true,
    })
  }
}

export const startTrip = () => {
  return (dispatch, getState) => {
    dispatch({
      type: START_TRIP,
    })
  }
}
<|endoftext|>


<commit_before>import Cycle from '@cycle/core';
import {makeDOMDriver, div, button, select, option, label} from '@cycle/dom';
import moment from 'moment';
import {Observable} from 'rx';
import R from 'ramda';

import {makeTrelloDriver} from './drivers/trello';
import {makeGraphDriver} from './drivers/graph';
import logDriver from './drivers/log';

import {parseActions, getDisplayedLists} from './models/trello';
import {parseTrelloData} from './models/graph';

function selectView ( id, labelText, selected, values ) {
  return div( [
    label( { htmlFor: id }, labelText ),
    select(
      { id: id, name: id },
      [ R.map( value => R.cond( [
        [ R.equals( selected ), R.always( option( { selected: true }, value ) ) ],
        [ R.T, R.always( option( value ) ) ]
      ] )( value ), values ) ]
    )
  ] );
}

function main ( { DOM, Trello } ) {
  // TODO - refactor these with components (button, select, trello)
  const buttonClicks$ = DOM
    .select( 'button' )
    .events( 'click' )
    .startWith( false );

  const firstDisplayedListChanges$ = DOM
    .select( '#first-displayed-list' )
    .events( 'input' )
    .map( ev => ev.target.value )
    .startWith( "Backlog" );

  const lastDisplayedListChanges$ = DOM
    .select( '#last-displayed-list' )
    .events( 'input' )
    .map( ev => ev.target.value )
    .startWith( false );

  const trelloLists$ = Trello.lists$.startWith( [] );

  const trelloActions$ = Observable.combineLatest(
    trelloLists$,
    Trello.actions$.startWith( [] ),
    parseActions( moment().format( 'YYYY-MM-DD' ) )
  );

  const displayedLists$ = Observable.combineLatest(
    trelloLists$,
    firstDisplayedListChanges$,
    lastDisplayedListChanges$,
    getDisplayedLists
  );

  const lists$ = trelloLists$.map( R.map( R.propOr( "", "name" ) ) );

  return {
    DOM: Observable.combineLatest(
      lists$,
      displayedLists$,
      ( lists, displayedLists ) =>
        div( [
          button( 'Get actions' ),
          selectView(
            'first-displayed-list',
            'Work begins',
            R.head( displayedLists ),
            lists
          ),
          selectView(
            'last-displayed-list',
            'Work ends',
            R.last( displayedLists ),
            lists
          )
        ] )
    ),
    Trello: buttonClicks$,
    graph: Observable.combineLatest(
      displayedLists$,
      trelloActions$,
      parseTrelloData
    ),
    log: trelloLists$
  };
}

const drivers = {
  DOM: makeDOMDriver( '#app' ),
  Trello: makeTrelloDriver(),
  graph: makeGraphDriver( '#chart svg' ),
  log: logDriver
};

Cycle.run( main, drivers );
<commit_msg>Limit analysis to current month by default<commit_after>import Cycle from '@cycle/core';
import {makeDOMDriver, div, button, select, option, label} from '@cycle/dom';
import moment from 'moment';
import {Observable} from 'rx';
import R from 'ramda';

import {makeTrelloDriver} from './drivers/trello';
import {makeGraphDriver} from './drivers/graph';
import logDriver from './drivers/log';

import {parseActions, getDisplayedLists} from './models/trello';
import {parseTrelloData} from './models/graph';

import {filterAfterDate} from './utils/utils';

function selectView ( id, labelText, selected, values ) {
  return div( [
    label( { htmlFor: id }, labelText ),
    select(
      { id: id, name: id },
      [ R.map( value => R.cond( [
        [ R.equals( selected ), R.always( option( { selected: true }, value ) ) ],
        [ R.T, R.always( option( value ) ) ]
      ] )( value ), values ) ]
    )
  ] );
}

function main ( { DOM, Trello } ) {
  // TODO - refactor these with components (button, select, trello)
  const buttonClicks$ = DOM
    .select( 'button' )
    .events( 'click' )
    .startWith( false );

  const firstDisplayedListChanges$ = DOM
    .select( '#first-displayed-list' )
    .events( 'input' )
    .map( ev => ev.target.value )
    .startWith( "Backlog" );

  const lastDisplayedListChanges$ = DOM
    .select( '#last-displayed-list' )
    .events( 'input' )
    .map( ev => ev.target.value )
    .startWith( false );

  const trelloLists$ = Trello.lists$.startWith( [] );
  const trelloActions$ = Trello.actions$
    .map( filterAfterDate( moment().date( 1 ).format( 'YYYY-MM-DD' ) ) )
    .startWith( [] );

  const actions$ = Observable.combineLatest(
    trelloLists$,
    trelloActions$,
    parseActions( moment().format( 'YYYY-MM-DD' ) )
  );

  const displayedLists$ = Observable.combineLatest(
    trelloLists$,
    firstDisplayedListChanges$,
    lastDisplayedListChanges$,
    getDisplayedLists
  );

  const lists$ = trelloLists$.map( R.map( R.propOr( "", "name" ) ) );

  return {
    DOM: Observable.combineLatest(
      lists$,
      displayedLists$,
      ( lists, displayedLists ) =>
        div( [
          button( 'Get actions' ),
          selectView(
            'first-displayed-list',
            'Work begins',
            R.head( displayedLists ),
            lists
          ),
          selectView(
            'last-displayed-list',
            'Work ends',
            R.last( displayedLists ),
            lists
          )
        ] )
    ),
    Trello: buttonClicks$,
    graph: Observable.combineLatest(
      displayedLists$,
      actions$,
      parseTrelloData
    ),
    log: trelloLists$
  };
}

const drivers = {
  DOM: makeDOMDriver( '#app' ),
  Trello: makeTrelloDriver(),
  graph: makeGraphDriver( '#chart svg' ),
  log: logDriver
};

Cycle.run( main, drivers );
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');

var pg = require('pg');
var db = db || 'marvel';
var url = process.env.DATABASE_URL || `postgres://localhost:5432/${db}`;

function query (sql, paramsOrCb, cb) {
  pg.connect(url, function (err, db, done) {
    if (err) throw err;

    if (typeof paramsOrCb === 'function') {
      db.query(sql, function (err, res) {
        paramsOrCb(err, res.rows);
      });
    } else {
      db.query(sql, paramsOrCb, function (err, res) {
        cb(err, res.rows);
      });
    }

    done();

  });
};

function Card() {};

Card.findAll = function (cb) {
  query('SELECT * FROM characters INNER JOIN images ON (characters.characterid = images.characterid) INNER JOIN attack ON (characters.characterid = attack.characterid) INNER JOIN defense ON (characters.characterid = defense.characterid);', function (err, cards) {
    if (err) throw err;
    var prototypedOrders = cards.map(function (card) {
      return setPrototype(card);
    });

    cb(err, prototypedOrders);
  });
};

// Card.findById = function (id, cb) {
//   query('SELECT * FROM characters INNER JOIN images ON (characters.characterid = images.characterid) INNER JOIN attack ON (characters.characterid = attack.characterid) INNER JOIN defense ON (characters.characterid = defense.characterid) WHERE id = characters.characterid;')
// };

module.exports = Card;

function setPrototype(pojo) {
  return _.create(Card.prototype, pojo);
}

<commit_msg>debugging<commit_after>'use strict';

var _ = require('lodash');

var pg = require('pg');
var db = db || 'marvel';
var url = process.env.DATABASE_URL || `postgres://localhost:5432/${db}`;

function query (sql, paramsOrCb, cb) {
  pg.connect(url, function (err, db, done) {
    console.log(url)
    if (err) throw err;

    if (typeof paramsOrCb === 'function') {
      db.query(sql, function (err, res) {
        paramsOrCb(err, res.rows);
      });
    } else {
      db.query(sql, paramsOrCb, function (err, res) {
        cb(err, res.rows);
      });
    }

    done();

  });
};

function Card() {};

Card.findAll = function (cb) {
  query('SELECT * FROM characters INNER JOIN images ON (characters.characterid = images.characterid) INNER JOIN attack ON (characters.characterid = attack.characterid) INNER JOIN defense ON (characters.characterid = defense.characterid);', function (err, cards) {
    if (err) throw err;
    var prototypedOrders = cards.map(function (card) {
      return setPrototype(card);
    });

    cb(err, prototypedOrders);
  });
};

// Card.findById = function (id, cb) {
//   query('SELECT * FROM characters INNER JOIN images ON (characters.characterid = images.characterid) INNER JOIN attack ON (characters.characterid = attack.characterid) INNER JOIN defense ON (characters.characterid = defense.characterid) WHERE id = characters.characterid;')
// };

module.exports = Card;

function setPrototype(pojo) {
  return _.create(Card.prototype, pojo);
}

<|endoftext|>