<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* eslint-disable */ // TODO: fix me
'use strict';

// MODULES //

var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var isArray = require( '@stdlib/assert/is-array' );
var copy = require( '@stdlib/utils/copy' );
var defineProperty = require( '@stdlib/utils/define-property' );
var exp = require( '@stdlib/math/base/special/exp' );
var modifiedHuberLoss = require( './loss/modified_huber.js' );
var squaredHingeLoss = require( './loss/squared_hinge.js' );
var WeightVector = require( './weight_vector.js' );
var perceptron = require( './loss/perceptron.js' );
var hingeLoss = require( './loss/hinge.js' );
var logLoss = require( './loss/log.js' );
var getEta = require( './eta_factory.js' );
var DEFAULTS = require( './defaults.json' );
var validate = require( './validate.js' );

// MAIN //

/**
* Online learning for classification using stochastic gradient descent (SGD).
*
* ## Method
*
* The sub-gradient of the loss function is estimated for each datum and the classification model is updated incrementally, with a decreasing learning rate and regularization of the feature weights based on L2 regularization.
*
* ## References
*
* -   Shalev-Shwartz, S., Singer, Y., Srebro, N., & Cotter, A. (2011). Pegasos: Primal estimated sub-gradient solver for SVM. Mathematical Programming, 127(1), 3–30. doi:10.1007/s10107-010-0420-4
*
* @param {Object} [options] - options object
* @param {PositiveNumber} [options.epsilon=0.1] - insensitivity parameter
* @param {PositiveNumber} [options.eta0=0.02] - constant learning rate
* @param {PositiveNumber} [options.lambda=1e-3] - regularization parameter
* @param {string} [options.learningRate='basic'] - string denoting the learning rate to use. Can be `constant`, `pegasos`, or `basic`
* @param {string} [options.loss='log'] - string denoting the loss function to use. Can be `hinge`, `log`, `modifiedHuber`, `perceptron`, or `squaredHinge`
* @param {boolean} [options.intercept=true] - boolean indicating whether to include an intercept
* @throws {TypeError} must provide valid options
* @returns {Object} classification model
*
* @example
* var incrBinaryClassification = require( '@stdlib/streams/ml/incr/sgd-classification' );
*
* var model = incrBinaryClassification({
*    'intercept': true
*    'lambda': 1e-5
* });
*
* // Update model as observations come in:
* var y = 1;
* var x = [ 2.3, 1.0, 5.0 ];
* model.update( x, y );
*
* // Predict new observation:
* var yHat = model.predict( x );
*
* // Retrieve coefficients:
* var coefs = model.coefs;
*/
function incrBinaryClassification( options ) {
	var _nFeatures;
	var _lossfun;
	var _weights;
	var _getEta;
	var model;
	var opts;
	var err;
	var _it;

	opts = copy( DEFAULTS );
	if ( arguments.length > 0 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	_weights = null;
	// Initialize counter:
	_it = 1;

	// Set loss function depending on chosen model:
	switch ( opts.loss ) {
	case 'log':
		_lossfun = logLoss;
	break;
	case 'hinge':
		_lossfun = hingeLoss;
	break;
	case 'modifiedHuber':
		_lossfun = modifiedHuberLoss;
	break;
	case 'perceptron':
		_lossfun = perceptron;
	break;
	case 'squaredHinge':
		_lossfun = squaredHingeLoss;
	break;
	default:
		throw Error( 'invalid input value. `loss` option must be either `hinge`, `log`, `modifiedHuber`, `perceptron` or `squaredHinge`. Value: `' + opts.loss + '`' );
	}

	// Set learning rate:
	_getEta = getEta( opts.learningRate, opts.eta0, opts.lambda );

	/**
	* SGD classification model.
	*
	* @namespace SGDClassificationModel
	*/
	model = {};

	// Define coefficient getter:

	/**
	*  Model coefficients / feature weights.
	*
	* @name coefs
	* @memberof SGDClassificationModel
	* @type {Array}
	*
	* @example
	* // Retrieve coefficients:
	* var coefs = model.coefs;
	*/
	defineProperty( model, 'coefs', {
		'get': function getCoefs() {
			var ret;
			var i;

			ret = new Array( _weights.nWeights );
			for ( i = 0; i < ret.length; i++ ) {
				ret[ i ] = _weights._data[ i ] * _weights.scale;
			}
			return ret;
		},
		'configurable': false,
		'enumerable': false
	});

	/**
	* Update weights given new observations `y` and `x`.
	*
	* @name update
	* @memberof SGDClassificationModel
	* @type {Function}
	* @param {NumericArray} x - feature vector
	* @param {number} y - response value
	*
	* @example
	* // Update model as observations come in:
	* var y = 1;
	* var x = [ 2.3, 1.0, 5.0 ];
	* model.update( x, y );
	*/
	model.update = function update( x, y ) {
		var eta;

		if ( !_weights ) {
			_weights = new WeightVector( x.length, opts.intercept );
			_nFeatures = opts.intercept ? _weights.nWeights - 1 : _weights.nWeights;
		}

		if ( !isArray( x ) || x.length !== _nFeatures ) {
			throw new TypeError( 'invalid input value. First argument `x` must be an array of length ' + this.nFeatures + '. Value: `' + x + '`' );
		}
		if ( y !== -1 && y !== 1 ) {
			throw new TypeError( 'invalid input value. Second argument `y` must be +1 or -1. Value: `' + y + '`' );
		}

		// Get current learning rate...
		eta = _getEta();

		// Update weights depending on the chosen loss function...
		_lossfun( _weights, x, y, eta, opts.lambda );
	};

	/**
	* Predict response for a new observation with features `x`.
	*
	* @name predict
	* @memberof SGDClassificationModel
	* @type {Function}
	* @param {NumericArray} x - feature vector
	* @param {string} [type="link"] - `probability` or `link`
	* @returns {number} response value
	*
	* @example
	* // Predict new observation:
	* var x = [ 2.3, 5.3, 8.6 ];
	* var yHat = model.predict( x );
	*/
	model.predict = function predict( x, type ) {
		var wx;
		if ( !isArray( x ) || x.length !== _nFeatures ) {
			throw new TypeError( 'invalid input value. First argument `x` must be an array of length ' + this.nFeatures + '. Value: `' + x + '`' );
		}
		if ( arguments.length > 1 ) {
			if ( !isString( type ) || ( type !== 'link' && type !== 'probability' ) ) {
				throw new TypeError( 'invalid input value. Second argument `type` must be `probability` or `link`. Value: `' + x + '`' );
			}
		}
		wx = _weights.innerProduct( x );
		if ( type !== 'probability' ) {
			return wx;
		}
		// Case: type === 'probability'
		if ( _lossfun !== logLoss && _lossfun !== modifiedHuberLoss ) {
			throw new Error( 'probability predictions are only supported when `loss` is `log` or `modifiedHuber`. Value: `' + type + '`' );
		}

		return 1.0 / ( 1.0 + exp( -wx ) );
	};

	return model;
}

// EXPORTS //

module.exports = incrBinaryClassification;
<commit_msg>Fix require path<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* eslint-disable */ // TODO: fix me
'use strict';

// MODULES //

var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var isArray = require( '@stdlib/assert/is-array' );
var copy = require( '@stdlib/utils/copy' );
var defineProperty = require( '@stdlib/utils/define-property' );
var exp = require( '@stdlib/math/base/special/exp' );
var modifiedHuberLoss = require( './loss/modified_huber.js' );
var squaredHingeLoss = require( './loss/squared_hinge.js' );
var WeightVector = require( './weight_vector.js' );
var perceptron = require( './loss/perceptron.js' );
var hingeLoss = require( './loss/hinge.js' );
var logLoss = require( './loss/log.js' );
var getEta = require( './eta_factory.js' );
var DEFAULTS = require( './defaults.json' );
var validate = require( './validate.js' );

// MAIN //

/**
* Online learning for classification using stochastic gradient descent (SGD).
*
* ## Method
*
* The sub-gradient of the loss function is estimated for each datum and the classification model is updated incrementally, with a decreasing learning rate and regularization of the feature weights based on L2 regularization.
*
* ## References
*
* -   Shalev-Shwartz, S., Singer, Y., Srebro, N., & Cotter, A. (2011). Pegasos: Primal estimated sub-gradient solver for SVM. Mathematical Programming, 127(1), 3–30. doi:10.1007/s10107-010-0420-4
*
* @param {Object} [options] - options object
* @param {PositiveNumber} [options.epsilon=0.1] - insensitivity parameter
* @param {PositiveNumber} [options.eta0=0.02] - constant learning rate
* @param {PositiveNumber} [options.lambda=1e-3] - regularization parameter
* @param {string} [options.learningRate='basic'] - string denoting the learning rate to use. Can be `constant`, `pegasos`, or `basic`
* @param {string} [options.loss='log'] - string denoting the loss function to use. Can be `hinge`, `log`, `modifiedHuber`, `perceptron`, or `squaredHinge`
* @param {boolean} [options.intercept=true] - boolean indicating whether to include an intercept
* @throws {TypeError} must provide valid options
* @returns {Object} classification model
*
* @example
* var incrBinaryClassification = require( '@stdlib/streams/ml/incr/binary-classification' );
*
* var model = incrBinaryClassification({
*    'intercept': true
*    'lambda': 1e-5
* });
*
* // Update model as observations come in:
* var y = 1;
* var x = [ 2.3, 1.0, 5.0 ];
* model.update( x, y );
*
* // Predict new observation:
* var yHat = model.predict( x );
*
* // Retrieve coefficients:
* var coefs = model.coefs;
*/
function incrBinaryClassification( options ) {
	var _nFeatures;
	var _lossfun;
	var _weights;
	var _getEta;
	var model;
	var opts;
	var err;
	var _it;

	opts = copy( DEFAULTS );
	if ( arguments.length > 0 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	_weights = null;
	// Initialize counter:
	_it = 1;

	// Set loss function depending on chosen model:
	switch ( opts.loss ) {
	case 'log':
		_lossfun = logLoss;
	break;
	case 'hinge':
		_lossfun = hingeLoss;
	break;
	case 'modifiedHuber':
		_lossfun = modifiedHuberLoss;
	break;
	case 'perceptron':
		_lossfun = perceptron;
	break;
	case 'squaredHinge':
		_lossfun = squaredHingeLoss;
	break;
	default:
		throw Error( 'invalid input value. `loss` option must be either `hinge`, `log`, `modifiedHuber`, `perceptron` or `squaredHinge`. Value: `' + opts.loss + '`' );
	}

	// Set learning rate:
	_getEta = getEta( opts.learningRate, opts.eta0, opts.lambda );

	/**
	* SGD classification model.
	*
	* @namespace SGDClassificationModel
	*/
	model = {};

	// Define coefficient getter:

	/**
	*  Model coefficients / feature weights.
	*
	* @name coefs
	* @memberof SGDClassificationModel
	* @type {Array}
	*
	* @example
	* // Retrieve coefficients:
	* var coefs = model.coefs;
	*/
	defineProperty( model, 'coefs', {
		'get': function getCoefs() {
			var ret;
			var i;

			ret = new Array( _weights.nWeights );
			for ( i = 0; i < ret.length; i++ ) {
				ret[ i ] = _weights._data[ i ] * _weights.scale;
			}
			return ret;
		},
		'configurable': false,
		'enumerable': false
	});

	/**
	* Update weights given new observations `y` and `x`.
	*
	* @name update
	* @memberof SGDClassificationModel
	* @type {Function}
	* @param {NumericArray} x - feature vector
	* @param {number} y - response value
	*
	* @example
	* // Update model as observations come in:
	* var y = 1;
	* var x = [ 2.3, 1.0, 5.0 ];
	* model.update( x, y );
	*/
	model.update = function update( x, y ) {
		var eta;

		if ( !_weights ) {
			_weights = new WeightVector( x.length, opts.intercept );
			_nFeatures = opts.intercept ? _weights.nWeights - 1 : _weights.nWeights;
		}

		if ( !isArray( x ) || x.length !== _nFeatures ) {
			throw new TypeError( 'invalid input value. First argument `x` must be an array of length ' + this.nFeatures + '. Value: `' + x + '`' );
		}
		if ( y !== -1 && y !== 1 ) {
			throw new TypeError( 'invalid input value. Second argument `y` must be +1 or -1. Value: `' + y + '`' );
		}

		// Get current learning rate...
		eta = _getEta();

		// Update weights depending on the chosen loss function...
		_lossfun( _weights, x, y, eta, opts.lambda );
	};

	/**
	* Predict response for a new observation with features `x`.
	*
	* @name predict
	* @memberof SGDClassificationModel
	* @type {Function}
	* @param {NumericArray} x - feature vector
	* @param {string} [type="link"] - `probability` or `link`
	* @returns {number} response value
	*
	* @example
	* // Predict new observation:
	* var x = [ 2.3, 5.3, 8.6 ];
	* var yHat = model.predict( x );
	*/
	model.predict = function predict( x, type ) {
		var wx;
		if ( !isArray( x ) || x.length !== _nFeatures ) {
			throw new TypeError( 'invalid input value. First argument `x` must be an array of length ' + this.nFeatures + '. Value: `' + x + '`' );
		}
		if ( arguments.length > 1 ) {
			if ( !isString( type ) || ( type !== 'link' && type !== 'probability' ) ) {
				throw new TypeError( 'invalid input value. Second argument `type` must be `probability` or `link`. Value: `' + x + '`' );
			}
		}
		wx = _weights.innerProduct( x );
		if ( type !== 'probability' ) {
			return wx;
		}
		// Case: type === 'probability'
		if ( _lossfun !== logLoss && _lossfun !== modifiedHuberLoss ) {
			throw new Error( 'probability predictions are only supported when `loss` is `log` or `modifiedHuber`. Value: `' + type + '`' );
		}

		return 1.0 / ( 1.0 + exp( -wx ) );
	};

	return model;
}

// EXPORTS //

module.exports = incrBinaryClassification;
<|endoftext|>


<commit_before>$(document).ready(function(){
    'use strict';

    var sizes = ['thin', 'medium', 'wide'];

    // Returns a random integer between min (included) and max (excluded)
    function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    };

    // Initialize the Stacky plugin
    var stackyContainer = $('#panels').Stacky({
        fadeInSpeed: 'fast',
        scrollToSpeed: 600,
        panelDefaults: {
            content: '',
            navigation: {
                left: [
                    {
                        link: '#',
                        alt: 'Open a new panel',
                        linkClass: 'open-panel',
                        iconClass: 'fa fa-folder-open-o'
                    },
                    {
                        link: '#',
                        alt: 'Open a new floating panel',
                        linkClass: 'open-panel open-floating-panel',
                        iconClass: 'fa fa-folder-open'
                    }
                ]
            },
            onBeforeOpen: function($panel){
                console.log('Pushing', $panel);
            },
            onBeforeClose: function($panel){
                if(confirm("Closing a panel causes all floating panels depending on ti to trigger their close event. Do you want to continue?")){
                    console.log('Removed', $panel);
                }else{
                    return false;
                }
            }
        }
    });

    // Binds click to create new panels
    $(document).on('click', ".open-panel", function(){
        var self = $(this),
            afterPanel = self.closest('.panel'),
            isFloating = self.hasClass('open-floating-panel'),
            identifier = getRandomInt(0, 1000);

        if(afterPanel.length == 0){
            afterPanel = undefined;
        }

        var $panel = stackyContainer.data('Stacky').push({
            title: 'Panel ' + identifier,
            id: 'panel-' + identifier,
            floating: isFloating,
            size: sizes[getRandomInt(0, 3)],    // Create panels of random size
            after: isFloating ? afterPanel : undefined
        });
    });

});<commit_msg>Small change in demo<commit_after>$(document).ready(function(){
    'use strict';

    var sizes = ['thin', 'medium', 'wide'];

    // Returns a random integer between min (included) and max (excluded)
    function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    };

    // Initialize the Stacky plugin
    var stackyContainer = $('#panels').Stacky({
        fadeInSpeed: 'fast',
        scrollToSpeed: 600,
        panelDefaults: {
            content: '',
            navigation: {
                left: [
                    {
                        link: '#',
                        alt: 'Open a new panel',
                        linkClass: 'open-panel',
                        iconClass: 'fa fa-folder-open-o'
                    },
                    {
                        link: '#',
                        alt: 'Open a new floating panel',
                        linkClass: 'open-panel open-floating-panel',
                        iconClass: 'fa fa-folder-open'
                    }
                ]
            },
            onBeforeOpen: function($panel){
                console.log('Pushing', $panel);
            },
            onBeforeClose: function($panel){
                console.log('Removed', $panel);
            }
        }
    });

    // Binds click to create new panels
    $(document).on('click', ".open-panel", function(){
        var self = $(this),
            afterPanel = self.closest('.panel'),
            isFloating = self.hasClass('open-floating-panel'),
            identifier = getRandomInt(0, 1000);

        if(afterPanel.length == 0){
            afterPanel = undefined;
        }

        var $panel = stackyContainer.data('Stacky').push({
            title: 'Panel ' + identifier,
            id: 'panel-' + identifier,
            floating: isFloating,
            size: sizes[getRandomInt(0, 3)],    // Create panels of random size
            after: isFloating ? afterPanel : undefined
        });
    });

});<|endoftext|>


<commit_before>/*
 * build.js: Titanium Mobile CLI build command
 *
 * Copyright (c) 2012-2013, Appcelerator, Inc.  All Rights Reserved.
 * See the LICENSE file for more information.
 */

var appc = require('node-appc'),
	fields = require('fields'),
	fs = require('fs'),
	jsanalyze = require('titanium-sdk/lib/jsanalyze'),
	path = require('path'),
	sprintf = require('sprintf'),
	ti = require('titanium-sdk'),
	tiappxml = require('titanium-sdk/lib/tiappxml'),
	__ = appc.i18n(__dirname).__;

fields.setup({
	formatters: {
		error: function (err) {
			if (err instanceof Error) {
				return ('[ERROR] ' + err.message).red + '\n';
			}
			err = '' + err;
			return '\n' + (/^(\[ERROR\])/i.test(err) ? err : '[ERROR] ' + err.replace(/^Error\:/i, '').trim()).red;
		}
	},
	style: {
		accelerator: 'cyan'
	}
});

exports.cliVersion = '>=3.2.1';
exports.title = __('Build');
exports.desc = __('builds a project');
exports.extendedDesc = 'Builds an existing app or module project.';

exports.config = function (logger, config, cli) {
	fields.setup({ colors: cli.argv.colors });

	return function (finished) {
		cli.createHook('build.config', function (callback) {
			ti.platformOptions(logger, config, cli, 'build', function (platformConf) {
				var conf = {
					flags: {
						'build-only': {
							abbr: 'b',
							desc: __('only perform the build; if true, does not install or run the app')
						},
						force: {
							abbr: 'f',
							desc: __('force a full rebuild')
						},
						legacy: {
							desc: __('build using the old Python-based builder.py; deprecated')
						},
						'skip-js-minify': {
							default: false,
							desc: __('bypasses JavaScript minification; %s builds are never minified; only supported for %s and %s', 'simulator'.cyan, 'Android'.cyan, 'iOS'.cyan)
						}
					},
					options: appc.util.mix({
						platform: {
							abbr: 'p',
							callback: function (platform) {
								cli.argv.$originalPlatform = platform;
								platform = ti.resolvePlatform(platform);

								var p = platformConf[platform];
								p && p.options && Object.keys(p.options).forEach(function (name) {
									if (p.options[name].default && cli.argv[name] === undefined) {
										cli.argv[name] = p.options[name].default;
									}
								});

								return platform;
							},
							desc: __('the target build platform'),
							hint: __('platform'),
							order: 2,
							prompt: {
								label: __('Target platform'),
								error: __('Invalid platform'),
								validator: function (platform) {
									if (!platform) {
										throw new Error(__('Invalid platform'));
									} else if (ti.availablePlatforms.indexOf(platform) == -1) {
										throw new Error(__('Invalid platform: %s', platform));
									}
									return true;
								}
							},
							required: true,
							skipValueCheck: true,
							values: ti.targetPlatforms
						},
						'project-dir': {
							abbr: 'd',
							callback: function (projectDir) {
								if (projectDir === '') {
									// no option value was specified
									// check if current directory is a valid dir
									// if not output meaningful error message
									projectDir = conf.options['project-dir'].default;
									if (!fs.existsSync(path.join(projectDir, 'tiapp.xml'))) {
										return;
									}
								}

								// start file logging here
								patchLogger(logger, cli);

								// load the tiapp.xml
								try {
									var tiapp = cli.tiapp = new tiappxml(path.join(projectDir, 'tiapp.xml'));
								} catch (ex) {
									logger.error(ex);
									logger.log();
									process.exit(1);
								}

								tiapp.properties || (tiapp.properties = {});

								// make sure the tiapp.xml is sane
								ti.validateTiappXml(logger, config, tiapp);

								// check that the Titanium SDK version is correct
								if (!ti.validateCorrectSDK(logger, config, cli, 'build')) {
									throw new cli.GracefulShutdown();
								}

								return projectDir;
							},
							desc: __('the directory containing the project'),
							default: process.env.SOURCE_ROOT ? path.join(process.env.SOURCE_ROOT, '..', '..') : '.',
							order: 1,
							prompt: function (callback) {
								callback(fields.file({
									promptLabel: __('Where is the __project directory__?'),
									complete: true,
									showHidden: true,
									ignoreDirs: new RegExp(config.get('cli.ignoreDirs')),
									ignoreFiles: /.*/,
									validate: conf.options['project-dir'].validate
								}));
							},
							required: true,
							validate: function (projectDir, callback) {
								var isDefault = projectDir == conf.options['project-dir'].default;

								var dir = appc.fs.resolvePath(projectDir);

								if (!fs.existsSync(dir)) {
									return callback(new Error(__('Project directory does not exist')));
								}

								var tiappFile = path.join(dir, 'tiapp.xml'),
									root = path.resolve('/');

								// try to find the tiapp.xml
								while (!fs.existsSync(tiappFile)) {
									dir = path.dirname(dir);
									if (dir == root) {
										if (!isDefault) {
											callback(new Error(__('Invalid project directory "%s" because tiapp.xml not found', projectDir)));
											return;
										} else {
											callback(true);
											return;
										}
									}
									tiappFile = path.join(dir, 'tiapp.xml');
								}

								callback(null, dir);
							}
						}
					}, ti.commonOptions(logger, config)),
					platforms: platformConf
				};
				callback(null, conf);
			});
		})(function (err, result) {
			finished(result);
		});
	};
};

exports.validate = function (logger, config, cli) {
	// TODO: set the type to 'app' for now, but we'll need to determine if the project is an app or a module
	cli.argv.type = 'app';

	ti.validatePlatform(logger, cli, 'platform');

	// since we need validate() to be async, we return a function in which the cli
	// will immediately call
	return function (finished) {
		function next(result) {
			if (result !== false) {
				// no error, load the tiapp.xml plugins
				ti.loadPlugins(logger, config, cli, cli.argv['project-dir'], function () {
					finished(result);
				});
			} else {
				finished(result);
			}
		}

		// loads the platform specific bulid command and runs its validate() function
		var result = ti.validatePlatformOptions(logger, config, cli, 'build');
		if (result && typeof result == 'function') {
			result(next);
		} else {
			next(result);
		}
	};
};

exports.run = function (logger, config, cli, finished) {
	var platform = ti.resolvePlatform(cli.argv.platform),
		buildModule = path.join(__dirname, '..', '..', platform, 'cli', 'commands', '_build.js'),
		counter = 0;

	if (!fs.existsSync(buildModule)) {
		logger.error(__('Unable to find platform specific build command') + '\n');
		logger.log(__("Your SDK installation may be corrupt. You can reinstall it by running '%s'.", (cli.argv.$ + ' sdk update --force --default').cyan) + '\n');
		process.exit(1);
	}

	if (config.get('cli.sendAPIUsage', true)) {
		cli.on('build.finalize', function (builder) {
			var deployType = builder.deployType || cli.argv['deploy-type'] || null;
			if (deployType == 'production') {
				cli.addAnalyticsEvent('Titanium API Usage', {
					platform: platform,
					tisdkname: (ti.manifest && ti.manifest.name) || (cli.sdk && cli.sdk.name) || null,
					tisdkver: (ti.manifest && ti.manifest.version) || (cli.sdk && cli.sdk.name) || null,
					deployType: deployType,
					target: builder.target || cli.argv.target || null,
					usage: jsanalyze.getAPIUsage()
				}, 'ti.apiusage');
			}
		});
	}

	require(buildModule).run(logger, config, cli, function (err) {
		if (!counter++) {
			var delta = appc.time.prettyDiff(cli.startTime, Date.now());
			if (err) {
				logger.error(__('Project failed to build after %s', delta));
				(err.message || err.toString()).trim().split('\n').forEach(function (msg) {
					logger.error(msg);
				});
				logger.log();
				process.exit(1);
			} else {
				logger.info(__('Project built successfully in %s', delta.cyan) + '\n');
			}

			finished();
		}
	});
};

/**
 * Monkey-patch the logger object to enable file logging during build
 * @param {Object} logger - The logger instance
 * @param {Object} cli - The CLI instance
 */
function patchLogger(logger, cli) {
	var origLoggerLog = logger.log,
		platform = ti.resolvePlatform(cli.argv.platform),
		logFileStream;
	// create our write stream
	logFileStream = fs.createWriteStream(path.join(cli.argv['project-dir'], 'build', 'build_' + platform + '.log'), { 'flags': 'w', 'encoding': 'ascii' });
	// write the banner to start out the log
	logFileStream.write(logBanner(cli));
	// override the existing log function
	logger.log = function() {
		// most of this copied from the CLI's logger.js logger.log() function
		var args = Array.prototype.slice.call(arguments),
			padLevels = logger.padLevels,
			prefix;

		// if there are no args (i.e. a blank line), we need at least one space
		args.length || args.unshift(' ');

		// if we're not being called from info/warn/error/debug, then set this as a general log entry
		args[0] in logger.levels || args.unshift('_');

		// turn off padding
		logger.padLevels = args[0] != '_';

		// get rid of any null args
		while (args.length && args[args.length-1] == null) args.pop();

		// if we're logging an error, we need to cast to a string so that sprintf doesn't complain
		if (args[1] instanceof Error || Object.prototype.toString.call(args[1]) == '[object Error]') {
			args[1] = (args[1].stack || args[1].toString()) + '\n';
		} else if (args[1] == null || args[1] == undefined) {
			args[1] = '';
		}

		typeof type != 'string' && (args[1] = ''+args[1]);

		// strip off starting full colons
		args[1] = args[1].replace(/:\s{1}/, ' ');

		// add [INFO] type prefixes for each line
		prefix = (args[0] != "_") ? "[" + args[0].toUpperCase() + "]" + ((args[0].length===5) ? '  ' : '   ') : "";

		// log it to our log file, stripping out the color codes
		logFileStream.write("\n" + prefix + args[1].replace(/\x1B\[\d+m/g, ''));

		// call the original logger with our cleaned up args
		origLoggerLog.apply(logger, [args[0], args.length > 2 ? sprintf.apply(null, args.slice(1)) : args[1]]);

		// restore padding
		logger.padLevels = padLevels;
	}
}

/**
* Outputs environment details at the top of the log file
* for each run of `titanium build`
* @param {Object} cli - The CLI instance
*
* See http://en.wikipedia.org/wiki/Darwin_%28operating_system%29#Release_history for
* os.release() to version mapping for OS X. (e.g. 14.0.0 is v10.10 Yosemite)
*/
function logBanner(cli) {
	var os = require('os');
	return '\n\n---------------------------------\n\n' +
		new Date().toLocaleString() + '\n\n' +
		'Build Environment \n' +
		'   Host OS         = ' + (os.platform()==='darwin' ? "OS X" : os.platform()) + ' ' + os.release() + ', ' + os.arch() + '\n'  +
		'   Target platform = ' + ti.resolvePlatform(cli.argv.platform) + '\n'  +
		'   CLI version     = ' + cli.version + '\n'  +
		'   SDK version     = ' + cli.argv.sdk + '\n' +
		'   SDK path        = ' + cli.sdk.path + '\n' +
		'   Node version    = ' + process.version + '\n' +
		'   Command         = ' + cli.argv.$ + ' ' + cli.argv.$_.join(' ') + '\n' +
		'\n';
}<commit_msg>[TIMOB-18074] Fixed bug where the build directory may not exist and needs to be created before writing the build log file.<commit_after>/*
 * build.js: Titanium Mobile CLI build command
 *
 * Copyright (c) 2012-2013, Appcelerator, Inc.  All Rights Reserved.
 * See the LICENSE file for more information.
 */

var appc = require('node-appc'),
	fields = require('fields'),
	fs = require('fs'),
	jsanalyze = require('titanium-sdk/lib/jsanalyze'),
	path = require('path'),
	sprintf = require('sprintf'),
	ti = require('titanium-sdk'),
	tiappxml = require('titanium-sdk/lib/tiappxml'),
	wrench = require('wrench'),
	__ = appc.i18n(__dirname).__;

fields.setup({
	formatters: {
		error: function (err) {
			if (err instanceof Error) {
				return ('[ERROR] ' + err.message).red + '\n';
			}
			err = '' + err;
			return '\n' + (/^(\[ERROR\])/i.test(err) ? err : '[ERROR] ' + err.replace(/^Error\:/i, '').trim()).red;
		}
	},
	style: {
		accelerator: 'cyan'
	}
});

exports.cliVersion = '>=3.2.1';
exports.title = __('Build');
exports.desc = __('builds a project');
exports.extendedDesc = 'Builds an existing app or module project.';

exports.config = function (logger, config, cli) {
	fields.setup({ colors: cli.argv.colors });

	return function (finished) {
		cli.createHook('build.config', function (callback) {
			ti.platformOptions(logger, config, cli, 'build', function (platformConf) {
				var conf = {
					flags: {
						'build-only': {
							abbr: 'b',
							desc: __('only perform the build; if true, does not install or run the app')
						},
						force: {
							abbr: 'f',
							desc: __('force a full rebuild')
						},
						legacy: {
							desc: __('build using the old Python-based builder.py; deprecated')
						},
						'skip-js-minify': {
							default: false,
							desc: __('bypasses JavaScript minification; %s builds are never minified; only supported for %s and %s', 'simulator'.cyan, 'Android'.cyan, 'iOS'.cyan)
						}
					},
					options: appc.util.mix({
						platform: {
							abbr: 'p',
							callback: function (platform) {
								cli.argv.$originalPlatform = platform;
								platform = ti.resolvePlatform(platform);

								var p = platformConf[platform];
								p && p.options && Object.keys(p.options).forEach(function (name) {
									if (p.options[name].default && cli.argv[name] === undefined) {
										cli.argv[name] = p.options[name].default;
									}
								});

								return platform;
							},
							desc: __('the target build platform'),
							hint: __('platform'),
							order: 2,
							prompt: {
								label: __('Target platform'),
								error: __('Invalid platform'),
								validator: function (platform) {
									if (!platform) {
										throw new Error(__('Invalid platform'));
									} else if (ti.availablePlatforms.indexOf(platform) == -1) {
										throw new Error(__('Invalid platform: %s', platform));
									}
									return true;
								}
							},
							required: true,
							skipValueCheck: true,
							values: ti.targetPlatforms
						},
						'project-dir': {
							abbr: 'd',
							callback: function (projectDir) {
								if (projectDir === '') {
									// no option value was specified
									// check if current directory is a valid dir
									// if not output meaningful error message
									projectDir = conf.options['project-dir'].default;
									if (!fs.existsSync(path.join(projectDir, 'tiapp.xml'))) {
										return;
									}
								}

								// start file logging here
								patchLogger(logger, cli);

								// load the tiapp.xml
								try {
									var tiapp = cli.tiapp = new tiappxml(path.join(projectDir, 'tiapp.xml'));
								} catch (ex) {
									logger.error(ex);
									logger.log();
									process.exit(1);
								}

								tiapp.properties || (tiapp.properties = {});

								// make sure the tiapp.xml is sane
								ti.validateTiappXml(logger, config, tiapp);

								// check that the Titanium SDK version is correct
								if (!ti.validateCorrectSDK(logger, config, cli, 'build')) {
									throw new cli.GracefulShutdown();
								}

								return projectDir;
							},
							desc: __('the directory containing the project'),
							default: process.env.SOURCE_ROOT ? path.join(process.env.SOURCE_ROOT, '..', '..') : '.',
							order: 1,
							prompt: function (callback) {
								callback(fields.file({
									promptLabel: __('Where is the __project directory__?'),
									complete: true,
									showHidden: true,
									ignoreDirs: new RegExp(config.get('cli.ignoreDirs')),
									ignoreFiles: /.*/,
									validate: conf.options['project-dir'].validate
								}));
							},
							required: true,
							validate: function (projectDir, callback) {
								var isDefault = projectDir == conf.options['project-dir'].default;

								var dir = appc.fs.resolvePath(projectDir);

								if (!fs.existsSync(dir)) {
									return callback(new Error(__('Project directory does not exist')));
								}

								var tiappFile = path.join(dir, 'tiapp.xml'),
									root = path.resolve('/');

								// try to find the tiapp.xml
								while (!fs.existsSync(tiappFile)) {
									dir = path.dirname(dir);
									if (dir == root) {
										if (!isDefault) {
											callback(new Error(__('Invalid project directory "%s" because tiapp.xml not found', projectDir)));
											return;
										} else {
											callback(true);
											return;
										}
									}
									tiappFile = path.join(dir, 'tiapp.xml');
								}

								callback(null, dir);
							}
						}
					}, ti.commonOptions(logger, config)),
					platforms: platformConf
				};
				callback(null, conf);
			});
		})(function (err, result) {
			finished(result);
		});
	};
};

exports.validate = function (logger, config, cli) {
	// TODO: set the type to 'app' for now, but we'll need to determine if the project is an app or a module
	cli.argv.type = 'app';

	ti.validatePlatform(logger, cli, 'platform');

	// since we need validate() to be async, we return a function in which the cli
	// will immediately call
	return function (finished) {
		function next(result) {
			if (result !== false) {
				// no error, load the tiapp.xml plugins
				ti.loadPlugins(logger, config, cli, cli.argv['project-dir'], function () {
					finished(result);
				});
			} else {
				finished(result);
			}
		}

		// loads the platform specific bulid command and runs its validate() function
		var result = ti.validatePlatformOptions(logger, config, cli, 'build');
		if (result && typeof result == 'function') {
			result(next);
		} else {
			next(result);
		}
	};
};

exports.run = function (logger, config, cli, finished) {
	var platform = ti.resolvePlatform(cli.argv.platform),
		buildModule = path.join(__dirname, '..', '..', platform, 'cli', 'commands', '_build.js'),
		counter = 0;

	if (!fs.existsSync(buildModule)) {
		logger.error(__('Unable to find platform specific build command') + '\n');
		logger.log(__("Your SDK installation may be corrupt. You can reinstall it by running '%s'.", (cli.argv.$ + ' sdk update --force --default').cyan) + '\n');
		process.exit(1);
	}

	if (config.get('cli.sendAPIUsage', true)) {
		cli.on('build.finalize', function (builder) {
			var deployType = builder.deployType || cli.argv['deploy-type'] || null;
			if (deployType == 'production') {
				cli.addAnalyticsEvent('Titanium API Usage', {
					platform: platform,
					tisdkname: (ti.manifest && ti.manifest.name) || (cli.sdk && cli.sdk.name) || null,
					tisdkver: (ti.manifest && ti.manifest.version) || (cli.sdk && cli.sdk.name) || null,
					deployType: deployType,
					target: builder.target || cli.argv.target || null,
					usage: jsanalyze.getAPIUsage()
				}, 'ti.apiusage');
			}
		});
	}

	require(buildModule).run(logger, config, cli, function (err) {
		if (!counter++) {
			var delta = appc.time.prettyDiff(cli.startTime, Date.now());
			if (err) {
				logger.error(__('Project failed to build after %s', delta));
				(err.message || err.toString()).trim().split('\n').forEach(function (msg) {
					logger.error(msg);
				});
				logger.log();
				process.exit(1);
			} else {
				logger.info(__('Project built successfully in %s', delta.cyan) + '\n');
			}

			finished();
		}
	});
};

/**
 * Monkey-patch the logger object to enable file logging during build
 * @param {Object} logger - The logger instance
 * @param {Object} cli - The CLI instance
 */
function patchLogger(logger, cli) {
	var origLoggerLog = logger.log,
		platform = ti.resolvePlatform(cli.argv.platform),
		buildDir = path.join(cli.argv['project-dir'], 'build'),
		logFileStream;

	fs.existsSync(buildDir) || wrench.mkdirSyncRecursive(buildDir);

	// create our write stream
	logFileStream = fs.createWriteStream(path.join(buildDir, 'build_' + platform + '.log'), { 'flags': 'w', 'encoding': 'ascii' });

	// write the banner to start out the log
	logFileStream.write(logBanner(cli));

	// override the existing log function
	logger.log = function() {
		// most of this copied from the CLI's logger.js logger.log() function
		var args = Array.prototype.slice.call(arguments),
			padLevels = logger.padLevels,
			prefix;

		// if there are no args (i.e. a blank line), we need at least one space
		args.length || args.unshift(' ');

		// if we're not being called from info/warn/error/debug, then set this as a general log entry
		args[0] in logger.levels || args.unshift('_');

		// turn off padding
		logger.padLevels = args[0] != '_';

		// get rid of any null args
		while (args.length && args[args.length-1] == null) args.pop();

		// if we're logging an error, we need to cast to a string so that sprintf doesn't complain
		if (args[1] instanceof Error || Object.prototype.toString.call(args[1]) == '[object Error]') {
			args[1] = (args[1].stack || args[1].toString()) + '\n';
		} else if (args[1] == null || args[1] == undefined) {
			args[1] = '';
		}

		typeof type != 'string' && (args[1] = ''+args[1]);

		// strip off starting full colons
		args[1] = args[1].replace(/:\s{1}/, ' ');

		// add [INFO] type prefixes for each line
		prefix = (args[0] != "_") ? "[" + args[0].toUpperCase() + "]" + ((args[0].length===5) ? '  ' : '   ') : "";

		// log it to our log file, stripping out the color codes
		logFileStream.write("\n" + prefix + args[1].replace(/\x1B\[\d+m/g, ''));

		// call the original logger with our cleaned up args
		origLoggerLog.apply(logger, [args[0], args.length > 2 ? sprintf.apply(null, args.slice(1)) : args[1]]);

		// restore padding
		logger.padLevels = padLevels;
	}
}

/**
* Outputs environment details at the top of the log file
* for each run of `titanium build`
* @param {Object} cli - The CLI instance
*
* See http://en.wikipedia.org/wiki/Darwin_%28operating_system%29#Release_history for
* os.release() to version mapping for OS X. (e.g. 14.0.0 is v10.10 Yosemite)
*/
function logBanner(cli) {
	var os = require('os');
	return '\n\n---------------------------------\n\n' +
		new Date().toLocaleString() + '\n\n' +
		'Build Environment \n' +
		'   Host OS         = ' + (os.platform()==='darwin' ? "OS X" : os.platform()) + ' ' + os.release() + ', ' + os.arch() + '\n'  +
		'   Target platform = ' + ti.resolvePlatform(cli.argv.platform) + '\n'  +
		'   CLI version     = ' + cli.version + '\n'  +
		'   SDK version     = ' + cli.argv.sdk + '\n' +
		'   SDK path        = ' + cli.sdk.path + '\n' +
		'   Node version    = ' + process.version + '\n' +
		'   Command         = ' + cli.argv.$ + ' ' + cli.argv.$_.join(' ') + '\n' +
		'\n';
}<|endoftext|>


<commit_before>/**
 * Created by Devon Timaeus on 10/10/2014.
 */

var fs = require("fs");

var modes = require('js-git/lib/modes');
var repo = {};
var treeHash = {};
require('js-git/mixins/mem-db')(repo);
require('js-git/mixins/create-tree')(repo);

/*
 TODO: Change to using async file and directory creation, but for now, this makes the logic easier to track
 */

function writeRepoToDirectory(porObject, path) {
    var repoOutputPath = path + "/" + porObject['repoName'];

    try {
        fs.mkdirSync(repoOutputPath);
    } finally {
        // Initialize the repo
        treeHash = repo.createTree({
            dirName: {
                mode: modes.tree}});

        recursivelyBuildRepoDirectory(porObject, repoOutputPath, 0);
        // Create a test commit
        // repo.saveAs("commit", {
        //     author: {
        //         name: "John Kulczak",
        //         email: "j_kulczak@hotmail.com"
        //     },
        //     tree: treeHash,
        //     message: "Test commit\n"
        // });
        gitRepoCreation(path + porObject['repoName']);
    }
}

function writeCommitToDirectory(porObject, path, commitMessage){
    var repoOutputPath = path + "/" + porObject['repoName'];

    try {
        fs.mkdirSync(repoOutputPath);
    } finally {
        // Initialize the repo
        treeHash = repo.createTree({
            dirName: {
                mode: modes.tree}
            });
        console.log('point 1');
        prepareRepo(path, porObject['repoName']);
        console.log('point 2');
        recursivelyBuildRepoDirectory(porObject, repoOutputPath, 0);
        console.log('point 3');
        gitCommit(path + porObject['repoName'], commitMessage);
        console.log('point 4');
    }
}

function prepareRepo(path, repoName){
    // I know these function are gross right now, they can be cleaned up /after/ everything works += .
    var cdShell = 'cd ' + path;
    var moveShell = 'mv ' + repoName + '/.git ./';
    var removeShell = 'rm -rf ' + repoName + '/*';
    var replaceShell = 'mv ./.git ./' + repoName;
    var removeGitShell = 'rm -rf ./.git';

    var command = cdShell + ' && ' + moveShell + ' && ' + removeShell + ' && ' + replaceShell + ' && ' + removeGitShell;

    shellOut(command);
}

function gitRepoCreation(repoPath){
    var cdShell = 'cd ' + repoPath;
    var initShell = 'git init '
    var addAllShell = 'git add *';
    var commitShell = 'git commit -m \" repo initialized \"';

    var command = cdShell + ' && ' + initShell + ' && ' + addAllShell + ' && ' + commitShell;

    shellOut(command);
}

function gitCommit(repoPath, commitMessage){
    var cdShell = 'cd ' + repoPath;
    var addAllShell = 'git add *';
    var commitMessage = commitMessage || 'repo initialized';
    var commitShell = 'git commit -m \"' + commitMessage + ' \"';

    var command = cdShell + ' && ' + addAllShell + ' && ' + commitShell

    shellOut(command);
}

function shellOut(command){    var asyncblock = require('asyncblock');
    var exec = require('child_process').exec;
    var child;

    asyncblock(function(flow){
        exec(command,
            function (error, stdout, stderr) {
                console.log('stdout: ' + stdout);
                if (error !== null) {
                     console.log('exec error: ' + error);
                }
            },
            flow.add('flag')
        );
        flow.wait('flag');
    });
}

function recursivelyBuildRepoDirectory(porObject, outputPath) {
    var changes;
    if (porObject.children) {
        var id = "";
        if (porObject.porID) {
            id = porObject.porID;
        }
        var newDirectory = outputPath + "/" + id;
        if (newDirectory != outputPath + "/") {
            fs.mkdirSync(newDirectory);
        }

        var childrenOrder = [];
        for (var index = 0; index < porObject.children.length; index++) {
            // TODO: Filename to include extension here, or no?
            var childPORID = porObject.children[index].porID ? porObject.children[index].porID : index + ".txt";
            childrenOrder.push(childPORID);
            recursivelyBuildRepoDirectory(porObject.children[index], newDirectory, index);
        }

        var metaFileJson = {};

        if (porObject.metadata) {
            metaFileJson = {
                tag: porObject.metadata.tag,
                attributes: porObject.metadata.attributes,
                constructionOrder: childrenOrder
            }
        } else {
            metaFileJson = {
                constructionOrder: childrenOrder
            }
        }

        var metadataJSON = JSON.stringify(metaFileJson);
        fs.writeFileSync(newDirectory + "/" + "metadata.json", metadataJSON, "utf8");

        // Create a new blob for this file and add it to the repo tree
        changes = [
            {
                path: newDirectory + "/" + "metadata.json",
                mode: modes.file,
                content: metadataJSON
            }
        ];

        changes.base = treeHash;
        treeHash = repo.createTree(changes);

    } else {
        var filepath = outputPath + "/" + porObject.porID + ".txt";
        fs.writeFileSync(filepath, porObject.value);
        // Create a new blob for this file and add it to the repo tree
        changes = [
            {
                path: filepath,
                mode: modes.file,
                content: porObject.value
            }
        ];

        changes.base = treeHash;
        treeHash = repo.createTree(changes);
    }
}

module.exports = {
    writeRepoToDirectory: writeRepoToDirectory,
    writeCommitToDirectory: writeCommitToDirectory
};<commit_msg>Cleaned up prints and code<commit_after>/**
 * Created by Devon Timaeus on 10/10/2014.
 */

var fs = require("fs");

var modes = require('js-git/lib/modes');
var repo = {};
var treeHash = {};
require('js-git/mixins/mem-db')(repo);
require('js-git/mixins/create-tree')(repo);

/*
 TODO: Change to using async file and directory creation, but for now, this makes the logic easier to track
 */

function writeRepoToDirectory(porObject, path) {
    var repoOutputPath = path + "/" + porObject['repoName'];

    try {
        fs.mkdirSync(repoOutputPath);
    } finally {
        // Initialize the repo
        treeHash = repo.createTree({
            dirName: {
                mode: modes.tree}});

        recursivelyBuildRepoDirectory(porObject, repoOutputPath, 0);
        gitRepoCreation(path + porObject['repoName']);
    }
}

function writeCommitToDirectory(porObject, path, commitMessage){
    var repoOutputPath = path + "/" + porObject['repoName'];

    try {
        fs.mkdirSync(repoOutputPath);
    } finally {
        // Initialize the repo
        treeHash = repo.createTree({
            dirName: {
                mode: modes.tree}
            });
        prepareRepo(path, porObject['repoName']);
        recursivelyBuildRepoDirectory(porObject, repoOutputPath, 0);
        gitCommit(path + porObject['repoName'], commitMessage);
    }
}

function prepareRepo(path, repoName){
    var command = '';

    command += 'cd ' + path + ' && ';
    command += 'mv ' + repoName + '/.git ./' + ' && ';
    command += 'rm -rf ' + repoName + '/*' + ' && ';
    command += 'mv ./.git ./' + repoName + ' && ';
    command += 'rm -rf ./.git';

    shellOut(command);
}

function gitRepoCreation(repoPath){
    var command = '';

    command += 'cd ' + repoPath + ' && ';
    command += 'git init ' + ' && ';
    command += 'git add *' + ' && ';
    command += 'git commit -m \" repo initialized \"';

    shellOut(command);
}

function gitCommit(repoPath, commitMessage){
    var command = '';

    message = commitMessage || 'repo initialized';

    command += 'cd ' + repoPath + ' && ';
    command += 'git add -A *' + ' && ';
    command += 'git commit -m \"' + message + ' \"';

    shellOut(command);
}

function shellOut(command){    var asyncblock = require('asyncblock');
    var exec = require('child_process').exec;
    var child;

    asyncblock(function(flow){
        exec(command,
            function (error, stdout, stderr) {
                console.log('stdout: ' + stdout);
                if (error !== null) {
                     console.log('exec error: ' + error);
                }
            },
            flow.add('flag')
        );
        flow.wait('flag');
    });
}

function recursivelyBuildRepoDirectory(porObject, outputPath) {
    var changes;
    if (porObject.children) {
        var id = "";
        if (porObject.porID) {
            id = porObject.porID;
        }
        var newDirectory = outputPath + "/" + id;
        if (newDirectory != outputPath + "/") {
            fs.mkdirSync(newDirectory);
        }

        var childrenOrder = [];
        for (var index = 0; index < porObject.children.length; index++) {
            // TODO: Filename to include extension here, or no?
            var childPORID = porObject.children[index].porID ? porObject.children[index].porID : index + ".txt";
            childrenOrder.push(childPORID);
            recursivelyBuildRepoDirectory(porObject.children[index], newDirectory, index);
        }

        var metaFileJson = {};

        if (porObject.metadata) {
            metaFileJson = {
                tag: porObject.metadata.tag,
                attributes: porObject.metadata.attributes,
                constructionOrder: childrenOrder
            }
        } else {
            metaFileJson = {
                constructionOrder: childrenOrder
            }
        }

        var metadataJSON = JSON.stringify(metaFileJson);
        fs.writeFileSync(newDirectory + "/" + "metadata.json", metadataJSON, "utf8");

        // Create a new blob for this file and add it to the repo tree
        changes = [
            {
                path: newDirectory + "/" + "metadata.json",
                mode: modes.file,
                content: metadataJSON
            }
        ];

        changes.base = treeHash;
        treeHash = repo.createTree(changes);

    } else {
        var filepath = outputPath + "/" + porObject.porID + ".txt";
        fs.writeFileSync(filepath, porObject.value);
        // Create a new blob for this file and add it to the repo tree
        changes = [
            {
                path: filepath,
                mode: modes.file,
                content: porObject.value
            }
        ];

        changes.base = treeHash;
        treeHash = repo.createTree(changes);
    }
}

module.exports = {
    writeRepoToDirectory: writeRepoToDirectory,
    writeCommitToDirectory: writeCommitToDirectory
};<|endoftext|>


<commit_before>placeholder
<commit_msg>[FEATURE] Monitor blockchain and record transactions in gatewayd.<commit_after>/*

 Run this deamon process alongside gatewayd:

     GATEWAYD_PATH=/path/to/gatewayd pm2 start deposits-manager.js

 The `gatewayd` object accesses the database models via the process
 environment to record crptyo coin addresses and transactions in
 gatewayd for processing and sending onward.

*/

const gatewayd = require(process.env.GATEWAYD_PATH);
const blockchain = require('blockchain-account-monitor');
const ExternalAccount = gatewayd.data.models.externalAccounts;
const ExternalTransaction = gatewayd.data.models.externalTransactions;

const monitor = new BlockchainAccountMonitor({
  blockchainClient:  new BlockchainClient(
    gatewayd.config.get('DOGECOIND')
  ),
  onBlock: function(block, next) {
    block.forEach(function(transaction) {
      ExternalAccount.findOrCreate({
        where: {
          uid: transaction.address,
          name: 'dogecoin'
        }
      })
      .then(function(externalAccount) {
        return ExternalTransaction.create({
          uid: transaction.hash,
          amount: transaction.amount,
          currency: 'DOG',
          external_account_id: externalAccount.id
        })
      })
      .then(function() {
        gatewayd.config.set('LAST_BLOCK_HASH', transaction.blockhash);
        next();
      })
      .error(function(error) {
        gatewayd.config.set('LAST_BLOCK_HASH', transaction.blockhash);
        next();
      });
    });
  },
  timeout: 5000
});

monitor.lastBlockHash = config.get('LAST_BLOCK_HASH');

monitor.start();
<|endoftext|>


<commit_before>var os=require('os');
var util=require('util');
var EventEmitter = require('events').EventEmitter;
var dgram = require('dgram');
var log = require('./log').logger('detection');

var OK = "YES I M !\0";
var ERR = "I DNT UNDRSTND !\0";
var HOSTNAME = "U NAME ?\0";
var REQ = "R U A SBT ?\0";
var default_port = 24862; // = 7777 without conversion

var start = function(port) {
	var socket = dgram.createSocket('udp4');
	var that = this;
	var Port = port || default_port;
		socket.bind(Port);

		socket.on("message", function ( data, rinfo ) {
			if(data.toString() == REQ)
			{
				log.info('scan in progress by '+ rinfo.address);
				socket.send(new Buffer(OK), 0, OK.length, rinfo.port, rinfo.address, function (err) {
							if (err) {
								console.log(err);
							}
							else {
								//console.log("reply yes to "+rinfo.address+" on port "+rinfo.port);
							}
						});
			}
			else if(data.toString() == HOSTNAME) // if the device is a sbt, continue the dialog.
			{
				//console.log("hostname asked");
				var result = {};
				result.hostname= os.hostname();
				result.networks=[];
				Object.keys(os.networkInterfaces()).forEach(function(key,index,arr){ //val = ip adresses , key = name of interface
					var networks_list = this;
					networks_list[key].forEach(function(val2,key2,arr2){
						if (val2.internal === false && val2.family === 'IPv4')
						{
							result.networks.push({'interface' : key , 'ip_address' : val2.address});
						}
					});
				},os.networkInterfaces());
				socket.send(new Buffer(JSON.stringify(result)), 0, JSON.stringify(result).length, rinfo.port, rinfo.address, function (err) {
					if (err) log.error(err);
							//console.log("ask info");
					});
				that.emit('client_scan',rinfo.address);
			}
			else
			{
				log.info("[detection_tool.js] received from "+rinfo.address+" : unknown message : '"+ data.toString() +"'");
			}
		});

	this.on('newListener', function(listener) {});

};
util.inherits(start , EventEmitter);
module.exports = start;
<commit_msg>add server_port accessible from the detection service<commit_after>var os=require('os');
var util=require('util');
var EventEmitter = require('events').EventEmitter;
var dgram = require('dgram');
var log = require('./log').logger('detection');
var settings = require('./settings');

var OK = "YES I M !\0";
var ERR = "I DNT UNDRSTND !\0";
var HOSTNAME = "U NAME ?\0";
var REQ = "R U A SBT ?\0";
var default_port = 24862; // = 7777 without conversion

var start = function(port) {
	var socket = dgram.createSocket('udp4');
	var that = this;
	var Port = port || default_port;
		socket.bind(Port);

		socket.on("message", function ( data, rinfo ) {
			if(data.toString() == REQ)
			{
				log.info('scan in progress by '+ rinfo.address);
				socket.send(new Buffer(OK), 0, OK.length, rinfo.port, rinfo.address, function (err) {
							if (err) {
								console.log(err);
							}
							else {
								//console.log("reply yes to "+rinfo.address+" on port "+rinfo.port);
							}
						});
			}
			else if(data.toString() == HOSTNAME) // if the device is a sbt, continue the dialog.
			{
				//console.log("hostname asked");
				var result = {};
				result.hostname= os.hostname();
				result.networks=[];
				result.port = settings.server_port;
				Object.keys(os.networkInterfaces()).forEach(function(key,index,arr){ //val = ip adresses , key = name of interface
					var networks_list = this;
					networks_list[key].forEach(function(val2,key2,arr2){
						if (val2.internal === false && val2.family === 'IPv4')
						{
							result.networks.push({'interface' : key , 'ip_address' : val2.address});
						}
					});
				},os.networkInterfaces());
				socket.send(new Buffer(JSON.stringify(result)), 0, JSON.stringify(result).length, rinfo.port, rinfo.address, function (err) {
					if (err) log.error(err);
							//console.log("ask info");
					});
				that.emit('client_scan',rinfo.address);
			}
			else
			{
				log.info("[detection_tool.js] received from "+rinfo.address+" : unknown message : '"+ data.toString() +"'");
			}
		});

	this.on('newListener', function(listener) {});

};
util.inherits(start , EventEmitter);
module.exports = start;
<|endoftext|>


<commit_before>function redirect (state, toState, role, loggedIn, ev) {

	switch (toState) {

		// ADMIN-ONLY STATES

		case 'main.import-students':
		case 'main.newprofessor':
		case 'main.reports':
		case 'main.settlement':
		case 'main.admin-dashboard':
		case 'main.newclass':
		case 'main.approve-hours':
		case 'main.classes':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role !== 'admin')
				goToDashboard(state, role, ev);

			break;

		// ADMIN-TEACHER STATES

		case 'main.edit-hours':
		case 'main.project':
		case 'main.evaluateproject':
		case 'main.addproject':
		case 'main.editproject':
		case 'main.projects':
		case 'main.section':
		case 'main.sections':
		case 'main.newsection':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role === 'student')
				goToDashboard(state, role, ev);

			break;

		// TEACHER-ONLY STATES

		case 'main.professor-dashboard':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role !== 'professor')
				goToDashboard(state, role, ev);

			break;

		// STUDENT-ONLY STATES

		case 'main.student-dashboard':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role !== 'student')
				goToDashboard(state, role, ev);

			break;

		case 'landing':
		case 'landing.login':
		case 'landing.enable-student':
		case 'main.activateprofessor':
			if (loggedIn)
				goToDashboard(state, role, ev);
			break;

		default:
			ev.preventDefault();
			break;

	}

}

function goToDashboard (state, role, ev) {
	state.go(`main.${role}-dashboard`);
	ev.preventDefault();
}

function goToLanding (state, ev) {
	state.go(`landing.login`);
	ev.preventDefault();
}

module.exports = redirect;<commit_msg>Add edit-section state to redirect<commit_after>function redirect (state, toState, role, loggedIn, ev) {

	switch (toState) {

		// ADMIN-ONLY STATES

		case 'main.import-students':
		case 'main.newprofessor':
		case 'main.reports':
		case 'main.settlement':
		case 'main.admin-dashboard':
		case 'main.new-class':
		case 'main.edit-class':
		case 'main.approve-hours':
		case 'main.classes':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role !== 'admin')
				goToDashboard(state, role, ev);

			break;

		// ADMIN-TEACHER STATES

		case 'main.edit-hours':
		case 'main.project':
		case 'main.evaluateproject':
		case 'main.addproject':
		case 'main.editproject':
		case 'main.projects':
		case 'main.section':
		case 'main.sections':
		case 'main.newsection':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role === 'student')
				goToDashboard(state, role, ev);

			break;

		// TEACHER-ONLY STATES

		case 'main.professor-dashboard':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role !== 'professor')
				goToDashboard(state, role, ev);

			break;

		// STUDENT-ONLY STATES

		case 'main.student-dashboard':
			if (!loggedIn)
				goToLanding(state, ev);

			else if (role !== 'student')
				goToDashboard(state, role, ev);

			break;

		case 'landing':
		case 'landing.login':
		case 'landing.enable-student':
		case 'main.activateprofessor':
			if (loggedIn)
				goToDashboard(state, role, ev);
			break;

		default:
			ev.preventDefault();
			break;

	}

}

function goToDashboard (state, role, ev) {
	state.go(`main.${role}-dashboard`);
	ev.preventDefault();
}

function goToLanding (state, ev) {
	state.go(`landing.login`);
	ev.preventDefault();
}

module.exports = redirect;<|endoftext|>


<commit_before>(function() {

    enchant.DomLayer = enchant.Class.create(enchant.Group, {
        initialize: function() {
            var game = enchant.Game.instance;
            var that = this;
            enchant.Group.call(this);

            this.width = this._width = game.width;
            this.height = this._height = game.height;

            this._touchEventTarget = null;

            this._frameBuffer = new enchant.DomView(this.width, this.height);
            this._domManager = new enchant.DomManager(this, 'div');
            this._domManager.layer = this;
            this._frameBuffer.element.appendChild(this._domManager.element);

            this._frameBuffer.element.style.position = 'absolute';
            this._frameBuffer.element.style[enchant.ENV.VENDOR_PREFIX + 'TransformOrigin'] = '0 0';
            this._frameBuffer.element.style[enchant.ENV.VENDOR_PREFIX + 'Transform'] = 'scale(' + enchant.Game.instance.scale + ')';

            var start = [
                enchant.Event.ENTER,
                enchant.Event.ADDED_TO_SCENE
            ];
            var end = [
                enchant.Event.EXIT,
                enchant.Event.REMOVED_FROM_SCENE
            ];
            start.forEach(function(type) {
                this.addEventListener(type, this._startRendering);
            }, this);
            end.forEach(function(type) {
                this.addEventListener(type, this._stopRendering);
            }, this);

            var __onchildadded = function(e) {
                var child = e.node;
                var next = e.next;
                var self = e.target;
                if (child.childNodes) {
                    child.addEventListener('childadded', __onchildadded);
                    child.addEventListener('childremoved', __onchildremoved);
                }
                child._updateCoordinate();
                var nextManager = next ? next._domManager : null;
                attachDomManager.call(child);
                self._domManager.addManager(child._domManager, nextManager);
                child._domManager.layer = self;
                rendering.call(child);
            };

            var __onchildremoved = function(e) {
                var child = e.node;
                var self = e.target;
                if (child.childNodes) {
                    child.removeEventListener('childadded', __onchildadded);
                    child.removeEventListener('childremoved', __onchildremoved);
                }
                self._domManager.removeManager(child._domManager);
                detachDomManager.call(child, that._colorManager);
            };

            this.addEventListener('childremoved', __onchildremoved);
            this.addEventListener('childadded', __onchildadded);

            this._onexitframe = function() {
                rendering.call(that);
            };
        },
        _startRendering: function() {
            enchant.Game.instance.addEventListener('exitframe', this._onexitframe);
        },
        _stopRendering: function() {
            enchant.Game.instance.removeEventListener('exitframe', this._onexitframe);
        },
        _determineEventTarget: function() {
            if (this._touchEventTarget) {
                if (this._touchEventTarget !== this) {
                    return this._touchEventTarget;
                }
            }
            return null;
        }
    });

    var nodesWalker = function(pre, post) {
        pre = pre || function() {
        };
        post = post || function() {
        };
        var walker = function() {
            pre.apply(this, arguments);
            var child;
            if (this.childNodes) {
                for (var i = 0, l = this.childNodes.length; i < l; i++) {
                    child = this.childNodes[i];
                    walker.apply(child, arguments);
                }
            }
            post.apply(this, arguments);
        };
        return walker;
    };

    var attachDomManager = nodesWalker(function() {
        if (!this._domManager) {
            if (this instanceof enchant.Group) {
                this._domManager = new enchant.DomlessManager(this);
            } else {
                this._domManager = new enchant.DomManager(this, 'div');
            }
        }
    });

    var detachDomManager = nodesWalker(function() {
        delete this._domManager;
    });

    var rendering = nodesWalker(function() {
        if (this._dirty) {
            this._domManager.render();
            if (typeof this.cssUpdate === 'function') {
                this.cssUpdate();
            }
            this._dirty = false;
        }
    });

enchant.Label.prototype.cssUpdate = function() {
    this._domManager.element.innerHTML = this._text;
    this._domManager.element.style.font = this._font;
    this._domManager.element.style.color = this._color;
    this._domManager.element.style.textAlign = this._textAlign;
};

enchant.Sprite.prototype.cssUpdate = function() {
    var element = this._domManager.element;
    if (this._image) {
        if (this._image._css) {
            element.style.backgroundImage = this._image._css;
            element.style.backgroundPosition =
                -this._frameLeft + 'px ' +
                -this._frameTop + 'px';
        } else if (element.firstChild) {
            // TODO new Surface
        }
    }
};

}());
<commit_msg>add _element to DomLayer and remove extra css scaling<commit_after>(function() {

    enchant.DomLayer = enchant.Class.create(enchant.Group, {
        initialize: function() {
            var game = enchant.Game.instance;
            var that = this;
            enchant.Group.call(this);

            this.width = this._width = game.width;
            this.height = this._height = game.height;

            this._touchEventTarget = null;

            this._frameBuffer = new enchant.DomView(this.width, this.height);
            this._domManager = new enchant.DomManager(this, 'div');
            this._domManager.layer = this;
            this._frameBuffer.element.appendChild(this._domManager.element);

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

            // TODO
            this._element = this._frameBuffer.element;

            var start = [
                enchant.Event.ENTER,
                enchant.Event.ADDED_TO_SCENE
            ];
            var end = [
                enchant.Event.EXIT,
                enchant.Event.REMOVED_FROM_SCENE
            ];
            start.forEach(function(type) {
                this.addEventListener(type, this._startRendering);
            }, this);
            end.forEach(function(type) {
                this.addEventListener(type, this._stopRendering);
            }, this);

            var __onchildadded = function(e) {
                var child = e.node;
                var next = e.next;
                var self = e.target;
                if (child.childNodes) {
                    child.addEventListener('childadded', __onchildadded);
                    child.addEventListener('childremoved', __onchildremoved);
                }
                child._updateCoordinate();
                var nextManager = next ? next._domManager : null;
                attachDomManager.call(child);
                self._domManager.addManager(child._domManager, nextManager);
                child._domManager.layer = self;
                rendering.call(child);
            };

            var __onchildremoved = function(e) {
                var child = e.node;
                var self = e.target;
                if (child.childNodes) {
                    child.removeEventListener('childadded', __onchildadded);
                    child.removeEventListener('childremoved', __onchildremoved);
                }
                self._domManager.removeManager(child._domManager);
                detachDomManager.call(child, that._colorManager);
            };

            this.addEventListener('childremoved', __onchildremoved);
            this.addEventListener('childadded', __onchildadded);

            this._onexitframe = function() {
                rendering.call(that);
            };
        },
        _startRendering: function() {
            enchant.Game.instance.addEventListener('exitframe', this._onexitframe);
        },
        _stopRendering: function() {
            enchant.Game.instance.removeEventListener('exitframe', this._onexitframe);
        },
        _determineEventTarget: function() {
            if (this._touchEventTarget) {
                if (this._touchEventTarget !== this) {
                    return this._touchEventTarget;
                }
            }
            return null;
        }
    });

    var nodesWalker = function(pre, post) {
        pre = pre || function() {
        };
        post = post || function() {
        };
        var walker = function() {
            pre.apply(this, arguments);
            var child;
            if (this.childNodes) {
                for (var i = 0, l = this.childNodes.length; i < l; i++) {
                    child = this.childNodes[i];
                    walker.apply(child, arguments);
                }
            }
            post.apply(this, arguments);
        };
        return walker;
    };

    var attachDomManager = nodesWalker(function() {
        if (!this._domManager) {
            if (this instanceof enchant.Group) {
                this._domManager = new enchant.DomlessManager(this);
            } else {
                this._domManager = new enchant.DomManager(this, 'div');
            }
        }
    });

    var detachDomManager = nodesWalker(function() {
        delete this._domManager;
    });

    var rendering = nodesWalker(function() {
        if (this._dirty) {
            this._domManager.render();
            if (typeof this.cssUpdate === 'function') {
                this.cssUpdate();
            }
            this._dirty = false;
        }
    });

enchant.Label.prototype.cssUpdate = function() {
    this._domManager.element.innerHTML = this._text;
    this._domManager.element.style.font = this._font;
    this._domManager.element.style.color = this._color;
    this._domManager.element.style.textAlign = this._textAlign;
};

enchant.Sprite.prototype.cssUpdate = function() {
    var element = this._domManager.element;
    if (this._image) {
        if (this._image._css) {
            element.style.backgroundImage = this._image._css;
            element.style.backgroundPosition =
                -this._frameLeft + 'px ' +
                -this._frameTop + 'px';
        } else if (element.firstChild) {
            // TODO new Surface
        }
    }
};

}());
<|endoftext|>


<commit_before>goog.provide('ojster');
goog.provide('ojster.StringWriter');
goog.provide('ojster.Template');

goog.require('goog.dom');
goog.require('goog.dom.NodeType');
goog.require('goog.dom.TagName');
goog.require('goog.string');

/**
 * @constructor
 */
ojster.StringWriter = function () {
  /** @type {!Array.<number|string|null>} */
  this.buff = [];
};

/**
 * @param {...(number|string|null)} var_args
 */
ojster.StringWriter.prototype.write = function (var_args) {
  this.buff.push.apply(this.buff, arguments);
};

/**
 * @return {string}
 */
ojster.StringWriter.prototype.done = function () {
  return this.buff.join('');
};

/**
 * @param {Object=} opt_data
 * @param {Object=} opt_ctx
 * @param {ojster.StringWriter=} opt_writer
 * @constructor
 */
ojster.Template = function (opt_data, opt_ctx, opt_writer) {
  /** @type {Object} */
  this.data = opt_data || null;
  /** @type {Object} */
  this.ctx = opt_ctx || null;
  /** @type {ojster.StringWriter} */
  this.writer = opt_writer || null;
  /** @type {!Object} */
  this.vars = {};
  /** @type {string} */
  this.baseCssName = '';

  this.init();
};

ojster.Template.prototype.init = goog.nullFunction;

/**
 * @param {function (this:ojster.Template)} setupFunc
 * @return {!ojster.Template}
 */
ojster.Template.prototype.setup = function (setupFunc) {
  setupFunc.call(this);
  return this;
};

/**
 * @return {string}
 */
ojster.Template.prototype.getBaseCssName = function () {
  return this.baseCssName;
};

/**
 * @param {string} baseCssName
 */
ojster.Template.prototype.setBaseCssName = function (baseCssName) {
  this.baseCssName = baseCssName;
};

/**
 * @param {string?} str
 * @return {string?}
 */
ojster.Template.prototype.escape = function (str) {
  return ojster.escape(str);
};

/**
 * @return {!ojster.StringWriter}
 */
Template.prototype.createWriter = function () {
  return new StringWriter();
};

/**
 * @return {string}
 */
ojster.Template.prototype.render = function () {
  // ensure we have a writer
  if (goog.isNull(this.writer)) {
    this.writer = this.createWriter();
  }

  // render
  this.renderBlockMain();
  return this.writer.done();
};

/**
 * @param {ojster.Template} template
 */
ojster.Template.prototype.renderTo = function (template) {
  this.writer = template.writer;
  this.renderBlockMain();
};

ojster.Template.prototype.renderBlockMain = goog.abstractMethod;

// functions

/**
 * @param {string?} str
 * @param {boolean=} opt_isLikelyToContainHtmlChars Don't perform a check to see
 *     if the character needs replacing - use this option if you expect each of
 *     the characters to appear often. Leave false if you expect few html
 *     characters to occur in your strings, such as if you are escaping HTML.
 * @return {string?}
 */
ojster.escape = function (str, opt_isLikelyToContainHtmlChars) {
  if (!goog.isNull(str)) {
    str = goog.string.htmlEscape(str, opt_isLikelyToContainHtmlChars);
  }
  return str;
};

/**
 * @param {Element} element
 * @param {ojster.Template} template
 * @return {Element}
 */
ojster.fillElement = function (element, template) {
  element.innerHTML = template.render();
  return element;
};

/**
 * @param {ojster.Template} template
 * @param {goog.dom.DomHelper=} opt_domHelper
 * @return {!Element}
 */
ojster.createElement = function (template, opt_domHelper) {
  /** @type {goog.dom.DomHelper} */
  var dom = opt_domHelper || goog.dom.getDomHelper();
  /** @type {!Element} */
  var wrapper = dom.createElement(goog.dom.TagName.DIV);
  wrapper.innerHTML = template.render();

  if (wrapper.childNodes.length == 1) {
    /** @type {!Element} */
    var firstChild = wrapper.firstChild;

    if (firstChild.nodeType == goog.dom.NodeType.ELEMENT) {
      return firstChild;
    }
  }

  return wrapper;
};

/**
 * @param {ojster.Template} template
 * @param {goog.dom.DomHelper=} opt_domHelper
 * @return {Node}
 */
ojster.createFragment = function (template, opt_domHelper) {
  var dom = opt_domHelper || goog.dom.getDomHelper();
  return dom.htmlToDocumentFragment(template.render());
};
<commit_msg>Fixed typos to repair compiler.<commit_after>goog.provide('ojster');
goog.provide('ojster.StringWriter');
goog.provide('ojster.Template');

goog.require('goog.dom');
goog.require('goog.dom.NodeType');
goog.require('goog.dom.TagName');
goog.require('goog.string');

/**
 * @constructor
 */
ojster.StringWriter = function () {
  /** @type {!Array.<number|string|null>} */
  this.buff = [];
};

/**
 * @param {...(number|string|null)} var_args
 */
ojster.StringWriter.prototype.write = function (var_args) {
  this.buff.push.apply(this.buff, arguments);
};

/**
 * @return {string}
 */
ojster.StringWriter.prototype.done = function () {
  return this.buff.join('');
};

/**
 * @param {Object=} opt_data
 * @param {Object=} opt_ctx
 * @param {ojster.StringWriter=} opt_writer
 * @constructor
 */
ojster.Template = function (opt_data, opt_ctx, opt_writer) {
  /** @type {Object} */
  this.data = opt_data || null;
  /** @type {Object} */
  this.ctx = opt_ctx || null;
  /** @type {ojster.StringWriter} */
  this.writer = opt_writer || null;
  /** @type {!Object} */
  this.vars = {};
  /** @type {string} */
  this.baseCssName = '';

  this.init();
};

ojster.Template.prototype.init = goog.nullFunction;

/**
 * @param {function (this:ojster.Template)} setupFunc
 * @return {!ojster.Template}
 */
ojster.Template.prototype.setup = function (setupFunc) {
  setupFunc.call(this);
  return this;
};

/**
 * @return {string}
 */
ojster.Template.prototype.getBaseCssName = function () {
  return this.baseCssName;
};

/**
 * @param {string} baseCssName
 */
ojster.Template.prototype.setBaseCssName = function (baseCssName) {
  this.baseCssName = baseCssName;
};

/**
 * @param {string?} str
 * @return {string?}
 */
ojster.Template.prototype.escape = function (str) {
  return ojster.escape(str);
};

/**
 * @return {!ojster.StringWriter}
 */
ojster.Template.prototype.createWriter = function () {
  return new ojster.StringWriter();
};

/**
 * @return {string}
 */
ojster.Template.prototype.render = function () {
  // ensure we have a writer
  if (goog.isNull(this.writer)) {
    this.writer = this.createWriter();
  }

  // render
  this.renderBlockMain();
  return this.writer.done();
};

/**
 * @param {ojster.Template} template
 */
ojster.Template.prototype.renderTo = function (template) {
  this.writer = template.writer;
  this.renderBlockMain();
};

ojster.Template.prototype.renderBlockMain = goog.abstractMethod;

// functions

/**
 * @param {string?} str
 * @param {boolean=} opt_isLikelyToContainHtmlChars Don't perform a check to see
 *     if the character needs replacing - use this option if you expect each of
 *     the characters to appear often. Leave false if you expect few html
 *     characters to occur in your strings, such as if you are escaping HTML.
 * @return {string?}
 */
ojster.escape = function (str, opt_isLikelyToContainHtmlChars) {
  if (!goog.isNull(str)) {
    str = goog.string.htmlEscape(str, opt_isLikelyToContainHtmlChars);
  }
  return str;
};

/**
 * @param {Element} element
 * @param {ojster.Template} template
 * @return {Element}
 */
ojster.fillElement = function (element, template) {
  element.innerHTML = template.render();
  return element;
};

/**
 * @param {ojster.Template} template
 * @param {goog.dom.DomHelper=} opt_domHelper
 * @return {!Element}
 */
ojster.createElement = function (template, opt_domHelper) {
  /** @type {goog.dom.DomHelper} */
  var dom = opt_domHelper || goog.dom.getDomHelper();
  /** @type {!Element} */
  var wrapper = dom.createElement(goog.dom.TagName.DIV);
  wrapper.innerHTML = template.render();

  if (wrapper.childNodes.length == 1) {
    /** @type {!Element} */
    var firstChild = wrapper.firstChild;

    if (firstChild.nodeType == goog.dom.NodeType.ELEMENT) {
      return firstChild;
    }
  }

  return wrapper;
};

/**
 * @param {ojster.Template} template
 * @param {goog.dom.DomHelper=} opt_domHelper
 * @return {Node}
 */
ojster.createFragment = function (template, opt_domHelper) {
  var dom = opt_domHelper || goog.dom.getDomHelper();
  return dom.htmlToDocumentFragment(template.render());
};
<|endoftext|>


<commit_before>import { Tracker } from "meteor/tracker";
import { trackPageWhenReady } from "./helpers";
import { _IronRouter } from "./routers";
import { SETTINGS } from "./constants";

const initIronRouter = function initIronRouter() {
  if (_IronRouter) {
    _IronRouter.onRun(function ironRouterOnRun() {
      const router = this;
      if (SETTINGS.autorun !== false) {
        Tracker.afterFlush(() => {
          trackPageWhenReady(router.route.getName());
        });
      }
      this.next();
    });
  }
};

export { initIronRouter };
<commit_msg>improve style, removed brackets<commit_after>import { Tracker } from "meteor/tracker";
import { trackPageWhenReady } from "./helpers";
import { _IronRouter } from "./routers";
import { SETTINGS } from "./constants";

const initIronRouter = function initIronRouter() {
  if (_IronRouter) {
    _IronRouter.onRun(function ironRouterOnRun() {
      const router = this;
      if (SETTINGS.autorun !== false) {
        Tracker.afterFlush(() => trackPageWhenReady(router.route.getName()));
      }
      this.next();
    });
  }
};

export { initIronRouter };
<|endoftext|>