<commit_before>var utils = require('../utils');
var Token = require('../utils/Token.js');
var socketIO = require('socket.io-client');
var clients = Object.create(null);
var DEBUG = false;

function valuesChanged(a, b) {
    for (var key in a) {
        var value1 = a[key];
        var value2 = b[key];

        if (Array.isArray(value1)) {
            if (valuesChanged(value1, value2)) {
                return true;
            }
        } else {
            if (String(value1) !== String(value2)) {
                return true;
            }
        }
    }

    return false;
}

function onConnect() {
    clearInterval(this.sendInfoTimer);

    this.isOnline.set(true);
    this.clientInfo = this.getInfo();

    this.send('rempl:client connect', this.clientInfo, function(data) {
        if ('clientId' in data) {
            this.setClientId(data.clientId);
        }

        this.sendInfoTimer = setInterval(this.sendInfo.bind(this), this.sendInfoTimerTTL);
    }.bind(this));

    if (DEBUG) {
        console.log('[rempl][ws-transport] connected');
    }
}

function onGetUI(id, settings, callback) {
    if (!this.publishersMap.hasOwnProperty(id)) {
        if (DEBUG) {
            console.error('[rempl][ws-transport] Publisher `' + id + '` isn\'t registered on page');
        }

        callback('[rempl][ws-transport] Publisher `' + id + '` isn\'t registered on page');
        return;
    }

    this.publishersMap[id].getRemoteUI.call(null, settings, callback);
}

function onData(id) {
    if (!this.publishersMap.hasOwnProperty(id)) {
        if (DEBUG) {
            console.error('[rempl][ws-transport] Publisher `' + id + '` isn\'t registered on page');
        }

        return;
    }

    var subscribers = this.publishersMap[id].subscribers;
    var args = Array.prototype.slice.call(arguments, 1);

    for (var i = 0; i < subscribers.length; i++) {
        subscribers[i].apply(null, args);
    }
}

function onDisconnect() {
    if (DEBUG) {
        console.log('[rempl] disconnected');
    }

    this.isOnline.set(false);
    this.setFeatures([]);

    clearInterval(this.sendInfoTimer);
    this.stopIdentify();
}

function WSTransport(uri) {
    this.sessionId = utils.genUID();
    this.clientId = null;

    this.clientInfo = {};
    this.publishers = [];
    this.publishersMap = {};

    this.sendInfoTimer = null;
    this.sendInfoTimerTTL = 150;

    this.isOnline = new Token(false);
    this.features = [];

    this.transport = socketIO.connect(uri)
        .on('connect', onConnect.bind(this))
        .on('disconnect', onDisconnect.bind(this))
        .on('features', this.setFeatures.bind(this))

        .on('rempl:get ui', onGetUI.bind(this))
        .on('rempl:to session', onData.bind(this))

        .on('rempl:identify', this.startIdentify.bind(this))
        .on('rempl:stop identify', this.stopIdentify.bind(this));
}

WSTransport.create = function(endpoint) {
    if (endpoint in clients) {
        return clients[endpoint];
    }

    return clients[endpoint] = new WSTransport(endpoint);
};

WSTransport.prototype.type = 'unknown';
WSTransport.prototype.clientInfoFields = [
    'clientId',
    'sessionId',
    'type',
    'features',
    'publishers'
];

WSTransport.prototype.setClientId = function(clientId) {
    this.clientId = clientId;
};

/**
 * Send data through WS
 */
WSTransport.prototype.send = function() {
    this.transport.emit.apply(this.transport, arguments);
};

/**
 * Get self info
 * @returns Object
 */
WSTransport.prototype.getInfo = function() {
    var result = {};

    this.clientInfoFields.forEach(function(name) {
        result[name] = Array.isArray(this[name]) ? this[name].slice() : this[name];
    }, this);

    return result;
    return {
        clientId: this.clientId,
        sessionId: this.sessionId,
        title: this.name,
        pid: process.pid,
        type: 'node',
        features: this.features.slice(),
        publishers: this.publishers.slice()
    };
};

/**
 * Send self info to server
 */
WSTransport.prototype.sendInfo = function() {
    var newInfo = this.getInfo();

    if (valuesChanged(this.clientInfo, newInfo)) {
        this.clientInfo = newInfo;
        this.send('rempl:client info', this.clientInfo);
    }
};

/**
 * Set features for this client
 *
 * @param {Array<string>} list
 */
WSTransport.prototype.setFeatures = function(list) {
    this.features = Array.prototype.slice.call(list || []);
    this.sendInfo();
};

WSTransport.prototype.startIdentify = function() {
    if (DEBUG) {
        console.error('[rempl] #startIdentify not implemented');
    }
};

WSTransport.prototype.stopIdentify = function() {
    if (DEBUG) {
        console.error('[rempl] #stopIdentify not implemented');
    }
};

WSTransport.prototype.createApi = function(id, getRemoteUI) {
    var subscribers = [];

    if (this.publishersMap.hasOwnProperty(id)) {
        if (DEBUG) {
            console.error('[rempl][ws-transport] Publisher `' + id + '` is already registered on page');
        }

        return;
    }

    this.publishers.push(id);
    this.publishersMap[id] = {
        getRemoteUI: getRemoteUI,
        subscribers: subscribers
    };

    this.sendInfo();

    return {
        connected: this.isOnline,
        setFeatures: function(list) {
            this.setFeatures(list);
        }.bind(this),
        send: function() {
            this.transport.emit.apply(this.transport, ['rempl:client data', id].concat(
                Array.prototype.slice.call(arguments)
            ));
        }.bind(this),
        subscribe: function(fn) {
            subscribers.push(fn);
        }
    };
};

module.exports = WSTransport;
<commit_msg>fix unreachable code<commit_after>var utils = require('../utils');
var Token = require('../utils/Token.js');
var socketIO = require('socket.io-client');
var clients = Object.create(null);
var DEBUG = false;

function valuesChanged(a, b) {
    for (var key in a) {
        var value1 = a[key];
        var value2 = b[key];

        if (Array.isArray(value1)) {
            if (valuesChanged(value1, value2)) {
                return true;
            }
        } else {
            if (String(value1) !== String(value2)) {
                return true;
            }
        }
    }

    return false;
}

function onConnect() {
    clearInterval(this.sendInfoTimer);

    this.isOnline.set(true);
    this.clientInfo = this.getInfo();

    this.send('rempl:client connect', this.clientInfo, function(data) {
        if ('clientId' in data) {
            this.setClientId(data.clientId);
        }

        this.sendInfoTimer = setInterval(this.sendInfo.bind(this), this.sendInfoTimerTTL);
    }.bind(this));

    if (DEBUG) {
        console.log('[rempl][ws-transport] connected');
    }
}

function onGetUI(id, settings, callback) {
    if (!this.publishersMap.hasOwnProperty(id)) {
        if (DEBUG) {
            console.error('[rempl][ws-transport] Publisher `' + id + '` isn\'t registered on page');
        }

        callback('[rempl][ws-transport] Publisher `' + id + '` isn\'t registered on page');
        return;
    }

    this.publishersMap[id].getRemoteUI.call(null, settings, callback);
}

function onData(id) {
    if (!this.publishersMap.hasOwnProperty(id)) {
        if (DEBUG) {
            console.error('[rempl][ws-transport] Publisher `' + id + '` isn\'t registered on page');
        }

        return;
    }

    var subscribers = this.publishersMap[id].subscribers;
    var args = Array.prototype.slice.call(arguments, 1);

    for (var i = 0; i < subscribers.length; i++) {
        subscribers[i].apply(null, args);
    }
}

function onDisconnect() {
    if (DEBUG) {
        console.log('[rempl] disconnected');
    }

    this.isOnline.set(false);
    this.setFeatures([]);

    clearInterval(this.sendInfoTimer);
    this.stopIdentify();
}

function WSTransport(uri) {
    this.sessionId = utils.genUID();
    this.clientId = null;

    this.clientInfo = {};
    this.publishers = [];
    this.publishersMap = {};

    this.sendInfoTimer = null;
    this.sendInfoTimerTTL = 150;

    this.isOnline = new Token(false);
    this.features = [];

    this.transport = socketIO.connect(uri)
        .on('connect', onConnect.bind(this))
        .on('disconnect', onDisconnect.bind(this))
        .on('features', this.setFeatures.bind(this))

        .on('rempl:get ui', onGetUI.bind(this))
        .on('rempl:to session', onData.bind(this))

        .on('rempl:identify', this.startIdentify.bind(this))
        .on('rempl:stop identify', this.stopIdentify.bind(this));
}

WSTransport.create = function(endpoint) {
    if (endpoint in clients) {
        return clients[endpoint];
    }

    return clients[endpoint] = new WSTransport(endpoint);
};

WSTransport.prototype.type = 'unknown';
WSTransport.prototype.clientInfoFields = [
    'clientId',
    'sessionId',
    'type',
    'features',
    'publishers'
];

WSTransport.prototype.setClientId = function(clientId) {
    this.clientId = clientId;
};

/**
 * Send data through WS
 */
WSTransport.prototype.send = function() {
    this.transport.emit.apply(this.transport, arguments);
};

/**
 * Get self info
 * @returns Object
 */
WSTransport.prototype.getInfo = function() {
    var result = {};

    this.clientInfoFields.forEach(function(name) {
        result[name] = Array.isArray(this[name]) ? this[name].slice() : this[name];
    }, this);

    return result;
};

/**
 * Send self info to server
 */
WSTransport.prototype.sendInfo = function() {
    var newInfo = this.getInfo();

    if (valuesChanged(this.clientInfo, newInfo)) {
        this.clientInfo = newInfo;
        this.send('rempl:client info', this.clientInfo);
    }
};

/**
 * Set features for this client
 *
 * @param {Array<string>} list
 */
WSTransport.prototype.setFeatures = function(list) {
    this.features = Array.prototype.slice.call(list || []);
    this.sendInfo();
};

WSTransport.prototype.startIdentify = function() {
    if (DEBUG) {
        console.error('[rempl] #startIdentify not implemented');
    }
};

WSTransport.prototype.stopIdentify = function() {
    if (DEBUG) {
        console.error('[rempl] #stopIdentify not implemented');
    }
};

WSTransport.prototype.createApi = function(id, getRemoteUI) {
    var subscribers = [];

    if (this.publishersMap.hasOwnProperty(id)) {
        if (DEBUG) {
            console.error('[rempl][ws-transport] Publisher `' + id + '` is already registered on page');
        }

        return;
    }

    this.publishers.push(id);
    this.publishersMap[id] = {
        getRemoteUI: getRemoteUI,
        subscribers: subscribers
    };

    this.sendInfo();

    return {
        connected: this.isOnline,
        setFeatures: function(list) {
            this.setFeatures(list);
        }.bind(this),
        send: function() {
            this.transport.emit.apply(this.transport, ['rempl:client data', id].concat(
                Array.prototype.slice.call(arguments)
            ));
        }.bind(this),
        subscribe: function(fn) {
            subscribers.push(fn);
        }
    };
};

module.exports = WSTransport;
<|endoftext|>


<commit_before>// based on THREE.CSS3DRenderer from https://github.com/mrdoob/three.js/blob/51ac0084709d4d3795ccb7119ee24e6a808618df/examples/js/renderers/CSS3DRenderer.js

import * as THREE from 'three'

export function CSS3DObjectNested( element ) {

	THREE.Object3D.call( this );

	this.element = element;

	requestAnimationFrame( () => {

    	// delay to the next frame because attributes are not allowed be set
    	// inside Custom Element constructors (i.e. when using Web Components
    	// APIs) otherwise this throws an error.

    	this.element.style.position = 'absolute';

	} );

};

CSS3DObjectNested.prototype = Object.create( THREE.Object3D.prototype );
CSS3DObjectNested.prototype.constructor = CSS3DObjectNested;

// TODO Sprite is untested in this new nested renderer
export function CSS3DNestedSprite( element ) {

	CSS3DObjectNested.call( this, element );

};

CSS3DNestedSprite.prototype = Object.create( CSS3DObjectNested.prototype );
CSS3DNestedSprite.prototype.constructor = CSS3DNestedSprite;

//

export function CSS3DRendererNested() {

	console.log( 'THREE.CSS3DRendererNested', THREE.REVISION );

	var _width, _height;
	var _widthHalf, _heightHalf;

	var matrix = new THREE.Matrix4();

	var cache = {
		camera: { fov: 0, style: '' },
		objects: new WeakMap()
	};

	var domElement = document.createElement( 'div' );
	domElement.classList.add( 'CSS3DRendererNested' );
	domElement.style.overflow = 'hidden';

	this.domElement = domElement;

	var cameraElement = document.createElement( 'div' );
	cameraElement.classList.add( 'cameraElement' );
	cameraElement.appendChild( document.createElement( 'slot' ) );

	cameraElement.style.WebkitTransformStyle = 'preserve-3d';
	cameraElement.style.transformStyle = 'preserve-3d';

	domElement.appendChild( cameraElement );

	this.getSize = function () {

		return {
			width: _width,
			height: _height
		};

	};

	this.setSize = function ( width, height ) {

		_width = width;
		_height = height;
		_widthHalf = _width / 2;
		_heightHalf = _height / 2;

		domElement.style.width = width + 'px';
		domElement.style.height = height + 'px';

		cameraElement.style.width = width + 'px';
		cameraElement.style.height = height + 'px';

	};

	function epsilon( value ) {

		return Math.abs( value ) < 1e-10 ? 0 : value;

	}

	function getCameraCSSMatrix( matrix ) {

		var elements = matrix.elements;

		return 'matrix3d(' +
			epsilon( elements[ 0 ] ) + ',' +
			epsilon( - elements[ 1 ] ) + ',' +
			epsilon( elements[ 2 ] ) + ',' +
			epsilon( elements[ 3 ] ) + ',' +
			epsilon( elements[ 4 ] ) + ',' +
			epsilon( - elements[ 5 ] ) + ',' +
			epsilon( elements[ 6 ] ) + ',' +
			epsilon( elements[ 7 ] ) + ',' +
			epsilon( elements[ 8 ] ) + ',' +
			epsilon( - elements[ 9 ] ) + ',' +
			epsilon( elements[ 10 ] ) + ',' +
			epsilon( elements[ 11 ] ) + ',' +
			epsilon( elements[ 12 ] ) + ',' +
			epsilon( - elements[ 13 ] ) + ',' +
			epsilon( elements[ 14 ] ) + ',' +
			epsilon( elements[ 15 ] ) +
		')';

	}

	function getObjectCSSMatrix( object, matrix ) {

		const parent = object.parent;
		const childOfScene = parent.type === 'Scene';

		var elements = matrix.elements;
		var matrix3d = 'matrix3d(' +
			epsilon( elements[ 0 ] ) + ',' +
			epsilon( elements[ 1 ] ) + ',' +
			epsilon( elements[ 2 ] ) + ',' +
			epsilon( elements[ 3 ] ) + ',' +
            epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 4 ] ) + ',' +
			epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 5 ] ) + ',' +
			epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 6 ] ) + ',' +
			epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 7 ] ) + ',' +
			epsilon( elements[ 8 ] ) + ',' +
			epsilon( elements[ 9 ] ) + ',' +
			epsilon( elements[ 10 ] ) + ',' +
			epsilon( elements[ 11 ] ) + ',' +
			epsilon( elements[ 12 ] ) + ',' + /* X position */
			epsilon( ( childOfScene ? 1 : - 1 ) * elements[ 13 ] ) + ',' + /* Y position */
			epsilon( elements[ 14 ] ) + ',' + /* Z position */
			epsilon( elements[ 15 ] ) +
		')';

		// similar to mountPoint
		return `${childOfScene ? 'translate(-50%, -50%)' : ''} ${matrix3d}`;

	}

	function renderObject( object, camera ) {

		if ( object instanceof CSS3DObjectNested ) {

			var style;

			if ( object instanceof CSS3DNestedSprite ) {

				// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/

				matrix.copy( camera.matrixWorldInverse );
				matrix.transpose();
				matrix.copyPosition( object.matrixWorld );
				matrix.scale( object.scale );

				matrix.elements[ 3 ] = 0;
				matrix.elements[ 7 ] = 0;
				matrix.elements[ 11 ] = 0;
				matrix.elements[ 15 ] = 1;

				style = getObjectCSSMatrix( object, matrix );

			} else {

				style = getObjectCSSMatrix( object, object.matrix );

			}

			var element = object.element;
			var cachedStyle = cache.objects.get( object );

			// if ( cachedStyle === undefined || cachedStyle !== style ) { // BUG, https://github.com/mrdoob/three.js/pull/15470
			if ( cachedStyle === undefined || cachedStyle.style !== style ) {

				element.style.WebkitTransform = style;
				element.style.transform = style;

				var objectData = { style: style };

				cache.objects.set( object, objectData );

			}

		}

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

			renderObject( object.children[ i ], camera );

		}

	}

	this.render = function ( scene, camera ) {

		var fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf;

		if ( cache.camera.fov !== fov ) {

			if ( camera.isPerspectiveCamera ) {

				domElement.style.WebkitPerspective = fov + 'px';
				domElement.style.perspective = fov + 'px';

			}

			cache.camera.fov = fov;

		}

		scene.updateMatrixWorld();

		if ( camera.parent === null ) camera.updateMatrixWorld();

		if ( camera.isOrthographicCamera ) {

			var tx = - ( camera.right + camera.left ) / 2;
			var ty = ( camera.top + camera.bottom ) / 2;

		}

		var cameraCSSMatrix = camera.isOrthographicCamera ?
			'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) :
			'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );

		var style = cameraCSSMatrix +
			'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)';

		if ( cache.camera.style !== style ) {

			cameraElement.style.WebkitTransform = style;
			cameraElement.style.transform = style;

			cache.camera.style = style;

		}

		renderObject( scene, camera );

	};

};
<commit_msg>commit the dispose method for CSSObjectNested that I meant to include in the previous commit<commit_after>// based on THREE.CSS3DRenderer from https://github.com/mrdoob/three.js/blob/51ac0084709d4d3795ccb7119ee24e6a808618df/examples/js/renderers/CSS3DRenderer.js

import * as THREE from 'three'

export function CSS3DObjectNested( element ) {

	THREE.Object3D.call( this );

	this.element = element;

	requestAnimationFrame( () => {

    	// delay to the next frame because attributes are not allowed be set
    	// inside Custom Element (i.e. Web Component) constructors, otherwise
    	// this can throw an error if called inside a Custom Element
    	// constructor.

    	this.element.style.position = 'absolute';

	} );

};

CSS3DObjectNested.prototype = Object.create( THREE.Object3D.prototype );
CSS3DObjectNested.prototype.constructor = CSS3DObjectNested;

CSS3DObjectNested.prototype.dispose = function() {

    this.element = null

};

// TODO Sprite is untested in this new nested renderer
export function CSS3DNestedSprite( element ) {

	CSS3DObjectNested.call( this, element );

};

CSS3DNestedSprite.prototype = Object.create( CSS3DObjectNested.prototype );
CSS3DNestedSprite.prototype.constructor = CSS3DNestedSprite;

//

export function CSS3DRendererNested() {

	console.log( 'THREE.CSS3DRendererNested', THREE.REVISION );

	var _width, _height;
	var _widthHalf, _heightHalf;

	var matrix = new THREE.Matrix4();

	var cache = {
		camera: { fov: 0, style: '' },
		objects: new WeakMap()
	};

	var domElement = document.createElement( 'div' );
	domElement.classList.add( 'CSS3DRendererNested' );
	domElement.style.overflow = 'hidden';

	this.domElement = domElement;

	var cameraElement = document.createElement( 'div' );
	cameraElement.classList.add( 'cameraElement' );
	cameraElement.appendChild( document.createElement( 'slot' ) );

	cameraElement.style.WebkitTransformStyle = 'preserve-3d';
	cameraElement.style.transformStyle = 'preserve-3d';

	domElement.appendChild( cameraElement );

	this.getSize = function () {

		return {
			width: _width,
			height: _height
		};

	};

	this.setSize = function ( width, height ) {

		_width = width;
		_height = height;
		_widthHalf = _width / 2;
		_heightHalf = _height / 2;

		domElement.style.width = width + 'px';
		domElement.style.height = height + 'px';

		cameraElement.style.width = width + 'px';
		cameraElement.style.height = height + 'px';

	};

	function epsilon( value ) {

		return Math.abs( value ) < 1e-10 ? 0 : value;

	}

	function getCameraCSSMatrix( matrix ) {

		var elements = matrix.elements;

		return 'matrix3d(' +
			epsilon( elements[ 0 ] ) + ',' +
			epsilon( - elements[ 1 ] ) + ',' +
			epsilon( elements[ 2 ] ) + ',' +
			epsilon( elements[ 3 ] ) + ',' +
			epsilon( elements[ 4 ] ) + ',' +
			epsilon( - elements[ 5 ] ) + ',' +
			epsilon( elements[ 6 ] ) + ',' +
			epsilon( elements[ 7 ] ) + ',' +
			epsilon( elements[ 8 ] ) + ',' +
			epsilon( - elements[ 9 ] ) + ',' +
			epsilon( elements[ 10 ] ) + ',' +
			epsilon( elements[ 11 ] ) + ',' +
			epsilon( elements[ 12 ] ) + ',' +
			epsilon( - elements[ 13 ] ) + ',' +
			epsilon( elements[ 14 ] ) + ',' +
			epsilon( elements[ 15 ] ) +
		')';

	}

	function getObjectCSSMatrix( object, matrix ) {

		const parent = object.parent;
		const childOfScene = parent.type === 'Scene';

		var elements = matrix.elements;
		var matrix3d = 'matrix3d(' +
			epsilon( elements[ 0 ] ) + ',' +
			epsilon( elements[ 1 ] ) + ',' +
			epsilon( elements[ 2 ] ) + ',' +
			epsilon( elements[ 3 ] ) + ',' +
            epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 4 ] ) + ',' +
			epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 5 ] ) + ',' +
			epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 6 ] ) + ',' +
			epsilon( ( childOfScene ? - 1 : 1 ) * elements[ 7 ] ) + ',' +
			epsilon( elements[ 8 ] ) + ',' +
			epsilon( elements[ 9 ] ) + ',' +
			epsilon( elements[ 10 ] ) + ',' +
			epsilon( elements[ 11 ] ) + ',' +
			epsilon( elements[ 12 ] ) + ',' + /* X position */
			epsilon( ( childOfScene ? 1 : - 1 ) * elements[ 13 ] ) + ',' + /* Y position */
			epsilon( elements[ 14 ] ) + ',' + /* Z position */
			epsilon( elements[ 15 ] ) +
		')';

		// similar to mountPoint
		return `${childOfScene ? 'translate(-50%, -50%)' : ''} ${matrix3d}`;

	}

	function renderObject( object, camera ) {

		if ( object instanceof CSS3DObjectNested ) {

			var style;

			if ( object instanceof CSS3DNestedSprite ) {

				// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/

				matrix.copy( camera.matrixWorldInverse );
				matrix.transpose();
				matrix.copyPosition( object.matrixWorld );
				matrix.scale( object.scale );

				matrix.elements[ 3 ] = 0;
				matrix.elements[ 7 ] = 0;
				matrix.elements[ 11 ] = 0;
				matrix.elements[ 15 ] = 1;

				style = getObjectCSSMatrix( object, matrix );

			} else {

				style = getObjectCSSMatrix( object, object.matrix );

			}

			var element = object.element;
			var cachedStyle = cache.objects.get( object );

			// if ( cachedStyle === undefined || cachedStyle !== style ) { // BUG, https://github.com/mrdoob/three.js/pull/15470
			if ( cachedStyle === undefined || cachedStyle.style !== style ) {

				element.style.WebkitTransform = style;
				element.style.transform = style;

				var objectData = { style: style };

				cache.objects.set( object, objectData );

			}

		}

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

			renderObject( object.children[ i ], camera );

		}

	}

	this.render = function ( scene, camera ) {

		var fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf;

		if ( cache.camera.fov !== fov ) {

			if ( camera.isPerspectiveCamera ) {

				domElement.style.WebkitPerspective = fov + 'px';
				domElement.style.perspective = fov + 'px';

			}

			cache.camera.fov = fov;

		}

		scene.updateMatrixWorld();

		if ( camera.parent === null ) camera.updateMatrixWorld();

		if ( camera.isOrthographicCamera ) {

			var tx = - ( camera.right + camera.left ) / 2;
			var ty = ( camera.top + camera.bottom ) / 2;

		}

		var cameraCSSMatrix = camera.isOrthographicCamera ?
			'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) :
			'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );

		var style = cameraCSSMatrix +
			'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)';

		if ( cache.camera.style !== style ) {

			cameraElement.style.WebkitTransform = style;
			cameraElement.style.transform = style;

			cache.camera.style = style;

		}

		renderObject( scene, camera );

	};

};
<|endoftext|>


<commit_before>#!/usr/bin/env node

let ciJobNumber = require('ci-job-number')
let chalk = require('chalk')

if (ciJobNumber() !== 1) {
  process.stdout.write(
    chalk.yellow('Size Limits run only on first CI job, to save CI resources'))
  process.stdout.write('\n')
  process.exit(0)
}

let cosmiconfig = require('cosmiconfig')
let readPkg = require('read-pkg-up')
let globby = require('globby')
let yargs = require('yargs')
let bytes = require('bytes')
let path = require('path')

let getSize = require('.')

const PACKAGE_EXAMPLE = '\n' +
                        '  "size-limit": [\n' +
                        '    {\n' +
                        '      "path": "index.js",\n' +
                        '      "limit": "9 KB"\n' +
                        '    }\n' +
                        '  ]'
const FILE_EXAMPLE = '\n' +
                     '  [\n' +
                     '    {\n' +
                     '      path: "index.js",\n' +
                     '      limit: "9 KB"\n' +
                     '    }\n' +
                     '  ]'

let argv = yargs
  .usage('$0')
  .option('limit', {
    describe: 'Size limit for passed files',
    type: 'string'
  })
  .option('why', {
    alias: 'w',
    describe: 'Show package content',
    type: 'boolean'
  })
  .option('no-webpack', {
    describe: 'Disable webpack',
    type: 'boolean'
  })
  .option('no-gzip', {
    describe: 'Disable gzip',
    type: 'boolean'
  })
  .option('config', {
    describe: 'Custom webpack config',
    type: 'string'
  })
  .alias('help', 'h')
  .alias('version', 'v')
  .epilog('Usage:\n' +
          '  $0\n' +
          '    Read configuration from package.json and check limit.\n' +
          '  $0 --why\n' +
          '    Show reasons why project have this size.\n' +
          '  $0 index.js\n' +
          '    Check specific file size with all file dependencies.\n' +
          '\n' +
          'Size Limit will read size-limit section from package.json:\n' +
          PACKAGE_EXAMPLE + '\n\n' +
          'or from .size-limit config:\n' +
          FILE_EXAMPLE)
  .locale('en')
  .argv

function ownError (msg) {
  let error = new Error(msg)
  error.sizeLimit = true
  return error
}

function isStrings (value) {
  if (!Array.isArray(value)) return false
  return value.every(i => typeof i === 'string')
}

let PACKAGE_ERRORS = {
  notArray: 'The `"size-limit"` section of package.json must be `an array`',
  empty: 'The `"size-limit"` section of package.json must `not be empty`',
  notObject: 'The `"size-limit"` array in package.json ' +
             'should contain only objects',
  pathNotString: 'The `path` in the `"size-limit"` section ' +
              'of package.json must be `a string` or `an array of strings`',
  entryNotString: 'The `entry` in the `"size-limit"` section ' +
                  'of package.json must be `a string` or `an array of strings`'
}

let FILE_ERRORS = {
  notArray: 'Size Limit config must contain `an array`',
  empty: 'Size Limit config must `not be empty`',
  notObject: 'Size Limit config should contain only objects',
  pathNotString: 'The `path` in Size Limit config ' +
                 'must be `a string` or `an array of strings`',
  entryNotString: 'The `entry` in Size Limit config ' +
                  'must be `a string` or `an array of strings`'
}

function isStringOrUndefined (value) {
  let type = typeof value
  return type !== 'undefined' && type !== 'string' && !isStrings(value)
}

function configError (limits) {
  if (!Array.isArray(limits)) {
    return 'notArray'
  }
  if (limits.length === 0) {
    return 'empty'
  }
  for (let limit of limits) {
    if (typeof limit !== 'object') {
      return 'notObject'
    }
    if (isStringOrUndefined(limit.path)) {
      return 'pathNotString'
    }
    if (isStringOrUndefined(limit.entry)) {
      return 'entryNotString'
    }
  }
  return false
}

function formatBytes (size) {
  return bytes.format(size, { unitSeparator: ' ' })
}

function capitalize (str) {
  return str[0].toUpperCase() + str.slice(1)
}

function renderSize (item, i, array) {
  let rows = []
  let passed = item.limit && item.size <= item.limit
  let failed = item.limit && item.limit < item.size
  let unlimited = !item.limit

  if (array.length > 1 && item.name) {
    rows.push(item.name)
  }

  let limitString = formatBytes(item.limit)
  let sizeString = formatBytes(item.size)

  if (passed) {
    rows.push(
      `Package size: ${ chalk.bold(chalk.green(sizeString)) }`,
      `Size limit:   ${ chalk.bold(limitString) }`
    )
  }

  if (failed) {
    if (limitString === sizeString) {
      limitString = item.limit + ' B'
      sizeString = item.size + ' B'
    }
    let diff = formatBytes(item.size - item.limit)
    rows.push(
      chalk.red('Package size limit has exceeded by ' + diff),
      `Package size: ${ chalk.bold(chalk.red(sizeString)) }`,
      `Size limit:   ${ chalk.bold(limitString) }`
    )
  }

  if (unlimited) {
    rows.push(`Package size: ${ chalk.bold(sizeString) }`)
  }

  return {
    output: rows.map(row => `  ${ row }\n`).join(''),
    failed
  }
}

function getConfig () {
  let explorer = cosmiconfig('size-limit', {
    searchPlaces: [
      'package.json',
      '.size-limit.json',
      '.size-limit',
      '.size-limit.js'
    ]
  })
  return explorer
    .search()
    .then(result => {
      if (result === null) {
        throw ownError(
          'Can not find settings for Size Limit. ' +
          'Add it to section `"size-limit"` in package.json ' +
          'according to Size Limit docs.' +
          `\n${ PACKAGE_EXAMPLE }\n`
        )
      }
      return result
    })
    .catch(err => {
      let msg = err.message
      let file = 'config'
      if (msg.indexOf('JSONError') !== -1 || msg.indexOf('JSON Error') !== -1) {
        let errorRegexp = /JSON\s?Error([^:]*):\s+([^\n]+)( while parsing)/
        let pathRegexp = / in ([^\n]+):\n/
        if (pathRegexp.test(msg)) {
          file = msg.match(pathRegexp)[1]
          file = path.relative(process.cwd(), file)
          file = '`' + file + '`'
        }
        if (errorRegexp.test(msg)) msg = msg.match(errorRegexp)[1]
        throw ownError(
          'Can not parse ' + file + '. ' + msg + '. ' +
          'Change config according to Size Limit docs.\n' +
          PACKAGE_EXAMPLE + '\n'
        )
      } else if (err.reason && err.mark && err.mark.name) {
        file = path.relative(process.cwd(), err.mark.name)
        let position = err.mark.line + ':' + err.mark.column
        throw ownError(
          'Can not parse `' + file + '` at ' + position + '. ' +
          capitalize(err.reason) + '. ' +
          'Change config according to Size Limit docs.\n' +
          FILE_EXAMPLE + '\n'
        )
      } else {
        throw err
      }
    })
}

let getOptions
if (argv['_'].length === 0) {
  getOptions = Promise.all([getConfig(), readPkg()]).then(all => {
    let config = all[0]
    let packagePath = all[1] ? all[1].path : false
    let packageJson = all[1] ? all[1].pkg : { }

    let error = configError(config.config)
    if (error) {
      if (/package\.json$/.test(config.filepath)) {
        throw ownError(
          PACKAGE_ERRORS[error] + '. ' +
          'Fix it according to Size Limit docs.' +
          `\n${ PACKAGE_EXAMPLE }\n`
        )
      } else {
        throw ownError(
          FILE_ERRORS[error] + '. ' +
          'Fix it according to Size Limit docs.' +
          `\n${ FILE_EXAMPLE }\n`
        )
      }
    }

    return Promise.all(config.config.map(entry => {
      let peer = Object.keys(packageJson.peerDependencies || { })

      let globbing, cwd
      if (entry.path) {
        cwd = path.dirname(config.filepath)
        globbing = globby(entry.path || packageJson.main, { cwd })
      } else {
        cwd = path.dirname(packagePath || '.')
        globbing = globby(packageJson.main || 'index.js', { cwd })
      }

      return globbing.then(files => {
        if (files.length === 0 && entry.path) {
          files = entry.path
          if (typeof files === 'string') files = [files]
        }
        return {
          webpack: entry.webpack !== false,
          config: entry.config,
          ignore: peer.concat(entry.ignore || []),
          limit: bytes.parse(argv.limit || entry.limit),
          gzip: entry.gzip !== false,
          name: entry.name || files.join(', '),
          full: files.map(i => {
            if (path.isAbsolute(i)) {
              return i
            } else {
              return path.join(cwd, i)
            }
          }),
          entry: entry.entry
        }
      })
    })).then(files => {
      return {
        bundle: packageJson.name,
        files
      }
    })
  })
} else {
  let files = argv['_'].slice(0)

  if (files.length === 0) {
    getOptions = Promise.reject(
      ownError(
        'Specify file for Size Limit. ' +
        `For example, \`size-limit ${ argv['_'] } index.js\`.`
      )
    )
  } else {
    let full = files.map(i => {
      if (path.isAbsolute(i)) {
        return i
      } else {
        return path.join(process.cwd(), i)
      }
    })

    getOptions = Promise.resolve({
      bundle: undefined,
      ignore: [],
      files: [
        {
          webpack: argv.webpack !== false,
          limit: bytes.parse(argv.limit),
          gzip: argv.gzip !== false,
          full
        }
      ]
    })
  }
}

getOptions.then(config => {
  return Promise.all(config.files.map(file => {
    if (file.webpack === false && argv.why) {
      throw ownError(
        '`--why` does not work with `"webpack": false`. ' +
        'Add Webpack Bundle Analyzer to your Webpack config.'
      )
    }

    let opts = {
      webpack: file.webpack,
      bundle: config.bundle,
      ignore: file.ignore,
      config: file.config || argv.config,
      entry: file.entry,
      gzip: file.gzip
    }
    if (argv.why && config.files.length === 1) {
      opts.analyzer = process.env['NODE_ENV'] === 'test' ? 'static' : 'server'
    }

    return getSize(file.full, opts).then(size => {
      if (typeof size.gzip === 'number') {
        file.size = size.gzip
      } else {
        file.size = size.parsed
      }
      return file
    })
  })).then(() => config)
}).then(config => {
  let files = config.files
  let results = files.map(renderSize)

  let output = results.map(i => i.output).join('\n')

  process.stdout.write('\n' + output + (files.length > 1 ? '\n' : ''))

  let message
  if (argv.config) {
    message = '  With given webpack configuration\n\n'
  } else {
    message = '  With all dependencies, minified and gzipped\n\n'
  }

  process.stdout.write(chalk.gray(message))

  if (argv.why && files.length > 1) {
    let ignore = files.reduce((all, i) => all.concat(i.ignore), [])
    let opts = {
      analyzer: process.env['NODE_ENV'] === 'test' ? 'static' : 'server',
      bundle: config.bundle,
      ignore
    }
    let full = files.reduce((all, i) => all.concat(i.full), [])
    return getSize(full, opts).then(() => files)
  }

  if (!argv.why) {
    if (results.some(i => i.failed)) {
      process.exit(3)
    } else {
      process.exit(0)
    }
  }

  return files
}).catch(e => {
  let msg
  if (e.sizeLimit) {
    msg = e.message
      .split('. ')
      .map(i => i.replace(/`([^`]*)`/g, chalk.bold('$1')))
      .join('.\n        ')
  } else if (e.message.indexOf('Module not found:') !== -1) {
    let first = e.message.match(/Module not found:[^\n]*/)[0]
    msg = `Size Limit c${ first.replace('Module not found: Error: C', '') }`
      .replace(/resolve '(.*)' in '(.*)'/,
        `resolve\n        ${ chalk.bold('$1') }` +
        `\n        in ${ chalk.bold('$2') }`
      )
  } else {
    msg = e.stack
  }

  process.stderr.write(`${ chalk.bgRed(' ERROR ') } ${ chalk.red(msg) }\n`)
  process.exit(1)
})
<commit_msg>Clean up tests<commit_after>#!/usr/bin/env node

let ciJobNumber = require('ci-job-number')
let chalk = require('chalk')

if (ciJobNumber() !== 1) {
  process.stdout.write(
    chalk.yellow('Size Limits run only on first CI job, to save CI resources'))
  process.stdout.write('\n')
  process.exit(0)
}

let cosmiconfig = require('cosmiconfig')
let readPkg = require('read-pkg-up')
let globby = require('globby')
let yargs = require('yargs')
let bytes = require('bytes')
let path = require('path')

let getSize = require('.')

const PACKAGE_EXAMPLE = '\n' +
                        '  "size-limit": [\n' +
                        '    {\n' +
                        '      "path": "index.js",\n' +
                        '      "limit": "9 KB"\n' +
                        '    }\n' +
                        '  ]'
const FILE_EXAMPLE = '\n' +
                     '  [\n' +
                     '    {\n' +
                     '      path: "index.js",\n' +
                     '      limit: "9 KB"\n' +
                     '    }\n' +
                     '  ]'

let argv = yargs
  .usage('$0')
  .option('limit', {
    describe: 'Size limit for passed files',
    type: 'string'
  })
  .option('why', {
    alias: 'w',
    describe: 'Show package content',
    type: 'boolean'
  })
  .option('no-webpack', {
    describe: 'Disable webpack',
    type: 'boolean'
  })
  .option('no-gzip', {
    describe: 'Disable gzip',
    type: 'boolean'
  })
  .option('config', {
    describe: 'Custom webpack config',
    type: 'string'
  })
  .alias('help', 'h')
  .alias('version', 'v')
  .epilog('Usage:\n' +
          '  $0\n' +
          '    Read configuration from package.json and check limit.\n' +
          '  $0 --why\n' +
          '    Show reasons why project have this size.\n' +
          '  $0 index.js\n' +
          '    Check specific file size with all file dependencies.\n' +
          '\n' +
          'Size Limit will read size-limit section from package.json:\n' +
          PACKAGE_EXAMPLE + '\n\n' +
          'or from .size-limit config:\n' +
          FILE_EXAMPLE)
  .locale('en')
  .argv

function ownError (msg) {
  let error = new Error(msg)
  error.sizeLimit = true
  return error
}

function isStrings (value) {
  if (!Array.isArray(value)) return false
  return value.every(i => typeof i === 'string')
}

let PACKAGE_ERRORS = {
  notArray: 'The `"size-limit"` section of package.json must be `an array`',
  empty: 'The `"size-limit"` section of package.json must `not be empty`',
  notObject: 'The `"size-limit"` array in package.json ' +
             'should contain only objects',
  pathNotString: 'The `path` in the `"size-limit"` section ' +
              'of package.json must be `a string` or `an array of strings`',
  entryNotString: 'The `entry` in the `"size-limit"` section ' +
                  'of package.json must be `a string` or `an array of strings`'
}

let FILE_ERRORS = {
  notArray: 'Size Limit config must contain `an array`',
  empty: 'Size Limit config must `not be empty`',
  notObject: 'Size Limit config should contain only objects',
  pathNotString: 'The `path` in Size Limit config ' +
                 'must be `a string` or `an array of strings`',
  entryNotString: 'The `entry` in Size Limit config ' +
                  'must be `a string` or `an array of strings`'
}

function isStringOrUndefined (value) {
  let type = typeof value
  return type !== 'undefined' && type !== 'string' && !isStrings(value)
}

function configError (limits) {
  if (!Array.isArray(limits)) {
    return 'notArray'
  }
  if (limits.length === 0) {
    return 'empty'
  }
  for (let limit of limits) {
    if (typeof limit !== 'object') {
      return 'notObject'
    }
    if (isStringOrUndefined(limit.path)) {
      return 'pathNotString'
    }
    if (isStringOrUndefined(limit.entry)) {
      return 'entryNotString'
    }
  }
  return false
}

function formatBytes (size) {
  return bytes.format(size, { unitSeparator: ' ' })
}

function capitalize (str) {
  return str[0].toUpperCase() + str.slice(1)
}

function renderSize (item, i, array) {
  let rows = []
  let passed = item.limit && item.size <= item.limit
  let failed = item.limit && item.limit < item.size
  let unlimited = !item.limit

  if (array.length > 1 && item.name) {
    rows.push(item.name)
  }

  let limitString = formatBytes(item.limit)
  let sizeString = formatBytes(item.size)

  if (passed) {
    rows.push(
      `Package size: ${ chalk.bold(chalk.green(sizeString)) }`,
      `Size limit:   ${ chalk.bold(limitString) }`
    )
  }

  if (failed) {
    if (limitString === sizeString) {
      limitString = item.limit + ' B'
      sizeString = item.size + ' B'
    }
    let diff = formatBytes(item.size - item.limit)
    rows.push(
      chalk.red('Package size limit has exceeded by ' + diff),
      `Package size: ${ chalk.bold(chalk.red(sizeString)) }`,
      `Size limit:   ${ chalk.bold(limitString) }`
    )
  }

  if (unlimited) {
    rows.push(`Package size: ${ chalk.bold(sizeString) }`)
  }

  return {
    output: rows.map(row => `  ${ row }\n`).join(''),
    failed
  }
}

function getConfig () {
  let explorer = cosmiconfig('size-limit', {
    searchPlaces: [
      'package.json',
      '.size-limit.json',
      '.size-limit',
      '.size-limit.js'
    ]
  })
  return explorer
    .search()
    .then(result => {
      if (result === null) {
        throw ownError(
          'Can not find settings for Size Limit. ' +
          'Add it to section `"size-limit"` in package.json ' +
          'according to Size Limit docs.' +
          `\n${ PACKAGE_EXAMPLE }\n`
        )
      }
      return result
    })
    .catch(err => {
      let msg = err.message
      let file = 'config'
      if (msg.indexOf('JSONError') !== -1 || msg.indexOf('JSON Error') !== -1) {
        let pathRegexp = / in ([^\n]+):\n/
        if (pathRegexp.test(msg)) {
          file = msg.match(pathRegexp)[1]
          file = path.relative(process.cwd(), file)
          file = '`' + file + '`'
        }
        let errorRegexp = /JSON\s?Error([^:]*):\s+([^\n]+)( while parsing)/
        if (errorRegexp.test(msg)) msg = msg.match(errorRegexp)[2]
        throw ownError(
          'Can not parse ' + file + '. ' + msg + '. ' +
          'Change config according to Size Limit docs.\n' +
          PACKAGE_EXAMPLE + '\n'
        )
      } else if (err.reason && err.mark && err.mark.name) {
        file = path.relative(process.cwd(), err.mark.name)
        let position = err.mark.line + ':' + err.mark.column
        throw ownError(
          'Can not parse `' + file + '` at ' + position + '. ' +
          capitalize(err.reason) + '. ' +
          'Change config according to Size Limit docs.\n' +
          FILE_EXAMPLE + '\n'
        )
      } else {
        throw err
      }
    })
}

let getOptions
if (argv['_'].length === 0) {
  getOptions = Promise.all([getConfig(), readPkg()]).then(all => {
    let config = all[0]
    let packagePath = all[1] ? all[1].path : false
    let packageJson = all[1] ? all[1].pkg : { }

    let error = configError(config.config)
    if (error) {
      if (/package\.json$/.test(config.filepath)) {
        throw ownError(
          PACKAGE_ERRORS[error] + '. ' +
          'Fix it according to Size Limit docs.' +
          `\n${ PACKAGE_EXAMPLE }\n`
        )
      } else {
        throw ownError(
          FILE_ERRORS[error] + '. ' +
          'Fix it according to Size Limit docs.' +
          `\n${ FILE_EXAMPLE }\n`
        )
      }
    }

    return Promise.all(config.config.map(entry => {
      let peer = Object.keys(packageJson.peerDependencies || { })

      let globbing, cwd
      if (entry.path) {
        cwd = path.dirname(config.filepath)
        globbing = globby(entry.path || packageJson.main, { cwd })
      } else {
        cwd = path.dirname(packagePath || '.')
        globbing = globby(packageJson.main || 'index.js', { cwd })
      }

      return globbing.then(files => {
        if (files.length === 0 && entry.path) {
          files = entry.path
          if (typeof files === 'string') files = [files]
        }
        return {
          webpack: entry.webpack !== false,
          config: entry.config,
          ignore: peer.concat(entry.ignore || []),
          limit: bytes.parse(argv.limit || entry.limit),
          gzip: entry.gzip !== false,
          name: entry.name || files.join(', '),
          full: files.map(i => {
            if (path.isAbsolute(i)) {
              return i
            } else {
              return path.join(cwd, i)
            }
          }),
          entry: entry.entry
        }
      })
    })).then(files => {
      return {
        bundle: packageJson.name,
        files
      }
    })
  })
} else {
  let files = argv['_'].slice(0)

  if (files.length === 0) {
    getOptions = Promise.reject(
      ownError(
        'Specify file for Size Limit. ' +
        `For example, \`size-limit ${ argv['_'] } index.js\`.`
      )
    )
  } else {
    let full = files.map(i => {
      if (path.isAbsolute(i)) {
        return i
      } else {
        return path.join(process.cwd(), i)
      }
    })

    getOptions = Promise.resolve({
      bundle: undefined,
      ignore: [],
      files: [
        {
          webpack: argv.webpack !== false,
          limit: bytes.parse(argv.limit),
          gzip: argv.gzip !== false,
          full
        }
      ]
    })
  }
}

getOptions.then(config => {
  return Promise.all(config.files.map(file => {
    if (file.webpack === false && argv.why) {
      throw ownError(
        '`--why` does not work with `"webpack": false`. ' +
        'Add Webpack Bundle Analyzer to your Webpack config.'
      )
    }

    let opts = {
      webpack: file.webpack,
      bundle: config.bundle,
      ignore: file.ignore,
      config: file.config || argv.config,
      entry: file.entry,
      gzip: file.gzip
    }
    if (argv.why && config.files.length === 1) {
      opts.analyzer = process.env['NODE_ENV'] === 'test' ? 'static' : 'server'
    }

    return getSize(file.full, opts).then(size => {
      if (typeof size.gzip === 'number') {
        file.size = size.gzip
      } else {
        file.size = size.parsed
      }
      return file
    })
  })).then(() => config)
}).then(config => {
  let files = config.files
  let results = files.map(renderSize)

  let output = results.map(i => i.output).join('\n')

  process.stdout.write('\n' + output + (files.length > 1 ? '\n' : ''))

  let message
  if (argv.config) {
    message = '  With given webpack configuration\n\n'
  } else {
    message = '  With all dependencies, minified and gzipped\n\n'
  }

  process.stdout.write(chalk.gray(message))

  if (argv.why && files.length > 1) {
    let ignore = files.reduce((all, i) => all.concat(i.ignore), [])
    let opts = {
      analyzer: process.env['NODE_ENV'] === 'test' ? 'static' : 'server',
      bundle: config.bundle,
      ignore
    }
    let full = files.reduce((all, i) => all.concat(i.full), [])
    return getSize(full, opts).then(() => files)
  }

  if (!argv.why) {
    if (results.some(i => i.failed)) {
      process.exit(3)
    } else {
      process.exit(0)
    }
  }

  return files
}).catch(e => {
  let msg
  if (e.sizeLimit) {
    msg = e.message
      .split('. ')
      .map(i => i.replace(/`([^`]*)`/g, chalk.bold('$1')))
      .join('.\n        ')
  } else if (e.message.indexOf('Module not found:') !== -1) {
    let first = e.message.match(/Module not found:[^\n]*/)[0]
    msg = `Size Limit c${ first.replace('Module not found: Error: C', '') }`
      .replace(/resolve '(.*)' in '(.*)'/,
        `resolve\n        ${ chalk.bold('$1') }` +
        `\n        in ${ chalk.bold('$2') }`
      )
  } else {
    msg = e.stack
  }

  process.stderr.write(`${ chalk.bgRed(' ERROR ') } ${ chalk.red(msg) }\n`)
  process.exit(1)
})
<|endoftext|>


<commit_before>#!/usr/bin/env node
// `yargs/yargs` required to work with webpack, see here.
// https://github.com/yargs/yargs/issues/781
var yargs = require('yargs/yargs');
var Ganache = require("ganache-core");
var pkg = require("./package.json");
var corepkg = require("./node_modules/ganache-core/package.json");
var URL = require("url");
var Web3 = require("web3");
var web3 = new Web3(); // Used only for its BigNumber library.
var fs = require("fs");

var parser = yargs()
.option("unlock", {
  type: "string",
  alias: "u"
});

var argv = parser.parse(process.argv);

if (argv.help || argv['?']) {
  console.log("");
  console.log("testrpc: Fast Ethereum RPC client for testing and development");
  console.log("  Full docs: https://github.com/ethereumjs/testrpc");
  console.log("");
  console.log("Usage: testrpc [options]");
  console.log("  options:");
  console.log("  --port/-p <port to bind to, default 8545>");
  console.log("  --host/-h <host to bind to, default 0.0.0.0>");
  console.log("  --fork/-f <url>   (Fork from another currently running Ethereum client at a given block)");
  console.log("");
  console.log("  --db <db path>   (directory to save chain db)");
  console.log("  --seed <seed value for PRNG, default random>");
  console.log("  --deterministic/-d     (uses fixed seed)");
  console.log("  --mnemonic/-m <mnemonic>");
  console.log("  --accounts/-a <number of accounts to generate at startup>");
  console.log("  --secure/-s   (Lock accounts by default)");
  console.log("  --unlock <accounts>   (Comma-separated list of accounts or indices to unlock)");
  console.log("");
  console.log("  --blocktime/-b <block time in seconds>");
  console.log("  --networkId/-i <network id> (default current time)");
  console.log("  --gasPrice/-g <gas price>   (default 20000000000)");
  console.log("  --gasLimit/-l <gas limit>   (default 0x47E7C4)");
  console.log("");
  console.log("  --debug       (Output VM opcodes for debugging)");
  console.log("  --verbose/-v");
  console.log("  --mem         (Only show memory output, not tx history)");
  console.log("");
  console.log("  --help / -?    (this output)");
  console.log("");
  process.exit(0);
}

function parseAccounts(accounts) {
  function splitAccount(account) {
    account = account.split(',')
    return {
      secretKey: account[0],
      balance: account[1]
    };
  }

  if (typeof accounts === 'string')
    return [ splitAccount(accounts) ];
  else if (!Array.isArray(accounts))
    return;

  var ret = []
  for (var i = 0; i < accounts.length; i++) {
    ret.push(splitAccount(accounts[i]));
  }
  return ret;
}

if (argv.d || argv.deterministic) {
  argv.s = "TestRPC is awesome!"; // Seed phrase; don't change to Ganache, maintain original determinism
}

if (typeof argv.unlock == "string") {
  argv.unlock = [argv.unlock];
}

var logger = console;

// If the mem argument is passed, only show memory output,
// not transaction history.
if (argv.mem === true) {
  logger = {
    log: function() {}
  };

  setInterval(function() {
    console.log(process.memoryUsage());
  }, 1000);
}

var options = {
  port: argv.p || argv.port || "8545",
  hostname: argv.h || argv.hostname,
  debug: argv.debug,
  seed: argv.s || argv.seed,
  mnemonic: argv.m || argv.mnemonic,
  total_accounts: argv.a || argv.accounts,
  blocktime: argv.b || argv.blocktime,
  gasPrice: argv.g || argv.gasPrice,
  gasLimit: argv.l || argv.gasLimit,
  accounts: parseAccounts(argv.account),
  unlocked_accounts: argv.unlock,
  fork: argv.f || argv.fork || false,
  network_id: argv.i || argv.networkId,
  verbose: argv.v || argv.verbose,
  secure: argv.n || argv.secure || false,
  db_path: argv.db || null,
  account_keys_path: argv.acctKeys || null,
  logger: logger
}

var fork_address;

// If we're forking from another client, don't try to use the same port.
if (options.fork) {
  var split = options.fork.split("@");
  fork_address = split[0];
  var block;
  if (split.length > 1) {
    block = split[1];
  }

  if (URL.parse(fork_address).port == options.port) {
    options.port = (parseInt(options.port) + 1);
  }

  options.fork = fork_address + (block != null ? "@" + block : "");
}

var server = Ganache.server(options);

//console.log("Ganache CLI v" + pkg.version);
console.log("EthereumJS TestRPC v" + pkg.version + " (ganache-core: " + corepkg.version + ")");

server.listen(options.port, options.hostname, function(err, state) {
  if (err) {
    console.log(err);
    return;
  }
  console.log("");
  console.log("Available Accounts");
  console.log("==================");

  var accounts = state.accounts;
  var addresses = Object.keys(accounts);

  addresses.forEach(function(address, index) {
    var line = "(" + index + ") " + address;

    if (state.isUnlocked(address) == false) {
      line += " 🔒";
    }

    console.log(line);
  });

  console.log("");
  console.log("Private Keys");
  console.log("==================");

  addresses.forEach(function(address, index) {
    console.log("(" + index + ") " + accounts[address].secretKey.toString("hex"));
  });

  if (options.account_keys_path != null) {
    console.log("");
    console.log("Saving accounts and keys to " + options.account_keys_path);
    var obj = {}
    obj.addresses = accounts;
    obj.private_keys = {};
    addresses.forEach(function(address, index) {
       obj.private_keys[address] = accounts[address].secretKey.toString("hex");
    });
    var json = JSON.stringify(obj);
    fs.writeFile(options.account_keys_path, json, 'utf8',function(err){
      if(err) throw err;
    })
  }

  if (options.accounts == null) {
    console.log("");
    console.log("HD Wallet");
    console.log("==================");
    console.log("Mnemonic:      " + state.mnemonic);
    console.log("Base HD Path:  " + state.wallet_hdpath + "{account_index}")
  }

  if (options.gasPrice) {
    console.log("");
    console.log("Gas Price");
    console.log("==================");
    console.log(options.gasPrice);
  }

  if (options.gasLimit) {
    console.log("");
    console.log("Gas Limit");
    console.log("==================");
    console.log(options.gasLimit);
  }

  if (options.fork) {
    console.log("");
    console.log("Forked Chain");
    console.log("==================");
    console.log("Location:    " + fork_address);
    console.log("Block:       " + web3.toBigNumber(state.blockchain.fork_block_number).toString(10));
    console.log("Network ID:  " + state.net_version);
    console.log("Time:        " + (state.blockchain.startTime || new Date()).toString());
  }

  console.log("");
  console.log("Listening on " + (options.hostname || "localhost") + ":" + options.port);
});

process.on('uncaughtException', function(e) {
  console.log(e.stack);
  process.exit(1);
})

// See http://stackoverflow.com/questions/10021373/what-is-the-windows-equivalent-of-process-onsigint-in-node-js
if (process.platform === "win32") {
  require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
  })
  .on("SIGINT", function () {
    process.emit("SIGINT");
  });
}

process.on("SIGINT", function () {
  // graceful shutdown
  server.close(function(err) {
    if (err) {
      console.log(err.stack || err);
    }
    process.exit();
  });
});
<commit_msg>Add helptext for account keys (added in PR #406)<commit_after>#!/usr/bin/env node
// `yargs/yargs` required to work with webpack, see here.
// https://github.com/yargs/yargs/issues/781
var yargs = require('yargs/yargs');
var Ganache = require("ganache-core");
var pkg = require("./package.json");
var corepkg = require("./node_modules/ganache-core/package.json");
var URL = require("url");
var Web3 = require("web3");
var web3 = new Web3(); // Used only for its BigNumber library.
var fs = require("fs");

var parser = yargs()
.option("unlock", {
  type: "string",
  alias: "u"
});

var argv = parser.parse(process.argv);

if (argv.help || argv['?']) {
  console.log("");
  console.log("testrpc: Fast Ethereum RPC client for testing and development");
  console.log("  Full docs: https://github.com/ethereumjs/testrpc");
  console.log("");
  console.log("Usage: testrpc [options]");
  console.log("  options:");
  console.log("  --port/-p <port to bind to, default 8545>");
  console.log("  --host/-h <host to bind to, default 0.0.0.0>");
  console.log("  --fork/-f <url>   (Fork from another currently running Ethereum client at a given block)");
  console.log("");
  console.log("  --db <db path>   (directory to save chain db)");
  console.log("  --seed <seed value for PRNG, default random>");
  console.log("  --deterministic/-d     (uses fixed seed)");
  console.log("  --mnemonic/-m <mnemonic>");
  console.log("  --accounts/-a <number of accounts to generate at startup>");
  console.log("  --acctKeys <path to file>  (saves generated accounts and private keys as JSON object in specified file)");
  console.log("  --secure/-s   (Lock accounts by default)");
  console.log("  --unlock <accounts>   (Comma-separated list of accounts or indices to unlock)");
  console.log("");
  console.log("  --blocktime/-b <block time in seconds>");
  console.log("  --networkId/-i <network id> (default current time)");
  console.log("  --gasPrice/-g <gas price>   (default 20000000000)");
  console.log("  --gasLimit/-l <gas limit>   (default 0x47E7C4)");
  console.log("");
  console.log("  --debug       (Output VM opcodes for debugging)");
  console.log("  --verbose/-v");
  console.log("  --mem         (Only show memory output, not tx history)");
  console.log("");
  console.log("  --help / -?    (this output)");
  console.log("");
  process.exit(0);
}

function parseAccounts(accounts) {
  function splitAccount(account) {
    account = account.split(',')
    return {
      secretKey: account[0],
      balance: account[1]
    };
  }

  if (typeof accounts === 'string')
    return [ splitAccount(accounts) ];
  else if (!Array.isArray(accounts))
    return;

  var ret = []
  for (var i = 0; i < accounts.length; i++) {
    ret.push(splitAccount(accounts[i]));
  }
  return ret;
}

if (argv.d || argv.deterministic) {
  argv.s = "TestRPC is awesome!"; // Seed phrase; don't change to Ganache, maintain original determinism
}

if (typeof argv.unlock == "string") {
  argv.unlock = [argv.unlock];
}

var logger = console;

// If the mem argument is passed, only show memory output,
// not transaction history.
if (argv.mem === true) {
  logger = {
    log: function() {}
  };

  setInterval(function() {
    console.log(process.memoryUsage());
  }, 1000);
}

var options = {
  port: argv.p || argv.port || "8545",
  hostname: argv.h || argv.hostname,
  debug: argv.debug,
  seed: argv.s || argv.seed,
  mnemonic: argv.m || argv.mnemonic,
  total_accounts: argv.a || argv.accounts,
  blocktime: argv.b || argv.blocktime,
  gasPrice: argv.g || argv.gasPrice,
  gasLimit: argv.l || argv.gasLimit,
  accounts: parseAccounts(argv.account),
  unlocked_accounts: argv.unlock,
  fork: argv.f || argv.fork || false,
  network_id: argv.i || argv.networkId,
  verbose: argv.v || argv.verbose,
  secure: argv.n || argv.secure || false,
  db_path: argv.db || null,
  account_keys_path: argv.acctKeys || null,
  logger: logger
}

var fork_address;

// If we're forking from another client, don't try to use the same port.
if (options.fork) {
  var split = options.fork.split("@");
  fork_address = split[0];
  var block;
  if (split.length > 1) {
    block = split[1];
  }

  if (URL.parse(fork_address).port == options.port) {
    options.port = (parseInt(options.port) + 1);
  }

  options.fork = fork_address + (block != null ? "@" + block : "");
}

var server = Ganache.server(options);

//console.log("Ganache CLI v" + pkg.version);
console.log("EthereumJS TestRPC v" + pkg.version + " (ganache-core: " + corepkg.version + ")");

server.listen(options.port, options.hostname, function(err, state) {
  if (err) {
    console.log(err);
    return;
  }
  console.log("");
  console.log("Available Accounts");
  console.log("==================");

  var accounts = state.accounts;
  var addresses = Object.keys(accounts);

  addresses.forEach(function(address, index) {
    var line = "(" + index + ") " + address;

    if (state.isUnlocked(address) == false) {
      line += " 🔒";
    }

    console.log(line);
  });

  console.log("");
  console.log("Private Keys");
  console.log("==================");

  addresses.forEach(function(address, index) {
    console.log("(" + index + ") " + accounts[address].secretKey.toString("hex"));
  });

  if (options.account_keys_path != null) {
    console.log("");
    console.log("Saving accounts and keys to " + options.account_keys_path);
    var obj = {}
    obj.addresses = accounts;
    obj.private_keys = {};
    addresses.forEach(function(address, index) {
       obj.private_keys[address] = accounts[address].secretKey.toString("hex");
    });
    var json = JSON.stringify(obj);
    fs.writeFile(options.account_keys_path, json, 'utf8',function(err){
      if(err) throw err;
    })
  }

  if (options.accounts == null) {
    console.log("");
    console.log("HD Wallet");
    console.log("==================");
    console.log("Mnemonic:      " + state.mnemonic);
    console.log("Base HD Path:  " + state.wallet_hdpath + "{account_index}")
  }

  if (options.gasPrice) {
    console.log("");
    console.log("Gas Price");
    console.log("==================");
    console.log(options.gasPrice);
  }

  if (options.gasLimit) {
    console.log("");
    console.log("Gas Limit");
    console.log("==================");
    console.log(options.gasLimit);
  }

  if (options.fork) {
    console.log("");
    console.log("Forked Chain");
    console.log("==================");
    console.log("Location:    " + fork_address);
    console.log("Block:       " + web3.toBigNumber(state.blockchain.fork_block_number).toString(10));
    console.log("Network ID:  " + state.net_version);
    console.log("Time:        " + (state.blockchain.startTime || new Date()).toString());
  }

  console.log("");
  console.log("Listening on " + (options.hostname || "localhost") + ":" + options.port);
});

process.on('uncaughtException', function(e) {
  console.log(e.stack);
  process.exit(1);
})

// See http://stackoverflow.com/questions/10021373/what-is-the-windows-equivalent-of-process-onsigint-in-node-js
if (process.platform === "win32") {
  require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
  })
  .on("SIGINT", function () {
    process.emit("SIGINT");
  });
}

process.on("SIGINT", function () {
  // graceful shutdown
  server.close(function(err) {
    if (err) {
      console.log(err.stack || err);
    }
    process.exit();
  });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

/* eslint-disable strict */

'use strict';

const program = require('commander');
const clc = require('cli-color');
const pkg = require('./package.json');
const installPeerDeps = require('./installPeerDeps');

const errorText = clc.red.bold('ERR');
const successText = clc.green.bold('SUCCESS');

const name = pkg.name;
const version = pkg.version;

function printPackageFormatError() {
  console.log(`${errorText} Please specify the package to install with peerDeps in the form of \`package\` or \`package@n.n.n\``);
  console.log(`${errorText} At this time you must provide the full semver version of the package.`);
  console.log(`${errorText} Alternatively, omit it to automatically install the latest version of the package.`);
}

program
  .version(version)
  .description('Installs the specified package along with correct peerDeps.')
  .option('-d, --dev', 'Install the package as a devDependency')
  .usage('<package>[@<version], default version is \'latest\'')
  .parse(process.argv);

console.log(clc.bold(`${name} v${version}`));

if (program.args.length > 1) {
  console.log(`${errorText} Please specify only one package at a time to install with peerDeps.`);
  process.exit(1);
}

if (program.args.length === 0) {
  console.log(`${errorText} Please specify a package to install with peerDeps.`);
  program.help();
  process.exit(1);
}

const packageString = program.args[0];
// eslint-disable-next-line no-useless-escape
const parsed = packageString.match(/^@?([\/\w-]+)(@([\d\.\w]+))?$/);
let packageName;
if (packageString[0] === '@') {
  packageName = `@${parsed[1]}`;
} else {
  packageName = parsed[1];
}
const packageVersion = parsed[3];

/* Tags can really be anything, so no version/tag validation for now
if (typeof packageVersion !== 'undefined') {
  const parsedVersion = packageVersion.match(/\d+\.\d+\.\d+/);
  if (typeof parsedVersion[0] === 'undefined') {
    printPackageFormatError();
    process.exit(1);
  }
}
*/

if (!packageName) {
  printPackageFormatError();
  process.exit(1);
}

installPeerDeps(packageName, packageVersion || 'latest', program.dev, (err) => {
  if (err) {
    console.log(`${errorText} ${err.message}`);
    process.exit(1);
  }
  console.log(`${successText} ${packageName} and its peerDeps were installed successfully.`);
  process.exit(0);
});
<commit_msg>set command name in cli.js<commit_after>#!/usr/bin/env node

/* eslint-disable strict */

'use strict';

const Command = require('commander').Command;
const clc = require('cli-color');
const pkg = require('./package.json');
const installPeerDeps = require('./installPeerDeps');

const program = new Command('install-peerdeps');
const errorText = clc.red.bold('ERR');
const successText = clc.green.bold('SUCCESS');

const name = pkg.name;
const version = pkg.version;

function printPackageFormatError() {
  console.log(`${errorText} Please specify the package to install with peerDeps in the form of \`package\` or \`package@n.n.n\``);
  console.log(`${errorText} At this time you must provide the full semver version of the package.`);
  console.log(`${errorText} Alternatively, omit it to automatically install the latest version of the package.`);
}

program
  .version(version)
  .description('Installs the specified package along with correct peerDeps.')
  .option('-d, --dev', 'Install the package as a devDependency')
  .usage('<package>[@<version>], default version is \'latest\'')
  .parse(process.argv);

console.log(clc.bold(`${name} v${version}`));

if (program.args.length > 1) {
  console.log(`${errorText} Please specify only one package at a time to install with peerDeps.`);
  process.exit(1);
}

if (program.args.length === 0) {
  console.log(`${errorText} Please specify a package to install with peerDeps.`);
  program.help();
  process.exit(1);
}

const packageString = program.args[0];
// eslint-disable-next-line no-useless-escape
const parsed = packageString.match(/^@?([\/\w-]+)(@([\d\.\w]+))?$/);
let packageName;
if (packageString[0] === '@') {
  packageName = `@${parsed[1]}`;
} else {
  packageName = parsed[1];
}
const packageVersion = parsed[3];

if (!packageName) {
  printPackageFormatError();
  process.exit(1);
}

installPeerDeps(packageName, packageVersion || 'latest', program.dev, (err) => {
  if (err) {
    console.log(`${errorText} ${err.message}`);
    process.exit(1);
  }
  console.log(`${successText} ${packageName} and its peerDeps were installed successfully.`);
  process.exit(0);
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
(async () => {
  var difi = require('difi')
  var pkg = require('./package.json')
  var getHelpText = require('./lib/getHelpText')
  var query = process.argv[2]
  var argv = require('minimist')((process.argv.slice(2)))
  var opts = {
    dataset: argv.dataset,
    format: argv.format || 'yaml',
    query: {
      query: argv.query
    }
  }

  if (!query || process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) {
    console.log(getHelpText())
    process.exit(0)
  }

  if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) {
    console.log(pkg.version)
    process.exit(0)
  }

  if (query.indexOf('--') === -1) {
    opts.dataset = argv._[0]
  }

  try {
    const data = await difi(opts)
    console.log(opts.format === 'json' ? JSON.stringify(data, null, 2) : data)
  } catch (error) {
    console.error(error)
    process.exit(1)
  }
})()
<commit_msg>var => const (patch)<commit_after>#!/usr/bin/env node
(async () => {
  const difi = require('difi')
  const pkg = require('./package.json')
  const getHelpText = require('./lib/getHelpText')
  const query = process.argv[2]
  const argv = require('minimist')((process.argv.slice(2)))
  const opts = {
    dataset: argv.dataset,
    format: argv.format || 'yaml',
    query: {
      query: argv.query
    }
  }

  if (!query || process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) {
    console.log(getHelpText())
    process.exit(0)
  }

  if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) {
    console.log(pkg.version)
    process.exit(0)
  }

  if (query.indexOf('--') === -1) {
    opts.dataset = argv._[0]
  }

  try {
    const data = await difi(opts)
    console.log(opts.format === 'json' ? JSON.stringify(data, null, 2) : data)
  } catch (error) {
    console.error(error)
    process.exit(1)
  }
})()
<|endoftext|>


<commit_before>// @flow

export type Config = {
  disabledPages: string[],
  showUserDomainInput: boolean,
  defaultUserDomain: string,
  showOpenstackCurrentUserSwitch: boolean,
  useBarbicanSecrets: boolean,
  requestPollTimeout: number,
  sourceOptionsProviders: string[],
  instancesListBackgroundLoading: { default: number, [string]: number },
  sourceProvidersWithExtraOptions: Array<string | { name: string, envRequiredFields: string[] }>,
  destinationProvidersWithExtraOptions: Array<string | { name: string, envRequiredFields: string[] }>,
  providerSortPriority: { [providerName: string]: number }
  hiddenUsers: string[],
}
<commit_msg>Add missing comma to type file<commit_after>// @flow

export type Config = {
  disabledPages: string[],
  showUserDomainInput: boolean,
  defaultUserDomain: string,
  showOpenstackCurrentUserSwitch: boolean,
  useBarbicanSecrets: boolean,
  requestPollTimeout: number,
  sourceOptionsProviders: string[],
  instancesListBackgroundLoading: { default: number, [string]: number },
  sourceProvidersWithExtraOptions: Array<string | { name: string, envRequiredFields: string[] }>,
  destinationProvidersWithExtraOptions: Array<string | { name: string, envRequiredFields: string[] }>,
  providerSortPriority: { [providerName: string]: number },
  hiddenUsers: string[],
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

var Campfire = require('campfire').Campfire,
    cli = require('cli'),
    options = cli.parse(),
    fs = require('fs'),
    colors = require('colors'),
    username, roomid, token, users = {},
    fire, doUser, putMessage;

// Gets a user by id (either from memory or API) and calls the callback with the user.
doUser = function(id,callback){
  if (users[id])
    callback(users[id]);
  else
    fire.user(id,function(error,user){
      if (error)
        console.log(error);
      else
        callback(users[id] = user.user);
    });
};

// Calls the callback with a console-formatted version of the message from API.
putMessage = function(message,callback){
  var left = false;
  callback = callback ? callback : console.log;
  switch (message.type.replace(/Message/,'') {
    case "Timestamp":
      callback(message.createdAt.toString().blue);
      break;
    case "Kick":
      // For now deal with it like a LeaveMessage. Campfire seems to do the same.
    case "Leave":
      left = true;
    case "Enter":
      doUser(message.userId,function(user){
        callback(('* '+user.name).green+(' has '+(left?'left':'entered')+' the room.').magenta);
      });
      break;
    case "Text":
      doUser(message.userId,function(user){
        callback((user.name+': ').green+message.body.white.bold);
      });
      break;
    default:
      callback(("Don't yet understand message of type: "+message.type).red);
  }
};

if (options.u && options.r && options.t) {
  account = options.s;
  roomid = options.r;
  token = options.t;
} else {
  var file = options.f ? options.f : process.env.HOME+'/.campfire.json',
      opts = JSON.parse(fs.readFileSync(file));
  account = opts.subdomain;
  roomid = opts.roomid;
  token = opts.token;
}

fire = new Campfire({
  ssl:true,
  token:token,
  account:account
});

fire.join(roomid,function(error,room){
  if (error) {
    console.log(error);
    return;
  }

  // For the recent messages, this weird recursion is necessary to put them in order, due to the
  // asynchronous nature of both console.log and getting the user name.
  room.messages(function(error,messages){
    var next = function(body){
      console.log(body);
      if (messages.length != 0)
        putMessage(messages.shift(),next);
    }
    next("Starting...");
  });

  room.listen(putMessage);

  // Need a better REPL-like thing here, but at least this makes it useable.
  cli.withInput(function(line, newline, eof){
    if (!eof && line != "")
      room.message(line,'TextMessage');
  });
});
<commit_msg>add missing )<commit_after>#!/usr/bin/env node

var Campfire = require('campfire').Campfire,
    cli = require('cli'),
    options = cli.parse(),
    fs = require('fs'),
    colors = require('colors'),
    username, roomid, token, users = {},
    fire, doUser, putMessage;

// Gets a user by id (either from memory or API) and calls the callback with the user.
doUser = function(id,callback){
  if (users[id])
    callback(users[id]);
  else
    fire.user(id,function(error,user){
      if (error)
        console.log(error);
      else
        callback(users[id] = user.user);
    });
};

// Calls the callback with a console-formatted version of the message from API.
putMessage = function(message,callback){
  var left = false;
  callback = callback ? callback : console.log;
  switch (message.type.replace(/Message/,'')) {
    case "Timestamp":
      callback(message.createdAt.toString().blue);
      break;
    case "Kick":
      // For now deal with it like a LeaveMessage. Campfire seems to do the same.
    case "Leave":
      left = true;
    case "Enter":
      doUser(message.userId,function(user){
        callback(('* '+user.name).green+(' has '+(left?'left':'entered')+' the room.').magenta);
      });
      break;
    case "Text":
      doUser(message.userId,function(user){
        callback((user.name+': ').green+message.body.white.bold);
      });
      break;
    default:
      callback(("Don't yet understand message of type: "+message.type).red);
  }
};

if (options.u && options.r && options.t) {
  account = options.s;
  roomid = options.r;
  token = options.t;
} else {
  var file = options.f ? options.f : process.env.HOME+'/.campfire.json',
      opts = JSON.parse(fs.readFileSync(file));
  account = opts.subdomain;
  roomid = opts.roomid;
  token = opts.token;
}

fire = new Campfire({
  ssl:true,
  token:token,
  account:account
});

fire.join(roomid,function(error,room){
  if (error) {
    console.log(error);
    return;
  }

  // For the recent messages, this weird recursion is necessary to put them in order, due to the
  // asynchronous nature of both console.log and getting the user name.
  room.messages(function(error,messages){
    var next = function(body){
      console.log(body);
      if (messages.length != 0)
        putMessage(messages.shift(),next);
    }
    next("Starting...");
  });

  room.listen(putMessage);

  // Need a better REPL-like thing here, but at least this makes it useable.
  cli.withInput(function(line, newline, eof){
    if (!eof && line != "")
      room.message(line,'TextMessage');
  });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

var cases = require('to-case').cases,
    concat = require('concat-stream'),
    helpVersion = require('help-version')(usage());

function usage() {
  var exampleInput = 'one, two, and Three';

  var lines = [
    'Usage:  caser <option>',
    '',
    'Caser reads from stdin and writes to stdout.',
    '',
    'Options (input=' + JSON.stringify(exampleInput) + '):'
  ].concat(Object.keys(cases).map(function (caseType) {
    return '  --' + caseType + '\t' + cases[caseType](exampleInput);
  }));

  return lines.join('\n');
}

var toCaseFunction = function (arg) {
  if (arg.slice(0, 2) != '--') {
    return null;
  }
  return cases[arg.slice(2)] || null;
};

(function main(argv) {
  var caseFunction = toCaseFunction(argv[0]);

  if (argv.length != 1 || !caseFunction) {
    return helpVersion.help(1);
  }

  process.stdin.pipe(concat({ encoding: 'string' }, function (input) {
    console.log(caseFunction(input));
  }));
}(process.argv.slice(2)));
<commit_msg>Do not print extra newline at the end<commit_after>#!/usr/bin/env node
'use strict';

var cases = require('to-case').cases,
    concat = require('concat-stream'),
    helpVersion = require('help-version')(usage());

function usage() {
  var exampleInput = 'one, two, and Three';

  var lines = [
    'Usage:  caser <option>',
    '',
    'Caser reads from stdin and writes to stdout.',
    '',
    'Options (input=' + JSON.stringify(exampleInput) + '):'
  ].concat(Object.keys(cases).map(function (caseType) {
    return '  --' + caseType + '\t' + cases[caseType](exampleInput);
  }));

  return lines.join('\n');
}

var toCaseFunction = function (arg) {
  if (arg.slice(0, 2) != '--') {
    return null;
  }
  return cases[arg.slice(2)] || null;
};

(function main(argv) {
  var caseFunction = toCaseFunction(argv[0]);

  if (argv.length != 1 || !caseFunction) {
    return helpVersion.help(1);
  }

  process.stdin.pipe(concat({ encoding: 'string' }, function (input) {
    process.stdout.write(caseFunction(input));
  }));
}(process.argv.slice(2)));
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

var chokidar = require('chokidar')
  , child = require('child_process')
  , argv = require('yargs')
    .usage('Usage: $0 -c "command" -t file-or-dir')
    .command('chokidar-cmd', 'Watch directory or file for changes and run given command')
    .example('$0 -c "npm run less" -t src/styles', 'Run less build on changes to styles')
    .demand(['command', 'target'])
    .alias('command', 'c')
    .alias('target', 't')
    .boolean('verbose')
    .alias('verbose', 'v')
    .describe('verbose', 'Show verbose output')
    .boolean('quiet')
    .alias('quiet', 'q')
    .describe('quiet', 'Silence normal output')
    .help('help')
    .alias('help', 'h')
    .version(function() { return require('./package').version })
    .argv
  , watcher = chokidar.watch(argv.target, { persistent: true })
  , run = runner(argv.command)

watcher
  .on('error', logError)
  .on('change', run)

log('Watching ' + argv.target + ' and running command "' + argv.command + '" on changes')

function runner(command) {
  var running = false

  return function(path) {
    verboseLog('Path "' + path + '" changed')
    if (running) return
    running = true
    verboseLog('Executing command: ' + command)
    execAsync(command, function(err, output) {
      if (err) logError(err)
      else verboseLog('Command "' + command + '" completed successfully')

      running = false
    })
  }
}

function log(msg) {
  if (!argv.quiet) console.log('[chokidar-cmd]', msg)
}

function logError(err) {
  console.error('[chokidar-cmd] ERROR:', err)
}

function verboseLog(msg) {
  if (argv.verbose) log(msg)
}

function execAsync(cmd, callback) {
  var output = ''

  var c = child.exec(cmd, { env: process.env, maxBuffer: 20 * 1024 * 1024 }, function(err) {
    callback(err ? err : null, output)
  })

  c.stdout.on('data', function(data) {
    output += data
    if (!argv.quiet) process.stdout.write(data)
  })

  c.stderr.on('data', function(data) {
    output += data
    process.stderr.write(data)
  })

  return c
}
<commit_msg>Exit on chokidar error<commit_after>#!/usr/bin/env node
"use strict";

var chokidar = require('chokidar')
  , child = require('child_process')
  , argv = require('yargs')
    .usage('Usage: $0 -c "command" -t file-or-dir')
    .command('chokidar-cmd', 'Watch directory or file for changes and run given command')
    .example('$0 -c "npm run less" -t src/styles', 'Run less build on changes to styles')
    .demand(['command', 'target'])
    .alias('command', 'c')
    .alias('target', 't')
    .boolean('verbose')
    .alias('verbose', 'v')
    .describe('verbose', 'Show verbose output')
    .boolean('quiet')
    .alias('quiet', 'q')
    .describe('quiet', 'Silence normal output')
    .help('help')
    .alias('help', 'h')
    .version(function() { return require('./package').version })
    .argv
  , watcher = chokidar.watch(argv.target, { persistent: true })
  , run = runner(argv.command)

watcher
  .on('error', function(err) {
    logError(err)
    process.exit(1)
  })
  .on('change', run)

log('Watching ' + argv.target + ' and running command "' + argv.command + '" on changes')

function runner(command) {
  var running = false

  return function(path) {
    verboseLog('Path "' + path + '" changed')
    if (running) return
    running = true
    verboseLog('Executing command: ' + command)
    execAsync(command, function(err, output) {
      if (err) logError(err)
      else verboseLog('Command "' + command + '" completed successfully')

      running = false
    })
  }
}

function log(msg) {
  if (!argv.quiet) console.log('[chokidar-cmd]', msg)
}

function logError(err) {
  console.error('[chokidar-cmd] ERROR:', err)
}

function verboseLog(msg) {
  if (argv.verbose) log(msg)
}

function execAsync(cmd, callback) {
  var output = ''

  var c = child.exec(cmd, { env: process.env, maxBuffer: 20 * 1024 * 1024 }, function(err) {
    callback(err ? err : null, output)
  })

  c.stdout.on('data', function(data) {
    output += data
    if (!argv.quiet) process.stdout.write(data)
  })

  c.stderr.on('data', function(data) {
    output += data
    process.stderr.write(data)
  })

  return c
}
<|endoftext|>