<commit_before>// ControllerRouter class

'use strict';

var includes             = require('es5-ext/array/#/contains')
  , customError          = require('es5-ext/error/custom')
  , identity             = require('es5-ext/function/identity')
  , constant             = require('es5-ext/function/constant')
  , assign               = require('es5-ext/object/assign')
  , ensureCallable       = require('es5-ext/object/valid-callable')
  , ensureObject         = require('es5-ext/object/valid-object')
  , ensureStringifiable  = require('es5-ext/object/validate-stringifiable-value')
  , forEach              = require('es5-ext/object/for-each')
  , endsWith             = require('es5-ext/string/#/ends-with')
  , d                    = require('d')
  , autoBind             = require('d/auto-bind')
  , lazy                 = require('d/lazy')
  , isPromise            = require('is-promise')
  , compareDynamicRoutes = require('./lib/compare-dynamic-routes')
  , isStatic             = require('./lib/is-token-static')
  , resolvePathMeta      = require('./lib/resolve-path-meta')
  , ensurePath           = require('./lib/ensure-path')

  , push = Array.prototype.push, slice = Array.prototype.slice, apply = Function.prototype.apply
  , create = Object.create, defineProperty = Object.defineProperty, stringify = JSON.stringify
  , routeCallIdIndex = 0;

var ControllerRouter = module.exports = Object.defineProperties(function (routes/*, options*/) {
	var options;
	// Validate initialization
	if (!(this instanceof ControllerRouter)) return new ControllerRouter(routes, arguments[1]);
	options = Object(arguments[1]);
	this.constructor.ensureRoutes(routes, options);

	if (options.eventProto != null) {
		// Override default event prototype
		defineProperty(this, '_eventProto', d(ensureObject(options.eventProto)));
	}

	defineProperty(this, 'routes', d(routes));

	// Configure internal routes map
	forEach(this.constructor.normalizeRoutes(routes, options), function (conf, path) {
		var pathData = resolvePathMeta(path);
		if (pathData.static) {
			this._staticRoutes[path] = conf;
			return;
		}
		if (!this._dynamicRoutes[pathData.tokens.length]) {
			this._dynamicRoutes[pathData.tokens.length] = [];
		}
		pathData.conf = conf;
		pathData.matchPositionsLength = pathData.matchPositions.length;
		this._dynamicRoutes[pathData.tokens.length].push(pathData);
	}, this);
	forEach(this._dynamicRoutes, function (data) { data.sort(compareDynamicRoutes); });

	// Whether route should resolve with promise or not
	if (options.promiseResultImplementation) {
		defineProperty(this, 'Promise', d(ensureCallable(options.promiseResultImplementation)));
	}
}, {
	// Validates provided routes map
	ensureRoutes: d(function (routes) {
		forEach(ensureObject(routes), function (conf, path) {
			var isDynamic;
			ensureObject(conf);
			ensurePath(path);
			if (path !== '/') isDynamic = !path.split('/').every(isStatic);
			if (typeof conf === 'function') {
				if (isDynamic) {
					throw customError("Missing match function for " + stringify(path), 'MISSING_MATCH');
				}
				return;
			}
			if (typeof conf.controller !== 'function') {
				throw customError("Invalid controller for " + stringify(path), 'INVALID_CONTROLLER');
			}
			if (typeof conf.match !== 'function') {
				if (isDynamic) {
					throw customError("Invalid match function for " + stringify(path), 'INVALID_MATCH');
				}
				return;
			}
			if (!isDynamic) {
				throw customError("Missing regular expression in path " + stringify(path),
					'MISSING_PATH_REGEX');
			}
		});
		return routes;
	}),
	// Normalizes routes to bare ControllerRouter format. If ControllerRouter extension
	// provides more sophisticated routes format, this should be a function which transforms it
	// directly to map as understood by ControllerRouter
	normalizeRoutes: d(identity)
});

Object.defineProperties(ControllerRouter.prototype, assign({
	_resolveResult: d(function (result) {
		if (result && isPromise(result.result)) return result.result.then(resolvedResult => {
			result.result = resolvedResult;
			return result;
		});
		return this.Promise ? this.Promise.resolve(result) : result;
	}),
	_resolveController: d(function (fn) {
		if (!this.Promise) {
			this.lastRouteData.result = fn();
		} else {
			try {
				this.lastRouteData.result = fn();
			} catch (e) {
				return this.Promise.reject(e);
			}
		}
		return this._resolveResult(this.lastRouteData);
	}),

	// Routes path to controller and provides an event to be used for controller invocation
	routeEvent: d(function (event, path/*, …controllerArgs*/) {
		var pathTokens, controllerArgs = slice.call(arguments, 2), conf, initConf, controller
		  , asyncResult, callId = ++routeCallIdIndex;

		ensureObject(event);
		path = ensureStringifiable(path);

		// Preprepare route data
		this.lastRouteData = { event: event };

		// Do not proceed for no path
		if (!path) return this._resolveResult(false);

		// Resolve path for route resolution
		if (path[0] === '/') path = path.slice(1);
		if (endsWith.call(path, '/')) path = path.slice(0, -1);
		event.path = path || '/';

		// Handle eventual static path
		conf = this._staticRoutes[path || '/'];
		if (conf) {
			initConf = this.routes[path || '/'];
			controller = conf.controller || conf;
			this.lastRouteData.conf =  initConf;
			return this._resolveController(apply.bind(controller, event, controllerArgs));
		}

		// Handle eventual dynamic paths
		pathTokens = path.split('/');
		if (!this._dynamicRoutes[pathTokens.length]) return this._resolveResult(false);
		this._dynamicRoutes[pathTokens.length].some(function (data) {
			var args = [], matchResult;

			// Check whether path matches
			if (!data.tokens.every(function (token, index) {
					var pathToken = pathTokens[index];
					if (includes.call(data.matchPositions, index)) {
						if (!token.test(pathToken)) return false;
						args.push(pathToken);
						return true;
					}
					return (token === pathToken);
				})) {
				return false;
			}

			// Path matches, now resolve with `match` function
			matchResult = data.conf.match.apply(event, args);
			if (isPromise(matchResult)) {
				asyncResult = matchResult.then(function (isMatch) {
					if (!isMatch) return false;
					this.lastRouteData = {
						event: event,
						conf: this.routes[data.path]
					};
					if (callId !== routeCallIdIndex) {
						// Cancel route (as promises are concerned we need to reject)
						throw customError("Route cancelled, as next one took action", 'OUTDATED_ROUTE_CALL');
					}
					this.lastRouteData.result = apply.call(data.conf.controller, event, controllerArgs);
					return this._resolveResult(this.lastRouteData);
				}.bind(this));
			} else if (matchResult) {
				conf = data.conf;
				initConf = this.routes[data.path];
			}
			return true;
		}, this);

		// If `match` is asynchronous return promise
		if (asyncResult) return asyncResult;
		if (!conf) return this._resolveResult(false);
		this.lastRouteData.conf = initConf;
		return this._resolveController(apply.bind(conf.controller, event, controllerArgs));
	}),
	// Default prototype for an route event
	_eventProto: d(Object.prototype)
}, lazy({
	// Internal map of dynamic routes (those that contain regexp tokens)
	_dynamicRoutes: d(function () { return create(null); }),
	// Internal map of static routes (no regexp tokens)
	_staticRoutes: d(function () { return create(null); })
}), autoBind({
	// Routes path to controller
	route: d(function (path/*, …controllerArgs*/) {
		var args = [create(this._eventProto)];
		push.apply(args, arguments);
		return this.routeEvent.apply(this, args);
	})
})));
<commit_msg>fix: do not break ES5 support<commit_after>// ControllerRouter class

'use strict';

var includes             = require('es5-ext/array/#/contains')
  , customError          = require('es5-ext/error/custom')
  , identity             = require('es5-ext/function/identity')
  , assign               = require('es5-ext/object/assign')
  , ensureCallable       = require('es5-ext/object/valid-callable')
  , ensureObject         = require('es5-ext/object/valid-object')
  , ensureStringifiable  = require('es5-ext/object/validate-stringifiable-value')
  , forEach              = require('es5-ext/object/for-each')
  , endsWith             = require('es5-ext/string/#/ends-with')
  , d                    = require('d')
  , autoBind             = require('d/auto-bind')
  , lazy                 = require('d/lazy')
  , isPromise            = require('is-promise')
  , compareDynamicRoutes = require('./lib/compare-dynamic-routes')
  , isStatic             = require('./lib/is-token-static')
  , resolvePathMeta      = require('./lib/resolve-path-meta')
  , ensurePath           = require('./lib/ensure-path')

  , push = Array.prototype.push, slice = Array.prototype.slice, apply = Function.prototype.apply
  , create = Object.create, defineProperty = Object.defineProperty, stringify = JSON.stringify
  , routeCallIdIndex = 0;

var ControllerRouter = module.exports = Object.defineProperties(function (routes/*, options*/) {
	var options;
	// Validate initialization
	if (!(this instanceof ControllerRouter)) return new ControllerRouter(routes, arguments[1]);
	options = Object(arguments[1]);
	this.constructor.ensureRoutes(routes, options);

	if (options.eventProto != null) {
		// Override default event prototype
		defineProperty(this, '_eventProto', d(ensureObject(options.eventProto)));
	}

	defineProperty(this, 'routes', d(routes));

	// Configure internal routes map
	forEach(this.constructor.normalizeRoutes(routes, options), function (conf, path) {
		var pathData = resolvePathMeta(path);
		if (pathData.static) {
			this._staticRoutes[path] = conf;
			return;
		}
		if (!this._dynamicRoutes[pathData.tokens.length]) {
			this._dynamicRoutes[pathData.tokens.length] = [];
		}
		pathData.conf = conf;
		pathData.matchPositionsLength = pathData.matchPositions.length;
		this._dynamicRoutes[pathData.tokens.length].push(pathData);
	}, this);
	forEach(this._dynamicRoutes, function (data) { data.sort(compareDynamicRoutes); });

	// Whether route should resolve with promise or not
	if (options.promiseResultImplementation) {
		defineProperty(this, 'Promise', d(ensureCallable(options.promiseResultImplementation)));
	}
}, {
	// Validates provided routes map
	ensureRoutes: d(function (routes) {
		forEach(ensureObject(routes), function (conf, path) {
			var isDynamic;
			ensureObject(conf);
			ensurePath(path);
			if (path !== '/') isDynamic = !path.split('/').every(isStatic);
			if (typeof conf === 'function') {
				if (isDynamic) {
					throw customError("Missing match function for " + stringify(path), 'MISSING_MATCH');
				}
				return;
			}
			if (typeof conf.controller !== 'function') {
				throw customError("Invalid controller for " + stringify(path), 'INVALID_CONTROLLER');
			}
			if (typeof conf.match !== 'function') {
				if (isDynamic) {
					throw customError("Invalid match function for " + stringify(path), 'INVALID_MATCH');
				}
				return;
			}
			if (!isDynamic) {
				throw customError("Missing regular expression in path " + stringify(path),
					'MISSING_PATH_REGEX');
			}
		});
		return routes;
	}),
	// Normalizes routes to bare ControllerRouter format. If ControllerRouter extension
	// provides more sophisticated routes format, this should be a function which transforms it
	// directly to map as understood by ControllerRouter
	normalizeRoutes: d(identity)
});

Object.defineProperties(ControllerRouter.prototype, assign({
	_resolveResult: d(function (result) {
		if (result && isPromise(result.result)) {
			return result.result.then(function (resolvedResult) {
				result.result = resolvedResult;
				return result;
			});
		}
		return this.Promise ? this.Promise.resolve(result) : result;
	}),
	_resolveController: d(function (fn) {
		if (!this.Promise) {
			this.lastRouteData.result = fn();
		} else {
			try {
				this.lastRouteData.result = fn();
			} catch (e) {
				return this.Promise.reject(e);
			}
		}
		return this._resolveResult(this.lastRouteData);
	}),

	// Routes path to controller and provides an event to be used for controller invocation
	routeEvent: d(function (event, path/*, …controllerArgs*/) {
		var pathTokens, controllerArgs = slice.call(arguments, 2), conf, initConf, controller
		  , asyncResult, callId = ++routeCallIdIndex;

		ensureObject(event);
		path = ensureStringifiable(path);

		// Preprepare route data
		this.lastRouteData = { event: event };

		// Do not proceed for no path
		if (!path) return this._resolveResult(false);

		// Resolve path for route resolution
		if (path[0] === '/') path = path.slice(1);
		if (endsWith.call(path, '/')) path = path.slice(0, -1);
		event.path = path || '/';

		// Handle eventual static path
		conf = this._staticRoutes[path || '/'];
		if (conf) {
			initConf = this.routes[path || '/'];
			controller = conf.controller || conf;
			this.lastRouteData.conf =  initConf;
			return this._resolveController(apply.bind(controller, event, controllerArgs));
		}

		// Handle eventual dynamic paths
		pathTokens = path.split('/');
		if (!this._dynamicRoutes[pathTokens.length]) return this._resolveResult(false);
		this._dynamicRoutes[pathTokens.length].some(function (data) {
			var args = [], matchResult;

			// Check whether path matches
			if (!data.tokens.every(function (token, index) {
					var pathToken = pathTokens[index];
					if (includes.call(data.matchPositions, index)) {
						if (!token.test(pathToken)) return false;
						args.push(pathToken);
						return true;
					}
					return (token === pathToken);
				})) {
				return false;
			}

			// Path matches, now resolve with `match` function
			matchResult = data.conf.match.apply(event, args);
			if (isPromise(matchResult)) {
				asyncResult = matchResult.then(function (isMatch) {
					if (!isMatch) return false;
					this.lastRouteData = {
						event: event,
						conf: this.routes[data.path]
					};
					if (callId !== routeCallIdIndex) {
						// Cancel route (as promises are concerned we need to reject)
						throw customError("Route cancelled, as next one took action", 'OUTDATED_ROUTE_CALL');
					}
					this.lastRouteData.result = apply.call(data.conf.controller, event, controllerArgs);
					return this._resolveResult(this.lastRouteData);
				}.bind(this));
			} else if (matchResult) {
				conf = data.conf;
				initConf = this.routes[data.path];
			}
			return true;
		}, this);

		// If `match` is asynchronous return promise
		if (asyncResult) return asyncResult;
		if (!conf) return this._resolveResult(false);
		this.lastRouteData.conf = initConf;
		return this._resolveController(apply.bind(conf.controller, event, controllerArgs));
	}),
	// Default prototype for an route event
	_eventProto: d(Object.prototype)
}, lazy({
	// Internal map of dynamic routes (those that contain regexp tokens)
	_dynamicRoutes: d(function () { return create(null); }),
	// Internal map of static routes (no regexp tokens)
	_staticRoutes: d(function () { return create(null); })
}), autoBind({
	// Routes path to controller
	route: d(function (path/*, …controllerArgs*/) {
		var args = [create(this._eventProto)];
		push.apply(args, arguments);
		return this.routeEvent.apply(this, args);
	})
})));
<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * Copyright (c) 2012 Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the MIT License.
 * See the accompanying LICENSE file for terms.
 */
/*jslint node:true, regexp:true */
'use strict';

var exec = require('child_process').exec,
    Table = require('cli-table'),
    colors = require('cli-table/node_modules/colors'),

    CHUNK_RE = /^([* ]) (\S+)\s+([0-9a-f]+) (.+)$/,
    REMOTE_RE = /^remotes\/([\w.\-]+)\/([\w.\-]+)/,
    msg_len_opt,

    branches = {}, //hash of local branch names[1], no values
    remotes = {},  //hash of remote names[2], no values
    meta = {};     //hash to look up git metadata by 'remote,branch'[3]

function index(star, ref, sha, msg) {
    var branch,
        remote,
        parts = ref.match(REMOTE_RE);

    if (parts) {
        remote = parts[1];
        branch = parts[2];
    } else {
        remote = 'local';
        branch = ref;
        branches[ref] = null; //local branches
    }

    if (!remotes.hasOwnProperty(remote)) {
        remotes[remote] = null; //index all remotes
    }

    meta[[remote, branch].join()] = {star: star, sha: sha, msg: msg};
}

function getMeta(repo, branch) {
    return meta[[repo, branch].join()];
}

function format(meta, local, prev) {
    var out = [];
    if (local === meta.sha) {
        //this column/repo branch head sha is same as local one (1st column)
        out.push('✔ '.green);
    } else {
        out.push(meta.sha);
        //optionally show commit message unless it's the same as prev column
        if (msg_len_opt && (prev !== meta.sha)) {
            out.push(meta.msg.slice(0, msg_len_opt).grey);
        }
    }
    return out.join(' ');
}

function map(remotes, branches) {
    var title = ['branch'].concat(remotes),
        style = {compact: true, 'padding-left': 1, 'padding-right': 2},
        table = new Table({head: title, style: style}),
        blank = {sha: '', msg: ''};

    function perBranch(branch) {
        var localmeta = getMeta('local', branch) || blank,
            star = localmeta.star ? ' ' + localmeta.star : '',
            row = [branch + star.blue],
            lsha = '', //local, for ✔
            psha = ''; //previous, for optional msg dedupe

        function perRow(remote) {
            var head = getMeta(remote, branch) || blank;
            row.push(format(head, lsha, psha));
            if (!lsha) {
            	lsha = localmeta.sha;
            }
            psha = head.sha;
        }

        remotes.forEach(perRow);
        table.push(row);
    }

    branches.forEach(perBranch);
    return table;
}

function chunk(err, stdout, stderr) {
    var table;

    if (err) {
        console.error(stderr);
        return process.exit(err.code);
    }

    stdout.split('\n').forEach(function (str) {
        var parts = str.match(CHUNK_RE);
        if (parts) {
            index(parts[1].trim(), parts[2], parts[3], parts[4]);
        }
    });

    console.log(map(Object.keys(remotes), Object.keys(branches)).toString());
}

colors.mode = process.stdout.isTTY ? 'console' : 'none'; // doesn't work

msg_len_opt = process.argv.length > 2 ? +process.argv.pop() || 18 : 0;

exec('git branch -av', chunk);

/*
1. branches => {
      arrowtests: null,
      connect: null,
      develop: null,
      'develop-perf': null,
      master: null,
      testjs: null
   }

2. remotes => { local: null, my: null, up: null }

3. meta => {
  'local,arrowtests':
   { star: '',
     sha: 'df4666f',
     msg: 'tweak to use MOJITO_DIR instead of path.join etc' },
  'local,connect':
   { star: '',
     sha: '1b1e3b1',
     msg: 'rm useless function wrapper, +lint/strict' },
  'local,develop':
   { star: '*',
     sha: '748e74b',
     msg: 'Merge pull request #740 from isao/develop' },
   ...
*/
<commit_msg>show log msg by default.<commit_after>#!/usr/bin/env node
/**
 * Copyright (c) 2012 Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the MIT License.
 * See the accompanying LICENSE file for terms.
 */
/*jslint node:true, regexp:true */
'use strict';

var exec = require('child_process').exec,
    Table = require('cli-table'),
    colors = require('cli-table/node_modules/colors'),

    CHUNK_RE = /^([* ]) (\S+)\s+([0-9a-f]+) (.+)$/,
    REMOTE_RE = /^remotes\/([\w.\-]+)\/([\w.\-]+)/,
    msg_len_opt,

    branches = {}, //hash of local branch names[1], no values
    remotes = {},  //hash of remote names[2], no values
    meta = {};     //hash to look up git metadata by 'remote,branch'[3]

function index(star, ref, sha, msg) {
    var branch,
        remote,
        parts = ref.match(REMOTE_RE);

    if (parts) {
        remote = parts[1];
        branch = parts[2];
    } else {
        remote = 'local';
        branch = ref;
        branches[ref] = null; //local branches
    }

    if (!remotes.hasOwnProperty(remote)) {
        remotes[remote] = null; //index all remotes
    }

    meta[[remote, branch].join()] = {star: star, sha: sha, msg: msg};
}

function getMeta(repo, branch) {
    return meta[[repo, branch].join()];
}

function format(meta, local, prev) {
    var out = [];
    if (local === meta.sha) {
        //this column/repo branch head sha is same as local one (1st column)
        out.push('✔ '.green);
    } else {
        out.push(meta.sha);
        //optionally show commit message unless it's the same as prev column
        if (msg_len_opt && (prev !== meta.sha)) {
            out.push(meta.msg.slice(0, msg_len_opt).grey);
        }
    }
    return out.join(' ');
}

function map(remotes, branches) {
    var title = ['branch'].concat(remotes),
        style = {compact: true, 'padding-left': 1, 'padding-right': 2},
        table = new Table({head: title, style: style}),
        blank = {sha: '', msg: ''};

    function perBranch(branch) {
        var localmeta = getMeta('local', branch) || blank,
            star = localmeta.star ? ' ' + localmeta.star : '',
            row = [branch + star.blue],
            lsha = '', //local, for ✔
            psha = ''; //previous, for optional msg dedupe

        function perRow(remote) {
            var head = getMeta(remote, branch) || blank;
            row.push(format(head, lsha, psha));
            if (!lsha) {
            	lsha = localmeta.sha;
            }
            psha = head.sha;
        }

        remotes.forEach(perRow);
        table.push(row);
    }

    branches.forEach(perBranch);
    return table;
}

function chunk(err, stdout, stderr) {
    var table;

    if (err) {
        console.error(stderr);
        return process.exit(err.code);
    }

    stdout.split('\n').forEach(function (str) {
        var parts = str.match(CHUNK_RE);
        if (parts) {
            index(parts[1].trim(), parts[2], parts[3], parts[4]);
        }
    });

    console.log(map(Object.keys(remotes), Object.keys(branches)).toString());
}

colors.mode = process.stdout.isTTY ? 'console' : 'none'; // doesn't work

msg_len_opt = process.argv.length > 2 ? +process.argv.pop() : 18;

exec('git branch -av', chunk);

/*
1. branches => {
      arrowtests: null,
      connect: null,
      develop: null,
      'develop-perf': null,
      master: null,
      testjs: null
   }

2. remotes => { local: null, my: null, up: null }

3. meta => {
  'local,arrowtests':
   { star: '',
     sha: 'df4666f',
     msg: 'tweak to use MOJITO_DIR instead of path.join etc' },
  'local,connect':
   { star: '',
     sha: '1b1e3b1',
     msg: 'rm useless function wrapper, +lint/strict' },
  'local,develop':
   { star: '*',
     sha: '748e74b',
     msg: 'Merge pull request #740 from isao/develop' },
   ...
*/
<|endoftext|>


<commit_before>var knox = require('knox')
  , EventEmitter = require('events').EventEmitter
  , fs = require('fs');

exports.createClient = function(options) {
  var client = new Client();
  client.knox = knox.createClient(options);
  return client;
};

exports.fromKnox = function(knoxClient) {
  var client = new Client();
  client.knox = knoxClient;
  return client;
}

function Client(options) {}

Client.prototype.upload = function(localFile, remoteFile, headers) {

  if (typeof headers != 'object')
    headers = { };

  var uploader = new EventEmitter();
  var knoxUpload = this.knox.putFile(localFile, remoteFile, headers, function (err, resp) {
    if (err) {
      uploader.emit('error', err);
    } else if (resp.statusCode === 200 || resp.statusCode === 307) {
      uploader.emit('end', resp.req.url);
    } else {
      uploader.emit('error', new Error("s3 http status code " + resp.statusCode));
    }
  });
  knoxUpload.on('progress', function (progress) {
    uploader.emit('progress', progress.written, progress.total);
  });
  return uploader;
};

Client.prototype.download = function(remoteFile, localFile) {
  var downloader = new EventEmitter();
  var headers;
  var amountDone = 0;
  var amountTotal;
  var writeStream;
  var knoxDownload = this.knox.getFile(remoteFile, function (err, resp) {
    if (err) {
      downloader.emit('error', err);
    } else if (resp.statusCode === 200 || resp.statusCode === 307) {
      amountTotal = parseInt(resp.headers['content-length'], 10);
      headers = resp.headers;
      var writeStream = fs.createWriteStream(localFile);
      writeStream.on('error', onError);
      resp.on('error', onError);
      resp.on('end', onSuccess);
      resp.on('data', onData);
      resp.pipe(writeStream);
    } else {
      downloader.emit('error', new Error("s3 http status code " + resp.statusCode));
    }
    function removeListeners() {
      writeStream.removeListener('error', onError);
      resp.removeListener('error', onError);
      resp.removeListener('end', onSuccess);
    }
    function onError(err) {
      removeListeners();
      writeStream.destroy();
      downloader.emit('error', err);
    }
    function onSuccess() {
      removeListeners();
      writeStream.end();
      downloader.emit('end', { headers: headers });
    }
    function onData(data) {
      amountDone += data.length;
      downloader.emit('progress', amountDone, amountTotal);
    }
  });
  return downloader;
};
<commit_msg>issue #7 resp.req could be undefined (refer resp.url)<commit_after>var knox = require('knox')
  , EventEmitter = require('events').EventEmitter
  , fs = require('fs');

exports.createClient = function(options) {
  var client = new Client();
  client.knox = knox.createClient(options);
  return client;
};

exports.fromKnox = function(knoxClient) {
  var client = new Client();
  client.knox = knoxClient;
  return client;
}

function Client(options) {}

Client.prototype.upload = function(localFile, remoteFile, headers) {

  if (typeof headers != 'object')
    headers = { };

  var uploader = new EventEmitter();
  var knoxUpload = this.knox.putFile(localFile, remoteFile, headers, function (err, resp) {
    if (err) {
      uploader.emit('error', err);
    } else if (resp.statusCode === 200 || resp.statusCode === 307) {
      uploader.emit('end', resp.req && resp.req.url || resp.url);
    } else {
      uploader.emit('error', new Error("s3 http status code " + resp.statusCode));
    }
  });
  knoxUpload.on('progress', function (progress) {
    uploader.emit('progress', progress.written, progress.total);
  });
  return uploader;
};

Client.prototype.download = function(remoteFile, localFile) {
  var downloader = new EventEmitter();
  var headers;
  var amountDone = 0;
  var amountTotal;
  var writeStream;
  var knoxDownload = this.knox.getFile(remoteFile, function (err, resp) {
    if (err) {
      downloader.emit('error', err);
    } else if (resp.statusCode === 200 || resp.statusCode === 307) {
      amountTotal = parseInt(resp.headers['content-length'], 10);
      headers = resp.headers;
      var writeStream = fs.createWriteStream(localFile);
      writeStream.on('error', onError);
      resp.on('error', onError);
      resp.on('end', onSuccess);
      resp.on('data', onData);
      resp.pipe(writeStream);
    } else {
      downloader.emit('error', new Error("s3 http status code " + resp.statusCode));
    }
    function removeListeners() {
      writeStream.removeListener('error', onError);
      resp.removeListener('error', onError);
      resp.removeListener('end', onSuccess);
    }
    function onError(err) {
      removeListeners();
      writeStream.destroy();
      downloader.emit('error', err);
    }
    function onSuccess() {
      removeListeners();
      writeStream.end();
      downloader.emit('end', { headers: headers });
    }
    function onData(data) {
      amountDone += data.length;
      downloader.emit('progress', amountDone, amountTotal);
    }
  });
  return downloader;
};
<|endoftext|>


<commit_before>var argv = require('minimist')(process.argv.slice(2));
var fs = require('fs');
var exec = require('child_process').exec;

var version;
var bump;
var newVersion;

var acceptedVersionBump = [ 'major', 'minor', 'patch' ];

if ( argv.version ) {
    if ( acceptedVersionBump.indexOf(argv.version) !== -1 ) {
        bump = argv.version;
    } else {
        console.log(argv.version + ' is no a valid bump type. Accepted types are major, minor, patch');
        throw 'Invalid bump type';
    }
} else {
    bump = 'patch';
}

fs.readFile('./package.json', 'utf8', parseVersion);

function parseVersion(err, response) {
    if (err) {
        console.log();
    }

    var pkg = JSON.parse(response);

    if ( !pkg.version ) {
        throw 'Could not read version from package.json. Is the file correctly formatted?';
    }

    newVersion = bumpVersion(pkg.version, bump);

    createNewReleaseBranch(newVersion);
}

function bumpVersion(currentVersion, type) {
    var versionArray = currentVersion.split('.');

    if ( acceptedVersionBump.indexOf(type) === -1 ) {
        throw 'Bump only accepts major, minor or patch bump types, ' + type + ' was given';
    }

    versionArray[acceptedVersionBump.indexOf(type)]++;

    return versionArray.join('.');
}

function confirmWrite(err) {
    if ( err ) throw err;

    console.log('Saved! New version is: ', newVersion);
}

function createNewReleaseBranch(name) {
    exec('git-flow release start ' + name, function(err, stdout, stderr) {
        if (err) throw err;

        console.log(stdout);
    });
}
<commit_msg>update cli arguments structure<commit_after>#! /usr/bin/env node

var argv = require('minimist')(process.argv.slice(2));
var fs = require('fs');
var exec = require('child_process').exec;

var version;
var bump = 'patch';
var newVersion;

var acceptedVersionBump = [ 'major', 'minor', 'patch' ];

acceptedVersionBump.forEach(function(version) {
    if ( argv._.indexOf(version) !== -1 ) {
        bump = version;
    }
});

fs.readFile('./package.json', 'utf8', parseVersion);

function parseVersion(err, response) {
    if (err) {
        console.log();
    }

    var pkg = JSON.parse(response);

    if ( !pkg.version ) {
        throw 'Could not read version from package.json. Is the file correctly formatted?';
    }

    newVersion = bumpVersion(pkg.version, bump);

    createNewReleaseBranch(newVersion);
}

function bumpVersion(currentVersion, type) {
    var versionArray = currentVersion.split('.');

    if ( acceptedVersionBump.indexOf(type) === -1 ) {
        throw 'Bump only accepts major, minor or patch bump types, ' + type + ' was given';
    }

    versionArray[acceptedVersionBump.indexOf(type)]++;

    return versionArray.join('.');
}

function confirmWrite(err) {
    if ( err ) throw err;

    console.log('Saved! New version is: ', newVersion);
}

function createNewReleaseBranch(name) {
    exec('git-flow release start ' + name, function(err, stdout, stderr) {
        if (err) throw err;

        console.log(stdout);
    });
}
<|endoftext|>


<commit_before>var fs = require('fs'),
    path = require('path'),

    tags = require('./lib/tags'),
    parser = require('./lib/parser'),
    filters = require('./lib/filters'),
    helpers = require('./lib/helpers'),
    dateformat = require('./lib/dateformat'),

    _ = require('underscore'),

    config = {
        allowErrors: false,
        autoescape: true,
        cache: true,
        encoding: 'utf8',
        filters: filters,
        root: '/',
        tags: tags,
        extensions: {},
        tzOffset: 0
    },
    _config = _.extend({}, config),
    CACHE = {};

// Call this before using the templates
exports.init = function (options) {
    CACHE = {};
    _config = _.extend({}, config, options);
    _config.filters = _.extend(filters, options.filters);
    _config.tags = _.extend(tags, options.tags);

    dateformat.defaultTZOffset = _config.tzOffset;
};

function TemplateError(error) {
    return { render: function () {
        return '
' + error.stack + '
';
    }};
}

function createTemplate(data, id) {
    var template = {
            // Allows us to include templates from the compiled code
            compileFile: exports.compileFile,
            // These are the blocks inside the template
            blocks: {},
            // Distinguish from other tokens
            type: parser.TEMPLATE,
            // The template ID (path relative to tempalte dir)
            id: id
        },
        tokens,
        code,
        render;

    // The template token tree before compiled into javascript
    if (_config.allowErrors) {
        template.tokens = parser.parse.call(template, data, _config.tags, _config.autoescape);
    } else {
        try {
            template.tokens = parser.parse.call(template, data, _config.tags, _config.autoescape);
        } catch (e) {
            return new TemplateError(e);
        }
    }

    // The raw template code
    code = parser.compile.call(template);

    // The compiled render function - this is all we need
    render = new Function('_context', '_parents', '_filters', '_', '_ext', [
        '_parents = _parents ? _parents.slice() : [];',
        '_context = _context || {};',
        // Prevents circular includes (which will crash node without warning)
        'var j = _parents.length,',
        '    _output = "",',
        '    _this = this;',
        // Note: this loop averages much faster than indexOf across all cases
        'while (j--) {',
        '   if (_parents[j] === this.id) {',
        '         return "Circular import of template " + this.id + " in " + _parents[_parents.length-1];',
        '   }',
        '}',
        // Add this template as a parent to all includes in its scope
        '_parents.push(this.id);',
        code,
        'return _output;',
    ].join(''));

    template.render = function (context, parents) {
        if (_config.allowErrors) {
            return render.call(this, context, parents, _config.filters, _, _config.extensions);
        } else {
            try {
                return render.call(this, context, parents, _config.filters, _, _config.extensions);
            } catch (e) {
                return new TemplateError(e);
            }
        }
    };

    return template;
}

function getTemplate(source, options) {
    var key = options.filename || source;
    if (_config.cache || options.cache) {
        if (!CACHE.hasOwnProperty(key)) {
            CACHE[key] = createTemplate(source, key);
        }

        return CACHE[key];
    }

    return createTemplate(source, key);
}

exports.compileFile = function (filepath) {
    var tpl, get;

    if (filepath[0] === '/') {
        filepath = filepath.substr(1);
    }

    if (_config.cache && CACHE.hasOwnProperty(filepath)) {
        return CACHE[filepath];
    }

    if (typeof window !== 'undefined') {
        throw new TemplateError({ stack: 'You must pre-compile all templates in-browser. Use `swig.compile(template);`.' });
    }

    get = function () {
        var file = ((/^\//).test(filepath)) ? filepath : _config.root + '/' + filepath,
            data = fs.readFileSync(file, config.encoding);
        tpl = getTemplate(data, { filename: filepath });
    };

    if (_config.allowErrors) {
        get();
    } else {
        try {
            get();
        } catch (error) {
            tpl = new TemplateError(error);
        }
    }
    return tpl;
};

exports.compile = function (source, options) {
    options = options || {};
    var tmpl = getTemplate(source, options || {});

    return function (source, options) {
        return tmpl.render(source, options);
    };
};
<commit_msg>Fixed path test on Windows style paths (where root starts with a drive letter)<commit_after>var fs = require('fs'),
    path = require('path'),

    tags = require('./lib/tags'),
    parser = require('./lib/parser'),
    filters = require('./lib/filters'),
    helpers = require('./lib/helpers'),
    dateformat = require('./lib/dateformat'),

    _ = require('underscore'),

    config = {
        allowErrors: false,
        autoescape: true,
        cache: true,
        encoding: 'utf8',
        filters: filters,
        root: '/',
        tags: tags,
        extensions: {},
        tzOffset: 0
    },
    _config = _.extend({}, config),
    CACHE = {};

// Call this before using the templates
exports.init = function (options) {
    CACHE = {};
    _config = _.extend({}, config, options);
    _config.filters = _.extend(filters, options.filters);
    _config.tags = _.extend(tags, options.tags);

    dateformat.defaultTZOffset = _config.tzOffset;
};

function TemplateError(error) {
    return { render: function () {
        return '
' + error.stack + '
';
    }};
}

function createTemplate(data, id) {
    var template = {
            // Allows us to include templates from the compiled code
            compileFile: exports.compileFile,
            // These are the blocks inside the template
            blocks: {},
            // Distinguish from other tokens
            type: parser.TEMPLATE,
            // The template ID (path relative to tempalte dir)
            id: id
        },
        tokens,
        code,
        render;

    // The template token tree before compiled into javascript
    if (_config.allowErrors) {
        template.tokens = parser.parse.call(template, data, _config.tags, _config.autoescape);
    } else {
        try {
            template.tokens = parser.parse.call(template, data, _config.tags, _config.autoescape);
        } catch (e) {
            return new TemplateError(e);
        }
    }

    // The raw template code
    code = parser.compile.call(template);

    // The compiled render function - this is all we need
    render = new Function('_context', '_parents', '_filters', '_', '_ext', [
        '_parents = _parents ? _parents.slice() : [];',
        '_context = _context || {};',
        // Prevents circular includes (which will crash node without warning)
        'var j = _parents.length,',
        '    _output = "",',
        '    _this = this;',
        // Note: this loop averages much faster than indexOf across all cases
        'while (j--) {',
        '   if (_parents[j] === this.id) {',
        '         return "Circular import of template " + this.id + " in " + _parents[_parents.length-1];',
        '   }',
        '}',
        // Add this template as a parent to all includes in its scope
        '_parents.push(this.id);',
        code,
        'return _output;',
    ].join(''));

    template.render = function (context, parents) {
        if (_config.allowErrors) {
            return render.call(this, context, parents, _config.filters, _, _config.extensions);
        } else {
            try {
                return render.call(this, context, parents, _config.filters, _, _config.extensions);
            } catch (e) {
                return new TemplateError(e);
            }
        }
    };

    return template;
}

function getTemplate(source, options) {
    var key = options.filename || source;
    if (_config.cache || options.cache) {
        if (!CACHE.hasOwnProperty(key)) {
            CACHE[key] = createTemplate(source, key);
        }

        return CACHE[key];
    }

    return createTemplate(source, key);
}

exports.compileFile = function (filepath) {
    var tpl, get;

    if (filepath[0] === '/') {
        filepath = filepath.substr(1);
    }

    if (_config.cache && CACHE.hasOwnProperty(filepath)) {
        return CACHE[filepath];
    }

    if (typeof window !== 'undefined') {
        throw new TemplateError({ stack: 'You must pre-compile all templates in-browser. Use `swig.compile(template);`.' });
    }

    get = function () {
        var file = ((/^\//).test(filepath) || (/^.:/).test(filepath)) ? filepath : _config.root + '/' + filepath,
            data = fs.readFileSync(file, config.encoding);
        tpl = getTemplate(data, { filename: filepath });
    };

    if (_config.allowErrors) {
        get();
    } else {
        try {
            get();
        } catch (error) {
            tpl = new TemplateError(error);
        }
    }
    return tpl;
};

exports.compile = function (source, options) {
    options = options || {};
    var tmpl = getTemplate(source, options || {});

    return function (source, options) {
        return tmpl.render(source, options);
    };
};
<|endoftext|>


<commit_before>'use strict';
var request = require('request'),
    xml2js = require('xml2js'),
    zlib = require('zlib');

function namespaces(ns) {
    var attributes = '';
    for (var name in ns) {
        attributes += `${name}="${ns[name]}"`;
    }
    return attributes.trim();
}

function gunzip(data) {
    var buffer = new Buffer(data);
    zlib.unzip(buffer, function (err, buffer) {
        if (!err) {
            return buffer.toString();
        }
    });
}

function isGzipped(response) {
    return /gzip/.test(response.headers['content-encoding']);
}

function envelope(operation, message, options) {
    var xml = '<?xml version="1.0" encoding="UTF-8"?>',
        builder = new xml2js.Builder({
            "headless": true
        });

    xml += `<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" ${namespaces(options.namespaces)}>`;
    if (options.header) {
        xml += `<env:Header>${options.header}</env:Header>`;
    }
    xml += `<env:Body>${builder.buildObject(message)}</env:Body>`;
    xml += '</env:Envelope>';
    console.log(xml);
    return xml;
}

function headers(schema, length) {
    return {
        'SOAPAction': schema,
        'Content-Type': 'text/xml;charset=UTF-8',
        'Content-Length': length,
        'Accept-Encoding': 'gzip',
        'Accept': '*/*'
    };
}

function parseString(str) {
    var prefixMatch = new RegExp(/(?!xmlns)^.*:/),
        stripPrefix = function (str) {
            return str.replace(prefixMatch, '');
        },
        parser = new xml2js.Parser({
            ignoreAttrs: true,
            explicitArray: false,
            firstCharLowerCase: true,
            tagNameProcessors: [stripPrefix]
        });
    return new Promise(
        function (resolve, reject) {
            parser.parseString(str, function (err, result) {
                if (err) {
                    reject(err);
                } else {
                    resolve(result);
                }
            });
        });
}

module.exports = function (endpoint, operation, action, message, options) {
    console.log('Start');
    var xml = envelope(operation, message, options);

    return new Promise(
        function (resolve, reject) {
            console.time('Promise');
            request.post({
                uri: endpoint,
                body: xml,
                headers: headers(action, xml.length),
                rejectUnauthorized: options.rejectUnauthorized,
                secureProtocol: options.secureProtocol
            }, function (error, response, body) {
                if (error) {
                    //console.log(error);
                    reject(error);
                } else {
                    if (isGzipped(response)) {
                        console.log('gunzip');
                        body = gunzip(body);
                    }
                    parseString(body).then(JSON.stringify).then(resolve).catch(reject);
                }

            });
        });
};<commit_msg>gzip is a module<commit_after>'use strict';
var request = require('request'),
    gzip = require('../gzip-simple'),
    xml2js = (function () {
        var xml2js = require('xml2js');
        return {
            buildObject: function (message) {
                var builder = new xml2js.Builder({
                    "headless": true
                });
                return builder.buildObject(message);
            },
            parseString: function (str) {
                var prefixMatch = new RegExp(/(?!xmlns)^.*:/),
                    stripPrefix = function (str) {
                        return str.replace(prefixMatch, '');
                    },
                    parser = new xml2js.Parser({
                        ignoreAttrs: true,
                        explicitArray: false,
                        firstCharLowerCase: true,
                        tagNameProcessors: [stripPrefix]
                    });
                return new Promise(
                    function (resolve, reject) {
                        parser.parseString(str, function (err, result) {
                            if (err) {
                                reject(err);
                            } else {
                                resolve(result);
                            }
                        });
                    });
            }
        };
    })();

function namespaces(ns) {
    var attributes = '';
    for (var name in ns) {
        attributes += `${name}="${ns[name]}"`;
    }
    return attributes.trim();
}

function envelope(operation, message, options) {
    var xml = '<?xml version="1.0" encoding="UTF-8"?>';

    xml += `<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" ${namespaces(options.namespaces)}>`;
    if (options.header) {
        xml += `<env:Header>${options.header}</env:Header>`;
    }
    xml += `<env:Body>${xml2js.buildObject(message)}</env:Body>`;
    xml += '</env:Envelope>';
    console.log(xml);
    return xml;
}

function headers(schema, length) {
    return {
        'SOAPAction': schema,
        'Content-Type': 'text/xml;charset=UTF-8',
        'Content-Length': length,
        'Accept-Encoding': 'gzip',
        'Accept': '*/*'
    };
}

module.exports = function (endpoint, operation, action, message, options) {
    console.log('Start');
    var xml = envelope(operation, message, options);

    return new Promise(
        function (resolve, reject) {
            console.time('Promise');
            request.post({
                uri: endpoint,
                body: xml,
                headers: headers(action, xml.length),
                rejectUnauthorized: options.rejectUnauthorized,
                secureProtocol: options.secureProtocol
            }, function (error, response, body) {
                if (error) {
                    //console.log(error);
                    reject(error);
                } else {
                    if (gzip.isGzipped(response)) {
                        console.log('gunzip');
                        body = gzip.gunzip(body);
                    }
                    xml2js.parseString(body).then(JSON.stringify).then(resolve).catch(reject);
                }

            });
        });
};<|endoftext|>


<commit_before>
export.name="choo";<commit_msg>Add comment in line 2<commit_after>
export.name="choo";  //This is my name.<|endoftext|>


<commit_before>angular
    .module('material.components.autocomplete')
    .controller('MdAutocompleteCtrl', MdAutocompleteCtrl);

var ITEM_HEIGHT = 41,
    MAX_HEIGHT = 5.5 * ITEM_HEIGHT,
    MENU_PADDING = 8;

function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $mdTheming, $window, $animate, $rootElement) {

  //-- private variables

  var self      = this,
      itemParts = $scope.itemsExpr.split(/ in /i),
      itemExpr  = itemParts[1],
      elements  = null,
      promise   = null,
      cache     = {},
      noBlur    = false,
      selectedItemWatchers = [],
      hasFocus  = false;

  //-- public variables

  self.scope    = $scope;
  self.parent   = $scope.$parent;
  self.itemName = itemParts[0];
  self.matches  = [];
  self.loading  = false;
  self.hidden   = true;
  self.index    = null;
  self.messages = [];
  self.id       = $mdUtil.nextUid();

  //-- public methods

  self.keydown  = keydown;
  self.blur     = blur;
  self.focus    = focus;
  self.clear    = clearValue;
  self.select   = select;
  self.getCurrentDisplayValue         = getCurrentDisplayValue;
  self.registerSelectedItemWatcher    = registerSelectedItemWatcher;
  self.unregisterSelectedItemWatcher  = unregisterSelectedItemWatcher;

  self.listEnter = function () { noBlur = true; };
  self.listLeave = function () {
    noBlur = false;
    if (!hasFocus) self.hidden = true;
  };
  self.mouseUp   = function () { elements.input.focus(); };

  return init();

  //-- initialization methods

  function init () {
    configureWatchers();
    $timeout(function () {
      gatherElements();
      focusElement();
      moveDropdown();
    });
  }

  function positionDropdown () {
    if (!elements) return $timeout(positionDropdown, 0, false);
    var hrect  = elements.wrap.getBoundingClientRect(),
        vrect  = elements.snap.getBoundingClientRect(),
        root   = elements.root.getBoundingClientRect(),
        top    = vrect.bottom - root.top,
        bot    = root.bottom - vrect.top,
        left   = hrect.left - root.left,
        width  = hrect.width,
        styles = {
          left:     left + 'px',
          minWidth: width + 'px',
          maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px'
        };
    if (top > bot && root.height - hrect.bottom - MENU_PADDING < MAX_HEIGHT) {
      styles.top = 'auto';
      styles.bottom = bot + 'px';
      styles.maxHeight = Math.min(MAX_HEIGHT, hrect.top - root.top - MENU_PADDING) + 'px';
    } else {
      styles.top = top + 'px';
      styles.bottom = 'auto';
      styles.maxHeight = Math.min(MAX_HEIGHT, root.bottom - hrect.bottom - MENU_PADDING) + 'px';
    }
    elements.$.ul.css(styles);
    $timeout(correctHorizontalAlignment, 0, false);

    function correctHorizontalAlignment () {
      var dropdown = elements.ul.getBoundingClientRect(),
          styles   = {};
      if (dropdown.right > root.right - MENU_PADDING) {
        styles.left = (hrect.right - dropdown.width) + 'px';
      }
      elements.$.ul.css(styles);
    }
  }

  function moveDropdown () {
    if (!elements.$.root.length) return;
    $mdTheming(elements.$.ul);
    elements.$.ul.detach();
    elements.$.root.append(elements.$.ul);
    if ($animate.pin) $animate.pin(elements.$.ul, $rootElement);
  }

  function focusElement () {
    if ($scope.autofocus) elements.input.focus();
  }

  function configureWatchers () {
    var wait = parseInt($scope.delay, 10) || 0;
    $scope.$watch('searchText', wait
        ? $mdUtil.debounce(handleSearchText, wait)
        : handleSearchText);
    registerSelectedItemWatcher(selectedItemChange);
    $scope.$watch('selectedItem', handleSelectedItemChange);
    $scope.$watch('$mdAutocompleteCtrl.hidden', function (hidden, oldHidden) {
      if (!hidden && oldHidden) positionDropdown();
    });
    angular.element($window).on('resize', positionDropdown);
  }

  function gatherElements () {
    elements = {
      main:  $element[0],
      ul:    $element.find('ul')[0],
      input: $element.find('input')[0],
      wrap:  $element.find('md-autocomplete-wrap')[0],
      root:  document.body
    };
    elements.snap = getSnapTarget();
    elements.$ = getAngularElements(elements);
  }

  function getSnapTarget () {
    for (var element = $element; element.length; element = element.parent()) {
      if (angular.isDefined(element.attr('md-autocomplete-snap'))) return element[0];
    }
    return elements.wrap;
  }

  function getAngularElements (elements) {
    var obj = {};
    for (var key in elements) {
      obj[key] = angular.element(elements[key]);
    }
    return obj;
  }

  //-- event/change handlers

  function selectedItemChange (selectedItem, previousSelectedItem) {
    if (selectedItem) {
      $scope.searchText = getDisplayValue(selectedItem);
    }
    if ($scope.itemChange && selectedItem !== previousSelectedItem)
      $scope.itemChange(getItemScope(selectedItem));
  }

  function handleSelectedItemChange(selectedItem, previousSelectedItem) {
    for (var i = 0; i < selectedItemWatchers.length; ++i) {
      selectedItemWatchers[i](selectedItem, previousSelectedItem);
    }
  }

  /**
   * Register a function to be called when the selected item changes.
   * @param cb
   */
  function registerSelectedItemWatcher(cb) {
    if (selectedItemWatchers.indexOf(cb) == -1) {
      selectedItemWatchers.push(cb);
    }
  }

  /**
   * Unregister a function previously registered for selected item changes.
   * @param cb
   */
  function unregisterSelectedItemWatcher(cb) {
    var i = selectedItemWatchers.indexOf(cb);
    if (i != -1) {
      selectedItemWatchers.splice(i, 1);
    }
  }

  function handleSearchText (searchText, previousSearchText) {
    self.index = getDefaultIndex();
    //-- do nothing on init
    if (searchText === previousSearchText) return;
    //-- clear selected item if search text no longer matches it
    if (searchText !== getDisplayValue($scope.selectedItem)) $scope.selectedItem = null;
    else return;
    //-- trigger change event if available
    if ($scope.textChange && searchText !== previousSearchText)
      $scope.textChange(getItemScope($scope.selectedItem));
    //-- cancel results if search text is not long enough
    if (!isMinLengthMet()) {
      self.loading = false;
      self.matches = [];
      self.hidden = shouldHide();
      updateMessages();
    } else {
      handleQuery();
    }
  }

  function blur () {
    hasFocus = false;
    if (!noBlur) self.hidden = true;
  }

  function focus () {
    hasFocus = true;
    //-- if searchText is null, let's force it to be a string
    if (!angular.isString($scope.searchText)) $scope.searchText = '';
    if ($scope.minLength > 0) return;
    self.hidden = shouldHide();
    if (!self.hidden) handleQuery();
  }

  function keydown (event) {
    switch (event.keyCode) {
      case $mdConstant.KEY_CODE.DOWN_ARROW:
        if (self.loading) return;
        event.preventDefault();
        self.index = Math.min(self.index + 1, self.matches.length - 1);
        updateScroll();
        updateSelectionMessage();
        break;
      case $mdConstant.KEY_CODE.UP_ARROW:
        if (self.loading) return;
        event.preventDefault();
        self.index = self.index < 0 ? self.matches.length - 1 : Math.max(0, self.index - 1);
        updateScroll();
        updateSelectionMessage();
        break;
      case $mdConstant.KEY_CODE.TAB:
      case $mdConstant.KEY_CODE.ENTER:
        if (self.hidden || self.loading || self.index < 0 || self.matches.length < 1) return;
        event.preventDefault();
        select(self.index);
        break;
      case $mdConstant.KEY_CODE.ESCAPE:
        self.matches = [];
        self.hidden = true;
        self.index = getDefaultIndex();
        break;
      default:
    }
  }

  //-- getters

  function getMinLength () {
    return angular.isNumber($scope.minLength) ? $scope.minLength : 1;
  }

  function getDisplayValue (item) {
    return (item && $scope.itemText) ? $scope.itemText(getItemScope(item)) : item;
  }

  function getItemScope (item) {
    if (!item) return;
    var locals = {};
    if (self.itemName) locals[self.itemName] = item;
    return locals;
  }

  function getDefaultIndex () {
    return $scope.autoselect ? 0 : -1;
  }

  function shouldHide () {
    if (!isMinLengthMet()) return true;
  }

  function getCurrentDisplayValue () {
    return getDisplayValue(self.matches[self.index]);
  }

  function isMinLengthMet () {
    return $scope.searchText.length >= getMinLength();
  }

  //-- actions

  function select (index) {
    $scope.selectedItem = self.matches[index];
    $scope.searchText = getDisplayValue($scope.selectedItem) || $scope.searchText;
    self.hidden = true;
    self.index = 0;
    self.matches = [];
  }

  function clearValue () {
    $scope.searchText = '';
    select(-1);

    // Per http://www.w3schools.com/jsref/event_oninput.asp
    var eventObj = document.createEvent('CustomEvent');
    eventObj.initCustomEvent('input', true, true, {value: $scope.searchText});
    elements.input.dispatchEvent(eventObj);

    elements.input.focus();
  }

  function fetchResults (searchText) {
    var items = $scope.$parent.$eval(itemExpr),
        term = searchText.toLowerCase();
    if (angular.isArray(items)) {
      handleResults(items);
    } else {
      self.loading = true;
      if (items.success) items.success(handleResults);
      if (items.then)    items.then(handleResults);
      if (items.error)   items.error(function () { self.loading = false; });
    }
    function handleResults (matches) {
      cache[term] = matches;
      self.loading = false;
      if (searchText !== $scope.searchText) return; //-- just cache the results if old request
      promise = null;
      self.matches = matches;
      self.hidden = shouldHide();
      updateMessages();
      positionDropdown();
    }
  }

  function updateMessages () {
    if (self.hidden) return;
    switch (self.matches.length) {
      case 0:  return self.messages.splice(0);
      case 1:  return self.messages.push({ display: 'There is 1 match available.' });
      default: return self.messages.push({ display: 'There are '
          + self.matches.length
          + ' matches available.' });
    }
  }

  function updateSelectionMessage () {
    self.messages.push({ display: getCurrentDisplayValue() });
  }

  function updateScroll () {
    var top = ITEM_HEIGHT * self.index,
        bot = top + ITEM_HEIGHT,
        hgt = elements.ul.clientHeight;
    if (top < elements.ul.scrollTop) {
      elements.ul.scrollTop = top;
    } else if (bot > elements.ul.scrollTop + hgt) {
      elements.ul.scrollTop = bot - hgt;
    }
  }

  function handleQuery () {
    var searchText = $scope.searchText,
        term = searchText.toLowerCase();
    //-- cancel promise if a promise is in progress
    if (promise && promise.cancel) {
      promise.cancel();
      promise = null;
    }
    //-- if results are cached, pull in cached results
    if (!$scope.noCache && cache[term]) {
      self.matches = cache[term];
      updateMessages();
    } else {
      fetchResults(searchText);
    }
    self.hidden = shouldHide();
  }

}
<commit_msg>fix(autocomplete): improves logic behind scrolling items into view on keyboard navigation<commit_after>angular
    .module('material.components.autocomplete')
    .controller('MdAutocompleteCtrl', MdAutocompleteCtrl);

var ITEM_HEIGHT = 41,
    MAX_HEIGHT = 5.5 * ITEM_HEIGHT,
    MENU_PADDING = 8;

function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $mdTheming, $window, $animate, $rootElement) {

  //-- private variables

  var self      = this,
      itemParts = $scope.itemsExpr.split(/ in /i),
      itemExpr  = itemParts[1],
      elements  = null,
      promise   = null,
      cache     = {},
      noBlur    = false,
      selectedItemWatchers = [],
      hasFocus  = false;

  //-- public variables

  self.scope    = $scope;
  self.parent   = $scope.$parent;
  self.itemName = itemParts[0];
  self.matches  = [];
  self.loading  = false;
  self.hidden   = true;
  self.index    = null;
  self.messages = [];
  self.id       = $mdUtil.nextUid();

  //-- public methods

  self.keydown  = keydown;
  self.blur     = blur;
  self.focus    = focus;
  self.clear    = clearValue;
  self.select   = select;
  self.getCurrentDisplayValue         = getCurrentDisplayValue;
  self.registerSelectedItemWatcher    = registerSelectedItemWatcher;
  self.unregisterSelectedItemWatcher  = unregisterSelectedItemWatcher;

  self.listEnter = function () { noBlur = true; };
  self.listLeave = function () {
    noBlur = false;
    if (!hasFocus) self.hidden = true;
  };
  self.mouseUp   = function () { elements.input.focus(); };

  return init();

  //-- initialization methods

  function init () {
    configureWatchers();
    $timeout(function () {
      gatherElements();
      focusElement();
      moveDropdown();
    });
  }

  function positionDropdown () {
    if (!elements) return $timeout(positionDropdown, 0, false);
    var hrect  = elements.wrap.getBoundingClientRect(),
        vrect  = elements.snap.getBoundingClientRect(),
        root   = elements.root.getBoundingClientRect(),
        top    = vrect.bottom - root.top,
        bot    = root.bottom - vrect.top,
        left   = hrect.left - root.left,
        width  = hrect.width,
        styles = {
          left:     left + 'px',
          minWidth: width + 'px',
          maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px'
        };
    if (top > bot && root.height - hrect.bottom - MENU_PADDING < MAX_HEIGHT) {
      styles.top = 'auto';
      styles.bottom = bot + 'px';
      styles.maxHeight = Math.min(MAX_HEIGHT, hrect.top - root.top - MENU_PADDING) + 'px';
    } else {
      styles.top = top + 'px';
      styles.bottom = 'auto';
      styles.maxHeight = Math.min(MAX_HEIGHT, root.bottom - hrect.bottom - MENU_PADDING) + 'px';
    }
    elements.$.ul.css(styles);
    $timeout(correctHorizontalAlignment, 0, false);

    function correctHorizontalAlignment () {
      var dropdown = elements.ul.getBoundingClientRect(),
          styles   = {};
      if (dropdown.right > root.right - MENU_PADDING) {
        styles.left = (hrect.right - dropdown.width) + 'px';
      }
      elements.$.ul.css(styles);
    }
  }

  function moveDropdown () {
    if (!elements.$.root.length) return;
    $mdTheming(elements.$.ul);
    elements.$.ul.detach();
    elements.$.root.append(elements.$.ul);
    if ($animate.pin) $animate.pin(elements.$.ul, $rootElement);
  }

  function focusElement () {
    if ($scope.autofocus) elements.input.focus();
  }

  function configureWatchers () {
    var wait = parseInt($scope.delay, 10) || 0;
    $scope.$watch('searchText', wait
        ? $mdUtil.debounce(handleSearchText, wait)
        : handleSearchText);
    registerSelectedItemWatcher(selectedItemChange);
    $scope.$watch('selectedItem', handleSelectedItemChange);
    $scope.$watch('$mdAutocompleteCtrl.hidden', function (hidden, oldHidden) {
      if (!hidden && oldHidden) positionDropdown();
    });
    angular.element($window).on('resize', positionDropdown);
  }

  function gatherElements () {
    elements = {
      main:  $element[0],
      ul:    $element.find('ul')[0],
      input: $element.find('input')[0],
      wrap:  $element.find('md-autocomplete-wrap')[0],
      root:  document.body
    };
    elements.li = elements.ul.getElementsByTagName('li');
    elements.snap = getSnapTarget();
    elements.$ = getAngularElements(elements);
  }

  function getSnapTarget () {
    for (var element = $element; element.length; element = element.parent()) {
      if (angular.isDefined(element.attr('md-autocomplete-snap'))) return element[0];
    }
    return elements.wrap;
  }

  function getAngularElements (elements) {
    var obj = {};
    for (var key in elements) {
      obj[key] = angular.element(elements[key]);
    }
    return obj;
  }

  //-- event/change handlers

  function selectedItemChange (selectedItem, previousSelectedItem) {
    if (selectedItem) {
      $scope.searchText = getDisplayValue(selectedItem);
    }
    if ($scope.itemChange && selectedItem !== previousSelectedItem)
      $scope.itemChange(getItemScope(selectedItem));
  }

  function handleSelectedItemChange(selectedItem, previousSelectedItem) {
    for (var i = 0; i < selectedItemWatchers.length; ++i) {
      selectedItemWatchers[i](selectedItem, previousSelectedItem);
    }
  }

  /**
   * Register a function to be called when the selected item changes.
   * @param cb
   */
  function registerSelectedItemWatcher(cb) {
    if (selectedItemWatchers.indexOf(cb) == -1) {
      selectedItemWatchers.push(cb);
    }
  }

  /**
   * Unregister a function previously registered for selected item changes.
   * @param cb
   */
  function unregisterSelectedItemWatcher(cb) {
    var i = selectedItemWatchers.indexOf(cb);
    if (i != -1) {
      selectedItemWatchers.splice(i, 1);
    }
  }

  function handleSearchText (searchText, previousSearchText) {
    self.index = getDefaultIndex();
    //-- do nothing on init
    if (searchText === previousSearchText) return;
    //-- clear selected item if search text no longer matches it
    if (searchText !== getDisplayValue($scope.selectedItem)) $scope.selectedItem = null;
    else return;
    //-- trigger change event if available
    if ($scope.textChange && searchText !== previousSearchText)
      $scope.textChange(getItemScope($scope.selectedItem));
    //-- cancel results if search text is not long enough
    if (!isMinLengthMet()) {
      self.loading = false;
      self.matches = [];
      self.hidden = shouldHide();
      updateMessages();
    } else {
      handleQuery();
    }
  }

  function blur () {
    hasFocus = false;
    if (!noBlur) self.hidden = true;
  }

  function focus () {
    hasFocus = true;
    //-- if searchText is null, let's force it to be a string
    if (!angular.isString($scope.searchText)) $scope.searchText = '';
    if ($scope.minLength > 0) return;
    self.hidden = shouldHide();
    if (!self.hidden) handleQuery();
  }

  function keydown (event) {
    switch (event.keyCode) {
      case $mdConstant.KEY_CODE.DOWN_ARROW:
        if (self.loading) return;
        event.preventDefault();
        self.index = Math.min(self.index + 1, self.matches.length - 1);
        updateScroll();
        updateSelectionMessage();
        break;
      case $mdConstant.KEY_CODE.UP_ARROW:
        if (self.loading) return;
        event.preventDefault();
        self.index = self.index < 0 ? self.matches.length - 1 : Math.max(0, self.index - 1);
        updateScroll();
        updateSelectionMessage();
        break;
      case $mdConstant.KEY_CODE.TAB:
      case $mdConstant.KEY_CODE.ENTER:
        if (self.hidden || self.loading || self.index < 0 || self.matches.length < 1) return;
        event.preventDefault();
        select(self.index);
        break;
      case $mdConstant.KEY_CODE.ESCAPE:
        self.matches = [];
        self.hidden = true;
        self.index = getDefaultIndex();
        break;
      default:
    }
  }

  //-- getters

  function getMinLength () {
    return angular.isNumber($scope.minLength) ? $scope.minLength : 1;
  }

  function getDisplayValue (item) {
    return (item && $scope.itemText) ? $scope.itemText(getItemScope(item)) : item;
  }

  function getItemScope (item) {
    if (!item) return;
    var locals = {};
    if (self.itemName) locals[self.itemName] = item;
    return locals;
  }

  function getDefaultIndex () {
    return $scope.autoselect ? 0 : -1;
  }

  function shouldHide () {
    if (!isMinLengthMet()) return true;
  }

  function getCurrentDisplayValue () {
    return getDisplayValue(self.matches[self.index]);
  }

  function isMinLengthMet () {
    return $scope.searchText.length >= getMinLength();
  }

  //-- actions

  function select (index) {
    $scope.selectedItem = self.matches[index];
    $scope.searchText = getDisplayValue($scope.selectedItem) || $scope.searchText;
    self.hidden = true;
    self.index = 0;
    self.matches = [];
  }

  function clearValue () {
    $scope.searchText = '';
    select(-1);

    // Per http://www.w3schools.com/jsref/event_oninput.asp
    var eventObj = document.createEvent('CustomEvent');
    eventObj.initCustomEvent('input', true, true, {value: $scope.searchText});
    elements.input.dispatchEvent(eventObj);

    elements.input.focus();
  }

  function fetchResults (searchText) {
    var items = $scope.$parent.$eval(itemExpr),
        term = searchText.toLowerCase();
    if (angular.isArray(items)) {
      handleResults(items);
    } else {
      self.loading = true;
      if (items.success) items.success(handleResults);
      if (items.then)    items.then(handleResults);
      if (items.error)   items.error(function () { self.loading = false; });
    }
    function handleResults (matches) {
      cache[term] = matches;
      self.loading = false;
      if (searchText !== $scope.searchText) return; //-- just cache the results if old request
      promise = null;
      self.matches = matches;
      self.hidden = shouldHide();
      updateMessages();
      positionDropdown();
    }
  }

  function updateMessages () {
    if (self.hidden) return;
    switch (self.matches.length) {
      case 0:  return self.messages.splice(0);
      case 1:  return self.messages.push({ display: 'There is 1 match available.' });
      default: return self.messages.push({ display: 'There are '
          + self.matches.length
          + ' matches available.' });
    }
  }

  function updateSelectionMessage () {
    self.messages.push({ display: getCurrentDisplayValue() });
  }

  function updateScroll () {
    var li  = elements.li[self.index],
        top = li.offsetTop,
        bot = top + li.offsetHeight,
        hgt = elements.ul.clientHeight;
    if (top < elements.ul.scrollTop) {
      elements.ul.scrollTop = top;
    } else if (bot > elements.ul.scrollTop + hgt) {
      elements.ul.scrollTop = bot - hgt;
    }
  }

  function handleQuery () {
    var searchText = $scope.searchText,
        term = searchText.toLowerCase();
    //-- cancel promise if a promise is in progress
    if (promise && promise.cancel) {
      promise.cancel();
      promise = null;
    }
    //-- if results are cached, pull in cached results
    if (!$scope.noCache && cache[term]) {
      self.matches = cache[term];
      updateMessages();
    } else {
      fetchResults(searchText);
    }
    self.hidden = shouldHide();
  }

}
<|endoftext|>


<commit_before>var questions = [];
var question_number = -1;
var questions_shown = 0;
var max_questions = 0;

var current_points = 0;
var global_question= null;
var assumption_selected = [];
var submit_reasons_set = false;

function display_feedback_for_assumptions(){
    // window.alert("display_feedback_for_assumptions");
    var assumptions_ele = global_question["assumptions"];
    for(i=0;i<assumptions_ele.length;i++){
        // window.alert(i);
        var existing_content = document.getElementById("assm_"+i).innerHTML;
        if(assumptions_ele[i]["assumption_type"]=="needed"){
           // window.alert("needed");
           // document.getElementById("assm_"+i).innerHTML = existing_content.replace('
',' ');
           // document.getElementById("assm_"+i).innerHTML += "
Success! Indicates a successful or positive action.
";
           // document.getElementById("assm_"+i).innerHTML +="
hi
"
           document.getElementById("assm_"+i).style.color = "green";

        }
        else if(assumptions_ele[i]["assumption_type"]=="unneeded"){
           document.getElementById("assm_"+i).style.color = "red";

        }
        else if(assumptions_ele[i]["assumption_type"]=="complicatingfactor"){
           document.getElementById("assm_"+i).style.color = "blue";

        }
    }
}

function check_atleast_one_selected(){
    var atleast_one_selected = false;

    var checkboxes = document.getElementsByName('all_assumptions_chk_bx');
    for (i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].type == 'checkbox' && checkboxes[i].checked) {
            atleast_one_selected = true;
        }

    }

    if(atleast_one_selected == false){
        return false;
    }
    return true;
}

function evaluate_assumptions_submission() {
    if(!check_atleast_one_selected()){
        window.alert("Select Assumptions!!!");
        return false;
    }
    var k = 0; //to populate assumption selected array. Multiple assumptions can be selected.
    var checkboxes = document.getElementsByName('all_assumptions_chk_bx');
    submit_reasons_set = false;
    for (i = 0; i < checkboxes.length; i++) {
        //process only if the checkbox is checked. else just disable the checkbox.
        if (checkboxes[i].type == 'checkbox' && checkboxes[i].checked) {
            assumption_selected[k] = checkboxes[i].value; // if first checkbox checked then 0 stored in array.
            var assumptions_ele = global_question["assumptions"];
            if(assumptions_ele[assumption_selected[k]]["assumption_type"]=="needed"){
                document.getElementById("chk_"+i).disabled= true;
                console.log("assumption type needed");
                current_points+=assumptions_ele[assumption_selected[k]]["assumption_points"];
                console.log("modified points:"+current_points);
                // document.getElementById('score_display_ele').innerHTML = "Score obtained : "+current_points;
                console.log("Score displayed");
                document.getElementById("next").disabled= false;
            }
            else if(assumptions_ele[assumption_selected[k]]["assumption_type"]=="unneeded" || assumptions_ele[assumption_selected[k]]["assumption_type"]=="complicatingfactor"){
                console.log("assumption type unneeded or complicatingfactor");
                document.getElementById("chk_"+i).disabled= true;

                current_points+=assumptions_ele[assumption_selected[k]]["assumption_points"];
                console.log("modified points:"+current_points);
                //Display reasons
                var all_reasons = assumptions_ele[assumption_selected[k]]["reasons"];

                if(all_reasons != null){
                    display_reasons(i,all_reasons);
                }

            }
        }
        else{
            //blurr the checkbox
            console.log("checkbox not selected : "+checkboxes[i].value);
            document.getElementById("chk_"+i).disabled= true;

        }
        //k is incremented here so as to be able to use k in between.
        k++;
    }

    display_feedback_for_assumptions();

    document.getElementById('Submit_assm').hidden = true;

    document.getElementById('score_button_id').innerHTML = "Score: "+current_points;

    return false;

}
function display_reasons(i,all_reasons){

    for (j = 0; j < all_reasons.length; j++){
        document.getElementById('assm_'+i).innerHTML += "<input type='radio' name='reasons_"+i+"' value="+j+" id = rd_"+j+" >"+all_reasons[j]["reason_text"]+"
";
    }
    console.log("Reason checkboxes displayed");

    //show submit button as well once all the radios are loaded.

    if(submit_reasons_set == false){
       document.getElementById('reasons').innerHTML += "<input type='submit' id='submit_reasons' name='Submit_reasons' class='btn btn-primary' value='Submit Reason'>";
       submit_reasons_set = true;
    }
    console.log("Reason submit displayed");

}

function evaluate_reasons_submission(){

    console.log("evaluate_reasons_submission");
    document.getElementById('submit_reasons').hidden = true;

    for (each_assm in assumption_selected){
        var radios = document.getElementsByName('reasons_'+each_assm);
        document.getElementsByName('reasons_'+each_assm).disabled = true;
        for (i = 0; i < radios.length; i++) {
            radios[i].disabled = true;
            if (radios[i].type == 'radio' && radios[i].checked) {
                // assumption_selected = radios[i].value;
                console.log("radio selected:"+radios[i].value);
                var reas_seq = radios[i].value;
                console.log("points for this reason :"+global_question["assumptions"][each_assm]["reasons"][reas_seq]["reason_points"]);
                current_points += global_question["assumptions"][each_assm]["reasons"][reas_seq]["reason_points"];
                console.log("modified points:"+current_points);

            }
        }
    }
    document.getElementById('score_button_id').innerHTML = "Score: "+current_points;
    console.log("Score displayed");
    document.getElementById("next").disabled= false;
    return false;

}

function display_assumptions(q) {
    document.getElementById("questionbody").style.visibility = "visible";
    // document.getElementById('question_ele').innerHTML += "
" +""+q["questiontitle"]+"" + "
";
    var assumptions_ele = q["assumptions"];
    create_checkboxes(assumptions_ele);

    //show submit button as well once all the radios are loaded.

    document.getElementById('assumptions').innerHTML += "<input type='submit' name='Submit' id='Submit_assm' class='btn btn-primary' value='Submit'>"+"
";

    display_images(q);
    return false;
}

function display_images(q){
    document.getElementById('realworld').innerHTML = "";
    document.getElementById('idealized').innerHTML = "";
}
function create_checkboxes(assumptions_ele){
    for (i = 0; i < assumptions_ele.length; i++){
            document.getElementById('assumptions').innerHTML += "
<input type='checkbox' name='all_assumptions_chk_bx' value="+i+" id= chk_"+i+">"+assumptions_ele[i]["assumption_text"]+"

";
        }

}

function select_random_question() {
    if (questions.length == 0) return false;
    question_number = Math.floor(questions.length * Math.random());
    var random_question = questions.splice(question_number, 1)[0];
    global_question = random_question;
    return true;
}

function display_question() {
    set_questiontitle(global_question.questiontitle);
    display_assumptions(global_question);
}

function load_questions() {
    try {
        var p = new parser(questions_config);
        questions = p.parse();
        max_questions = questions.length;
        questions_shown = 1;
        if (questions.length == 0)
            alert("That file seems to have no questions.");
        else {
            select_random_question();
            set_progress_bar();
            display_question();
        }
    } catch (e) {
        alert("Something went wrong: " + e);
    }
    return false;
}

function set_questiontitle(t) {
    document.getElementById('questiontitle').innerHTML = t;
}

function set_progress_bar(p) {
    var percent_done = (100 * (questions_shown-1) / max_questions) + '%';
    if (p) percent_done = p + '%';
    console.log('width: ' + percent_done);
    document.getElementById('progbar').style = 'width: ' + percent_done;
    document.getElementById('readable_percent_done').innerHTML = percent_done + " Complete";
}

function load_nextquestion() {
   // document.getElementById('question_ele').innerHTML = "Question goes here";
    var rad= document.getElementsByName("selection");
    remove_ele(rad);
    if(document.getElementsByName("reasons")!=null){
        remove_ele(document.getElementsByName("reasons"));
    }
    document.getElementById("assumptions").innerHTML = "";
    document.getElementById("reasons").innerHTML = "";
    // document.getElementById("score_display_ele").innerHTML = "Score obtained : "+current_points;
    document.getElementById("score_display_reasons").innerHTML= " ";
    document.getElementById("next").disabled= true;

    if (select_random_question()) {
        questions_shown += 1;
        set_progress_bar();
        display_question();
    }
    else {
        document.getElementById('question_images').hidden = true;
        set_progress_bar(100);
        set_questiontitle("You've completed all of the questions!");
    }
}
function remove_ele(ele){
    for(i=0;i<ele.length;i++){
        var id = ele[i].getAttribute('id');
        document.getElementById(id).remove();
    }
}
<commit_msg>issue 60 resolved.<commit_after>var questions = [];
var question_number = -1;
var questions_shown = 0;
var max_questions = 0;

var current_points = 0;
var global_question= null;
var assumption_selected = [];
var submit_reasons_set = false;

function display_feedback_for_assumptions(){
    // window.alert("display_feedback_for_assumptions");
    var assumptions_ele = global_question["assumptions"];
    var checkboxes = document.getElementsByName('all_assumptions_chk_bx');
    for(i=0;i<assumptions_ele.length;i++){
        // window.alert(i);
        var existing_content = document.getElementById("assm_"+i).innerHTML;
        if(assumptions_ele[i]["assumption_type"]=="needed"){
           // window.alert("needed");
           // document.getElementById("assm_"+i).innerHTML = existing_content.replace('
',' ');
           // document.getElementById("assm_"+i).innerHTML += "
Success! Indicates a successful or positive action.
";
           // document.getElementById("assm_"+i).innerHTML +="
hi
"
           document.getElementById("assm_"+i).style.color = "green";

        }
        else if(assumptions_ele[i]["assumption_type"]=="unneeded"){
            if(checkboxes[i].checked){
                document.getElementById("assm_"+i).style.color = "red";
            }else{
                document.getElementById("assm_"+i).style.color = "#D3D3D3";
            }

        }
        else if(assumptions_ele[i]["assumption_type"]=="complicatingfactor"){
           document.getElementById("assm_"+i).style.color = "blue";

        }
    }
}

function check_atleast_one_selected(){
    var atleast_one_selected = false;

    var checkboxes = document.getElementsByName('all_assumptions_chk_bx');
    for (i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].type == 'checkbox' && checkboxes[i].checked) {
            atleast_one_selected = true;
        }

    }

    if(atleast_one_selected == false){
        return false;
    }
    return true;
}

function evaluate_assumptions_submission() {
    if(!check_atleast_one_selected()){
        window.alert("Select Assumptions!!!");
        return false;
    }
    var k = 0; //to populate assumption selected array. Multiple assumptions can be selected.
    var checkboxes = document.getElementsByName('all_assumptions_chk_bx');
    submit_reasons_set = false;
    for (i = 0; i < checkboxes.length; i++) {

        assumption_selected[k] = checkboxes[i].value; // if first checkbox checked then 0 stored in array.
        var assumptions_ele = global_question["assumptions"];

        //process only if the checkbox is checked. else just disable the checkbox.
        if (checkboxes[i].type == 'checkbox' && checkboxes[i].checked) {
            // assumption_selected[k] = checkboxes[i].value; // if first checkbox checked then 0 stored in array.
            // var assumptions_ele = global_question["assumptions"];
            if(assumptions_ele[assumption_selected[k]]["assumption_type"]=="needed"){
                document.getElementById("chk_"+i).disabled= true;
                console.log("assumption type needed");
                current_points+=assumptions_ele[assumption_selected[k]]["assumption_points"];
                console.log("modified points:"+current_points);
                // document.getElementById('score_display_ele').innerHTML = "Score obtained : "+current_points;
                console.log("Score displayed");
                document.getElementById("next").disabled= false;
            }
            else if(assumptions_ele[assumption_selected[k]]["assumption_type"]=="unneeded" || assumptions_ele[assumption_selected[k]]["assumption_type"]=="complicatingfactor"){
                console.log("assumption type unneeded or complicatingfactor");
                document.getElementById("chk_"+i).disabled= true;

                current_points+=assumptions_ele[assumption_selected[k]]["assumption_points"];
                console.log("modified points:"+current_points);
                //Display reasons
                var all_reasons = assumptions_ele[assumption_selected[k]]["reasons"];

                if(all_reasons != null){
                    display_reasons(i,all_reasons);
                }

            }
        }
        else{
            //blurr the checkbox
            console.log("checkbox not selected : "+checkboxes[i].value);
            document.getElementById("chk_"+i).disabled= true;

        }
        //k is incremented here so as to be able to use k in between.
        k++;
    }

    display_feedback_for_assumptions();

    document.getElementById('Submit_assm').hidden = true;

    document.getElementById('score_button_id').innerHTML = "Score: "+current_points;

    return false;

}
function display_reasons(i,all_reasons){

    for (j = 0; j < all_reasons.length; j++){
        document.getElementById('assm_'+i).innerHTML += "<input type='radio' name='reasons_"+i+"' value="+j+" id = rd_"+j+" >"+all_reasons[j]["reason_text"]+"
";
    }

    document.getElementById("chk_"+i).checked = true;

    console.log("Reason checkboxes displayed");

    //show submit button as well once all the radios are loaded.

    if(submit_reasons_set == false){
       document.getElementById('reasons').innerHTML += "<input type='submit' id='submit_reasons' name='Submit_reasons' class='btn btn-primary' value='Submit Reason'>";
       submit_reasons_set = true;
    }
    console.log("Reason submit displayed");

}

function evaluate_reasons_submission(){

    console.log("evaluate_reasons_submission");
    document.getElementById('submit_reasons').hidden = true;

    for (each_assm in assumption_selected){
        var radios = document.getElementsByName('reasons_'+each_assm);
        document.getElementsByName('reasons_'+each_assm).disabled = true;
        for (i = 0; i < radios.length; i++) {
            radios[i].disabled = true;
            if (radios[i].type == 'radio' && radios[i].checked) {
                // assumption_selected = radios[i].value;
                console.log("radio selected:"+radios[i].value);
                var reas_seq = radios[i].value;
                console.log("points for this reason :"+global_question["assumptions"][each_assm]["reasons"][reas_seq]["reason_points"]);
                current_points += global_question["assumptions"][each_assm]["reasons"][reas_seq]["reason_points"];
                console.log("modified points:"+current_points);

            }
        }
    }
    document.getElementById('score_button_id').innerHTML = "Score: "+current_points;
    console.log("Score displayed");
    document.getElementById("next").disabled= false;
    return false;

}

function display_assumptions(q) {
    document.getElementById("questionbody").style.visibility = "visible";
    // document.getElementById('question_ele').innerHTML += "
" +""+q["questiontitle"]+"" + "
";
    var assumptions_ele = q["assumptions"];
    create_checkboxes(assumptions_ele);

    //show submit button as well once all the radios are loaded.

    document.getElementById('assumptions').innerHTML += "<input type='submit' name='Submit' id='Submit_assm' class='btn btn-primary' value='Submit'>"+"
";

    display_images(q);
    return false;
}

function display_images(q){
    document.getElementById('realworld').innerHTML = "";
    document.getElementById('idealized').innerHTML = "";
}
function create_checkboxes(assumptions_ele){
    for (i = 0; i < assumptions_ele.length; i++){
            document.getElementById('assumptions').innerHTML += "
<input type='checkbox' name='all_assumptions_chk_bx' value="+i+" id= chk_"+i+">"+assumptions_ele[i]["assumption_text"]+"

";
        }

}

function select_random_question() {
    if (questions.length == 0) return false;
    question_number = Math.floor(questions.length * Math.random());
    var random_question = questions.splice(question_number, 1)[0];
    global_question = random_question;
    return true;
}

function display_question() {
    set_questiontitle(global_question.questiontitle);
    display_assumptions(global_question);
}

function load_questions() {
    try {
        var p = new parser(questions_config);
        questions = p.parse();
        max_questions = questions.length;
        questions_shown = 1;
        if (questions.length == 0)
            alert("That file seems to have no questions.");
        else {
            select_random_question();
            set_progress_bar();
            display_question();
        }
    } catch (e) {
        alert("Something went wrong: " + e);
    }
    return false;
}

function set_questiontitle(t) {
    document.getElementById('questiontitle').innerHTML = t;
}

function set_progress_bar(p) {
    var percent_done = (100 * (questions_shown-1) / max_questions) + '%';
    if (p) percent_done = p + '%';
    console.log('width: ' + percent_done);
    document.getElementById('progbar').style = 'width: ' + percent_done;
    document.getElementById('readable_percent_done').innerHTML = percent_done + " Complete";
}

function load_nextquestion() {
   // document.getElementById('question_ele').innerHTML = "Question goes here";
    var rad= document.getElementsByName("selection");
    remove_ele(rad);
    if(document.getElementsByName("reasons")!=null){
        remove_ele(document.getElementsByName("reasons"));
    }
    document.getElementById("assumptions").innerHTML = "";
    document.getElementById("reasons").innerHTML = "";
    // document.getElementById("score_display_ele").innerHTML = "Score obtained : "+current_points;
    document.getElementById("score_display_reasons").innerHTML= " ";
    document.getElementById("next").disabled= true;

    if (select_random_question()) {
        questions_shown += 1;
        set_progress_bar();
        display_question();
    }
    else {
        document.getElementById('question_images').hidden = true;
        set_progress_bar(100);
        set_questiontitle("You've completed all of the questions!");
    }
}
function remove_ele(ele){
    for(i=0;i<ele.length;i++){
        var id = ele[i].getAttribute('id');
        document.getElementById(id).remove();
    }
}
<|endoftext|>