<commit_before>'use strict';

var jsdom = require('jsdom');
var fs = require('fs');

var Context = function (template) {
    // We provide an empty DOM that allows some basic parts of AngularJS to work,
    // but we're not actually expecting to render an app in here... it just gives
    // us an anchor document so we can do things like call document.createElement
    // when using jqLite/jQuery.
    var document = jsdom.jsdom(
        template,
        null,
        {
            features: {
                // Don't do anything with external resources, since we're not actually
                // trying to emulate a browser here, just a DOM.
                FetchExternalResources: false,
                ProcessExternalResources: false,
                SkipExternalResources: false,
                MutationEvents: false
            }
        }
    );
    var window = document.parentWindow;
    // 'window' has already been contextified by jsdom, so we can just use it.
    var rawContext = window;
    var disposeCallbacks = [];

    // Run some code in the context, then run a callback.
    // The first parameter is list of items. Each of these can be in of the forms:
    // a) "filename to read and run"
    // b) ["source code", "indicative filename for debuging"]
    var runMulti = function (files, callback) {
        var loadedCount = 0;
        var firstError;
        var sources = [];
        var filenames = [];
        sources.length = files.length;
        filenames.length = files.length;

        var runSources = function () {
            if (firstError) {
                callback(false, firstError);
            }
            else {
                // now run the sources in the correct order
                try {
                    for (var i = 0; i < sources.length; i++) {
                        rawContext.run(sources[i], filenames[i]);
                    }
                }
                catch (err) {
                    firstError = err;
                    callback(false, err);
                }
            }
            if (! firstError) {
                callback(true);
            }
        };

        var makeLoadHandler = function (i) {
            return function (err, data) {
                loadedCount++;
                if (err) {
                    if (! firstError) {
                        firstError = err;
                    }
                }
                else {
                    sources[i] = data;
                }
                if (loadedCount === files.length) {
                    // we've got everything loaded, so now run them
                    runSources();
                }
            };
        };

        for (var i = 0; i < files.length; i++) {
            if (files[i] instanceof Array) {
                filenames[i] = files[i][0];
                sources[i] = files[i][1];
                loadedCount++;
                if (loadedCount === files.length) {
                    // we've got everything loaded, so now run them
                    runSources();
                }
            }
            else {
                filenames[i] = files[i];
                fs.readFile(
                    files[i],
                    'utf8',
                    makeLoadHandler(i)
                );
            }
        }

    };

    return {
        run: function (source, filename) {
            rawContext.run(source, filename);
        },

        runFile: function (fileName, callback) {
            runFiles([fileName], callback);
            fs.readFile(
                fileName,
                'utf8',
                function (err, data) {
                    if (err) {
                        callback(undefined, err);
                    }
                    else {
                        callback(rawContext.run(data, fileName));
                    }
                }
            );
        },

        // Deprecated, provided for compat only
        runFiles: runMulti,

        runMulti: runMulti,

        hasAngular: function () {
            return typeof rawContext.angular === 'object';
        },

        getAngular: function () {
            return rawContext.angular;
        },

        hasRequire: function () {
            return typeof rawContext.require === 'object';
        },

        getRequire: function () {
            return rawContext.require;
        },

        module: function () {
            return rawContext.angular.module.apply(
                rawContext.angular.module,
                arguments
            );
        },

        injector: function (modules) {
            return rawContext.angular.injector(modules);
        },

        bootstrap: function (element, modules) {
            if (modules === undefined) {
                modules = element;
                element = document;
            }
            return rawContext.angular.bootstrap(element, modules);
        },

        element: function (param) {
            return rawContext.angular.element(param);
        },

        onDispose: function (cb) {
            disposeCallbacks.push(cb);
        },

        dispose: function () {
            // First call the dispose callbacks to give callers an opportunity to clean up
            // any pending async events. (If they don't do this then the app can crash
            // when the operations complete, since their state has been freed.)
            for (var i = 0; i < disposeCallbacks.length; i++) {
                disposeCallbacks[i](this);
            }
            window.close();
        }
    };
};

exports.Context = Context;
<commit_msg>The source code is on index 0<commit_after>'use strict';

var jsdom = require('jsdom');
var fs = require('fs');

var Context = function (template) {
    // We provide an empty DOM that allows some basic parts of AngularJS to work,
    // but we're not actually expecting to render an app in here... it just gives
    // us an anchor document so we can do things like call document.createElement
    // when using jqLite/jQuery.
    var document = jsdom.jsdom(
        template,
        null,
        {
            features: {
                // Don't do anything with external resources, since we're not actually
                // trying to emulate a browser here, just a DOM.
                FetchExternalResources: false,
                ProcessExternalResources: false,
                SkipExternalResources: false,
                MutationEvents: false
            }
        }
    );
    var window = document.parentWindow;
    // 'window' has already been contextified by jsdom, so we can just use it.
    var rawContext = window;
    var disposeCallbacks = [];

    // Run some code in the context, then run a callback.
    // The first parameter is list of items. Each of these can be in of the forms:
    // a) "filename to read and run"
    // b) ["source code", "indicative filename for debuging"]
    var runMulti = function (files, callback) {
        var loadedCount = 0;
        var firstError;
        var sources = [];
        var filenames = [];
        sources.length = files.length;
        filenames.length = files.length;

        var runSources = function () {
            if (firstError) {
                callback(false, firstError);
            }
            else {
                // now run the sources in the correct order
                try {
                    for (var i = 0; i < sources.length; i++) {
                        rawContext.run(sources[i], filenames[i]);
                    }
                }
                catch (err) {
                    firstError = err;
                    callback(false, err);
                }
            }
            if (! firstError) {
                callback(true);
            }
        };

        var makeLoadHandler = function (i) {
            return function (err, data) {
                loadedCount++;
                if (err) {
                    if (! firstError) {
                        firstError = err;
                    }
                }
                else {
                    sources[i] = data;
                }
                if (loadedCount === files.length) {
                    // we've got everything loaded, so now run them
                    runSources();
                }
            };
        };

        for (var i = 0; i < files.length; i++) {
            if (files[i] instanceof Array) {
                sources[i] = files[i][0];
                filenames[i] = files[i][1];
                loadedCount++;
                if (loadedCount === files.length) {
                    // we've got everything loaded, so now run them
                    runSources();
                }
            }
            else {
                filenames[i] = files[i];
                fs.readFile(
                    files[i],
                    'utf8',
                    makeLoadHandler(i)
                );
            }
        }

    };

    return {
        run: function (source, filename) {
            rawContext.run(source, filename);
        },

        runFile: function (fileName, callback) {
            runFiles([fileName], callback);
            fs.readFile(
                fileName,
                'utf8',
                function (err, data) {
                    if (err) {
                        callback(undefined, err);
                    }
                    else {
                        callback(rawContext.run(data, fileName));
                    }
                }
            );
        },

        // Deprecated, provided for compat only
        runFiles: runMulti,

        runMulti: runMulti,

        hasAngular: function () {
            return typeof rawContext.angular === 'object';
        },

        getAngular: function () {
            return rawContext.angular;
        },

        hasRequire: function () {
            return typeof rawContext.require === 'object';
        },

        getRequire: function () {
            return rawContext.require;
        },

        module: function () {
            return rawContext.angular.module.apply(
                rawContext.angular.module,
                arguments
            );
        },

        injector: function (modules) {
            return rawContext.angular.injector(modules);
        },

        bootstrap: function (element, modules) {
            if (modules === undefined) {
                modules = element;
                element = document;
            }
            return rawContext.angular.bootstrap(element, modules);
        },

        element: function (param) {
            return rawContext.angular.element(param);
        },

        onDispose: function (cb) {
            disposeCallbacks.push(cb);
        },

        dispose: function () {
            // First call the dispose callbacks to give callers an opportunity to clean up
            // any pending async events. (If they don't do this then the app can crash
            // when the operations complete, since their state has been freed.)
            for (var i = 0; i < disposeCallbacks.length; i++) {
                disposeCallbacks[i](this);
            }
            window.close();
        }
    };
};

exports.Context = Context;
<|endoftext|>


<commit_before>'use babel'

/* @flow */

import DebuggerMi2 from './debugger-mi2'
import type { EventDefs } from 'debugger'

module.exports = {
  instance: null,
  BreakpointEvent: null,
  SessionEvent: null,
  TargetEvent: null,

  activate(): void {
    this.instance = new DebuggerMi2()
  },

  consumeEventDefs(eventDefs: EventDefs): void {
    this.BreakpointEvent = eventDefs.BreakpointEvent
    this.SessionEvent    = eventDefs.SessionEvent
    this.TargetEvent     = eventDefs.TargetEvent
  },

  provideDebugger(): DebuggerMi2 {
    return this.instance
  }
}
<commit_msg>Update event defs to get VariableEvent<commit_after>'use babel'

/* @flow */

import DebuggerMi2 from './debugger-mi2'
import type { EventDefs } from 'debugger'

module.exports = {
  instance: null,
  BreakpointEvent: null,
  SessionEvent: null,
  TargetEvent: null,
  VariableEvent: null,

  activate(): void {
    this.instance = new DebuggerMi2()
  },

  consumeEventDefs(eventDefs: EventDefs): void {
    this.BreakpointEvent = eventDefs.BreakpointEvent
    this.SessionEvent    = eventDefs.SessionEvent
    this.TargetEvent     = eventDefs.TargetEvent
    this.VariableEvent   = eventDefs.VariableEvent
  },

  provideDebugger(): DebuggerMi2 {
    return this.instance
  }
}
<|endoftext|>


<commit_before>
/*
	jCheck is a quick and dumn property testing framework for JavaScript / Node.

*/

/*
	Helper Functions.

*/

/*
	Remove the first element from an array.

	@param {[any]}
*/

const restOf = function (coll) {

	var out = []

	for (var ith = 0; ith < coll.length; ith++) {
		if (ith !== 0) {
			out = out.concat( coll[ith] )
		}
	}

	return out
}

/*
	Get the unique values in a collection.
*/

const uniqueOf = function (coll) {

	var set = []

	for (var ith = 0; ith < coll.length; ith++) {

		var elem     = coll[ith]
		var hasMatch = false

		for (var jth = 0; jth < set.length; jth++) {
			if (elem === set[jth]) {
				hasMatch = true
			}
		}

		if (!hasMatch) {
			set.push(elem)
		}
	}

	return set
}

/*
	Get the indices of a collection.
*/

const indicesOf = function (coll) {

	var indices = []

	for (var ith = 0; ith < coll.length; ith++) {
		indices[ith] = ith
	}

	return indices

}

/*
	takes a number of seconds, and
	returns a function that returns true if
	called within that timespan after creation.

*/

const stopwatch = function (num) {

	const posixTime = function () {

		return Math.round((new Date).getTime() / 1000.0)
	}

	const genesis = posixTime()

	return function () {

		const lifespan  = posixTime() - genesis
		return lifespan < num

	}
}

const rightPad = function (str, num) {
	return str.length < num? str + Array(num - str.length).join(' '): str
}

const colourise = {
	red    : function (x) {return x},
	yellow : function (x) {return x}
}

const fromStream = ( function () {

	var self = {}

	/*
		-------------------------------- Generators --------------------------------

	*/

	// -------------------------------- numeric --------------------------------

	self.number = function (len) {
		// uniform random number of a given order 'len'.

		const  sign = Math.random() > 0.5? +1: -1
		return sign * Math.random() * Math.pow(10, len)
	}
	self.integer = function (len) {
		// uniform random integer of a given order 'len'.

		return Math.round(self.number(len))
	}

	self.nan    = function (len) {
		return NaN
	}

	// -------------------------------- character --------------------------------

	self.alphabetical = (function () {
		// uppercase and lowecase letters in a string of length 'len'.

		const charset =
			'abcdefghijklmnopqrstuvwxyz' +
			'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

		return function (len) {

			var out = ''

			for (var ith = 0; ith < len; ith++) {
				out += charset.charAt(Math.random * charset.length)
			}

			return out
		}

	})()

	/*
		-------------------------------- Sampler --------------------------------

	*/

	return function (len) {
		// return a random generator.

		const generators = Object.keys(self)
		const ith        = generators[Math.floor(Math.random() * generators.length)]

		return self[ith](len)
	}

} )()

/*
	The core testing function.
*/

const runTest = function (tester, groups, state, testcase, info) {

	for (var groupIth = 0; groupIth < groups.length; groupIth++) {

		var group = groups[groupIth]

		var groupPred  = group[0]
		var groupProps = restOf(groups)

		var isMatch = groupPred.apply(null, testcase)

		state.casesExamined += 1

		if (!isMatch) {
			continue
		}

		state.testsRun += 1

		/*
			the predicate for this group was true; test each associated
			property.
		*/

		for (var propIth = 0; propIth < groupProps.length; propIth++) {

			var prop    = groupProps[propIth]
			var hasProp = tester(prop, testcase)

			// the result of the predicate was non-boolean.
			if (hasProp !== true && hasProp !== false) {
				var message =
					info + '\n' +
					colourise.red('Failed!') +
					' the property returned a non-logical result\n' +
					'For the test-case '

				throw message
			}

			if (!hasProp) {

				// note the earliest fail.
				state.failsAfter =
					Math.min(state.failsAfter, state.testsRun)

				// store the failed cases.
				state.failsFor =
					state.failsFor.concat([testcase])

				// store the index of the failed properties.

				var failedIndex = {
					group    : groupIth,
					property : propIth,
					summary  : groupIth + ', ' + propIth
				}

				state.failedIndices =
					[state.failedIndices, [failedIndex]]

			}
		}

	}

	return state
}

/*
	Generate bindings for each random variable.

	@param {[string]} strs. The parametres to be bound to a random value.
	@param {number} num. The length or order of the random value to be
	    generated.
*/

const yieldCase = function (strs, num) {

	return strs.map(function (param) {
		return fromStream(num)
	})

}

/*

*/

const propertyError = function (properties, testData, state) {

	const after    = state.failsAfter
	const failsFor = state.failsFor
	const indices  = state.failedIndices

	// whichFailed, descriptions are co-ordered

	const whichFailed  = uniqueOf(indices)

	const expressions  = whichFailed.map( function (triple) {

		const ith = triple.group
		const jth = triple.property + 1

	})

	const descriptions = whichFailed.map( function (triple) {
		testData.info[triple.group]
	})

	const paragraphs = 1

	const message = 'failed! After ' + after + ' cases'

	throw message
}

/*
	warn that no test-cases were given to some property group.
*/

const exhaustionWarning = function (testData, state, info) {

	const run      = state.testsRun
	const examined = state.casesExamined

	const message =
		info + colourise.yellow(" Failed!\n") +
		"all " + examined + " test cases were rejected."

	console.warn(message)
}

/*

*/

const successMessage = function (states, info) {
	/*

	*/

	const testsRun =
		states
		.map(function (state) {
			return state.testsRun
		})
		.reduce(function (acc, val) {
			return acc + ', ' + val
		})

	const message =
		rightPad("'"+ info + "'" + ' passed! ', 80)  + "(" + testsRun + ")"

	console.log(message)
}

/*

*/

const whenTest = function (prop, testcase) {
	// simply call the predicate with the testcase.

	return prop.apply(null, testcase)
}

/*
	ensure that the test being passed to run
	can be executed properly.
*/
const validateTest = function (test) {

	// throw an error if any fields are missing.
	;['info', 'params', 'time'].forEach(function (key) {

		if (!test.hasOwnProperty(key)) {
			var message =
				"the property '" + key + "' was missing from the test object."

			throw colourise.red(message)
		}
	})

	// time mustn't be NaN
	if (test.time !== test.time) {

		var message =
			'time must not be NaN.'

		throw colourise.red(message)
	}

	// time definitely mustn't be Infinite
	if (!isFinite(test.time)) {

		var message =
			'time must not be infinite.'

		throw colourise.red(message)
	}

	// time must be positive
	if (test.time < 0) {
		var message =
			'time must be positive.'

		throw colourise.red(message)
	}

	return true
}

/*
	The backend wrapper in which the test is executed.
*/

const executeTest = function (test) {

	validateTest(test)

	// attach the test data to the local environment.

	const info         = test.info
	const params       = test.params
	const time         = test.time
	const whenProperty = test.whenProperty

	const initialState = function () {
		return {
			casesExamined : 0,
			testsRun      : 0,
			failsFor      : [],
			failsAfter    : Infinity,
			failedIndices : []
		}
	}

	// each test subtype has its own state, tester and property group.

	var states       = [initialState()]
	const groupTypes = [whenProperty]
	const testers    = [whenTest]

	var timeLeft = stopwatch(time)

	/*
		execute the tests and collect statistics on the failures.
	*/

	const len = 10

	while (timeLeft()) {

		var testcase = yieldCase(params, len)

		for (var ith = 0; ith < states.length; ith++) {

			var test  = testers[ith]
			var group = groupTypes[ith]
			var state = states[ith]

			runTest(test, group, state, testcase, info)
		}

	}

	// additional data needed to report success or failure.

	const testData = {
		info: info,
		time: time
	}

	/*
		Check that the correct number of tests were run, and
		that none of the tests fail.
	*/

	for (var ith = 0; ith < states.length; ith++) {

		var group = groupTypes[ith]
		var state = states[ith]

		if (group.length > 0 && state.testsRun === 0) {
			/*
				No tests were run for a particular test group.
				Warn the user about this fact.
			*/
			exhaustionWarning(testData, state, info)
		}

		if (state.failsFor.length > 0) {
			/*
				Throw errors for this particular group.
			*/

			propertyError(group, testData, state)
		}

	}

	successMessage(states, info)
}

/*
	-------------------------------- Grammar --------------------------------

	describe(string)            add a description to a property group. Concatanative property.

	over([string])              the parametres to bind random variables to.
	                            Overriding property.

	over_(string_)              the parametres to bind random variables to.
	                            Overriding property.

	when(Function, [Function])  when a predicate is true, assert that several other
	                            predicates are also true. Concatanative property.

	when_(Function_)            when a predicate is true, assert that several other
	                            predicates are also true. Concatanative property.

	run(number)                 triggers the start of a test, specifies how long the test runs for.
*/

const describe = function (info) {

	var self  = joinTest(this, {
		info : info,
		type : 'describe'
	})

	return self
}

/*
	Bind random variables to test over.

	@param {[string]} strs. An array of strings.
*/

const over = function (strs) {

	var self  = joinTest(this, {
		params 	: strs,
		type   	: 'over'
	})

	return self
}

/*

*/

const over_ = function () {

	const args = Array.prototype.slice.call(arguments)

	var self  = joinTest(this, {
		params 	: args,
		type   	: 'over'
	})

	return self
}

/*
	When a predicate is true of a test-case, ensure several other predicates are true too.

	@param {Function}   pred:  a predicate function. This function tests if a test-case
	    is suitable to be given to a set of properties.

	@param {[Function]} preds: an array of predicate functions. These functions are
	    properties that must hold true for an test-case that matches `pred`.

	@return {object}
*/

const when = function (pred, preds) {

	var self  = joinTest(this, {
		whenProperty : [pred].concat(preds),
		type         : 'when'
	})

	return self
}

/*

*/

const when_ = function () {

	const args = Array.prototype.slice.call(arguments)

	var self  = joinTest(this, {
		whenProperty : args,
		type         : 'when'
	})

	return self
}

/*
	Run a test.

	@param {number} num. The number of seconds testing should continue for.
*/

const run = function (num) {

	var self  = joinTest(this, {
		time : num,
		type : 'run'
	})

	return self
}

const _forallProto = {
	run      : run,

	over     : over,
	over_    : over_,

	when     : when,
	when_    : when_,

	describe : describe
}

/*
	Test if an object is the global 'this' object.
*/

const isGlobalThis = function (obj) {
	return obj.GLOBAL || obj.window
}

/*
	JoinTest

	JoinTest takes the 'this' passed to a grammar method, and some
	new data as its right argument. It then updates i
*/

const joinTest = function (acc, right) {

	if (isGlobalThis(acc)) {
		var acc = Object.create(_forallProto)
	}

	const override = function (key) {
		return function () {

			acc[key] = right[key]
			return acc

		}
	}

	const join = function (key) {
		return function () {

			if (acc[key]) {
				acc[key] = acc[key].concat( [right[key]] )
			} else {
				acc[key] = [right[key]]
			}

			return acc
		}
	}

	const responses = {
		describe : join('info'),
		over     : override('params'),
		when     : join('whenProperty'),
		run      : function () {

			acc.time = right.time

			executeTest(acc)
		}
	}

	for (type in responses) {

		if (right.type === type) {
			return responses[type]()
		}
	}

}

over_('a', 'b') .

describe('addition is commutative') .
when_(
	function (a, b) {
		return typeof a === 'number' && a === a &&
		typeof b === 'number' && b === b
	},
	function (a, b) {
		return a + b === b + a + 1
	}
) .

run(1)
<commit_msg>colourised messages.<commit_after>
/*
	jCheck is a quick and dumn property testing framework for JavaScript / Node.

*/

/*
	Helper Functions.

*/

/*
	Remove the first element from an array.

	@param {[any]}
*/

const restOf = function (coll) {

	var out = []

	for (var ith = 0; ith < coll.length; ith++) {
		if (ith !== 0) {
			out = out.concat( coll[ith] )
		}
	}

	return out
}

/*
	Get the unique values in a collection.
*/

const uniqueOf = function (coll) {

	var set = []

	for (var ith = 0; ith < coll.length; ith++) {

		var elem     = coll[ith]
		var hasMatch = false

		for (var jth = 0; jth < set.length; jth++) {
			if (elem === set[jth]) {
				hasMatch = true
			}
		}

		if (!hasMatch) {
			set.push(elem)
		}
	}

	return set
}

/*
	Get the indices of a collection.
*/

const indicesOf = function (coll) {

	var indices = []

	for (var ith = 0; ith < coll.length; ith++) {
		indices[ith] = ith
	}

	return indices

}

/*
	takes a number of seconds, and
	returns a function that returns true if
	called within that timespan after creation.

*/

const stopwatch = function (num) {

	const posixTime = function () {

		return Math.round((new Date).getTime() / 1000.0)
	}

	const genesis = posixTime()

	return function () {

		const lifespan  = posixTime() - genesis
		return lifespan < num

	}
}

const rightPad = function (str, num) {
	return str.length < num? str + Array(num - str.length).join(' '): str
}

const colourise = ( function () {

	const supportColour = function () {
		return true
	}

	const colouriser = function (code) {
		return function (message) {
			return supportColour()? "\033[" + code + message + "\033[0m": message
		}
	}

	return {
		black  : colouriser("0;30m"),
		blue   : colouriser("0;34m"),
		green  : colouriser("0;32m"),
		red    : colouriser("0;31m"),
		yellow : colouriser("1;33m")
	}

} )()

const fromStream = ( function () {

	var self = {}

	/*
		-------------------------------- Generators --------------------------------

	*/

	// -------------------------------- numeric --------------------------------

	self.number = function (len) {
		// uniform random number of a given order 'len'.

		const  sign = Math.random() > 0.5? +1: -1
		return sign * Math.random() * Math.pow(10, len)
	}
	self.integer = function (len) {
		// uniform random integer of a given order 'len'.

		return Math.round(self.number(len))
	}

	self.nan    = function (len) {
		return NaN
	}

	// -------------------------------- character --------------------------------

	self.alphabetical = (function () {
		// uppercase and lowecase letters in a string of length 'len'.

		const charset =
			'abcdefghijklmnopqrstuvwxyz' +
			'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

		return function (len) {

			var out = ''

			for (var ith = 0; ith < len; ith++) {
				out += charset.charAt(Math.random * charset.length)
			}

			return out
		}

	})()

	/*
		-------------------------------- Sampler --------------------------------

	*/

	return function (len) {
		// return a random generator.

		const generators = Object.keys(self)
		const ith        = generators[Math.floor(Math.random() * generators.length)]

		return self[ith](len)
	}

} )()

/*
	The core testing function.
*/

const runTest = function (tester, groups, state, testcase, info) {

	for (var groupIth = 0; groupIth < groups.length; groupIth++) {

		var group = groups[groupIth]

		var groupPred  = group[0]
		var groupProps = restOf(groups)

		var isMatch = groupPred.apply(null, testcase)

		state.casesExamined += 1

		if (!isMatch) {
			continue
		}

		state.testsRun += 1

		/*
			the predicate for this group was true; test each associated
			property.
		*/

		for (var propIth = 0; propIth < groupProps.length; propIth++) {

			var prop    = groupProps[propIth]
			var hasProp = tester(prop, testcase)

			// the result of the predicate was non-boolean.
			if (hasProp !== true && hasProp !== false) {
				var message =
					info + '\n' +
					colourise.red('Failed!') +
					' the property returned a non-logical result\n' +
					'For the test-case '

				throw message
			}

			if (!hasProp) {

				// note the earliest fail.
				state.failsAfter =
					Math.min(state.failsAfter, state.testsRun)

				// store the failed cases.
				state.failsFor =
					state.failsFor.concat([testcase])

				// store the index of the failed properties.

				var failedIndex = {
					group    : groupIth,
					property : propIth,
					summary  : groupIth + ', ' + propIth
				}

				state.failedIndices =
					[state.failedIndices, [failedIndex]]

			}
		}

	}

	return state
}

/*
	Generate bindings for each random variable.

	@param {[string]} strs. The parametres to be bound to a random value.
	@param {number} num. The length or order of the random value to be
	    generated.
*/

const yieldCase = function (strs, num) {

	return strs.map(function (param) {
		return fromStream(num)
	})

}

/*

*/

const propertyError = function (properties, testData, state) {

	const after    = state.failsAfter
	const failsFor = state.failsFor
	const indices  = state.failedIndices

	// whichFailed, descriptions are co-ordered

	const whichFailed  = uniqueOf(indices)

	const expressions  = whichFailed.map( function (triple) {

		const ith = triple.group
		const jth = triple.property + 1

	})

	const descriptions = whichFailed.map( function (triple) {
		testData.info[triple.group]
	})

	const paragraphs = 1

	const message = 'failed! After ' + after + ' cases'

	throw message
}

/*
	warn that no test-cases were given to some property group.
*/

const exhaustionWarning = function (testData, state, info) {

	const run      = state.testsRun
	const examined = state.casesExamined

	const message =
		info + colourise.yellow(" Failed!\n") +
		"all " + examined + " test cases were rejected."

	console.warn(message)
}

/*

*/

const successMessage = function (states, info) {
	/*

	*/

	/*
		for each state object get the number of
		tests of that type run, convert to .csv
	*/

	const testsRun =
		states
		.map(function (state) {
			return state.testsRun
		})
		.reduce(function (acc, val) {
			return acc + ', ' + val
		})

	const message =
		rightPad("'"+ info + "'" + ' passed! ', 80)  + "(" + colourise.blue(testsRun) + ")"

	console.log(message)
}

/*

*/

const whenTest = function (prop, testcase) {
	// simply call the predicate with the testcase.

	return prop.apply(null, testcase)
}

/*
	ensure that the test being passed to run
	can be executed properly.
*/
const validateTest = function (test) {

	// throw an error if any fields are missing.
	;['info', 'params', 'time'].forEach(function (key) {

		if (!test.hasOwnProperty(key)) {
			var message =
				"the property '" + key + "' was missing from the test object."

			throw colourise.red(message)
		}
	})

	// time mustn't be NaN
	if (test.time !== test.time) {

		var message =
			'time must not be NaN.'

		throw colourise.red(message)
	}

	// time definitely mustn't be Infinite
	if (!isFinite(test.time)) {

		var message =
			'time must not be infinite.'

		throw colourise.red(message)
	}

	// time must be positive
	if (test.time < 0) {
		var message =
			'time must be positive.'

		throw colourise.red(message)
	}

	return true
}

/*
	The backend wrapper in which the test is executed.
*/

const executeTest = function (test) {

	validateTest(test)

	// attach the test data to the local environment.

	const info         = test.info
	const params       = test.params
	const time         = test.time
	const whenProperty = test.whenProperty

	const initialState = function () {
		return {
			casesExamined : 0,
			testsRun      : 0,
			failsFor      : [],
			failsAfter    : Infinity,
			failedIndices : []
		}
	}

	// each test subtype has its own state, tester and property group.

	var states       = [initialState()]
	const groupTypes = [whenProperty]
	const testers    = [whenTest]

	var timeLeft = stopwatch(time)

	/*
		execute the tests and collect statistics on the failures.
	*/

	const len = 10

	while (timeLeft()) {

		var testcase = yieldCase(params, len)

		for (var ith = 0; ith < states.length; ith++) {

			var test  = testers[ith]
			var group = groupTypes[ith]
			var state = states[ith]

			runTest(test, group, state, testcase, info)
		}

	}

	// additional data needed to report success or failure.

	const testData = {
		info: info,
		time: time
	}

	/*
		Check that the correct number of tests were run, and
		that none of the tests fail.
	*/

	for (var ith = 0; ith < states.length; ith++) {

		var group = groupTypes[ith]
		var state = states[ith]

		if (group.length > 0 && state.testsRun === 0) {
			/*
				No tests were run for a particular test group.
				Warn the user about this fact.
			*/
			exhaustionWarning(testData, state, info)
		}

		if (state.failsFor.length > 0) {
			/*
				Throw errors for this particular group.
			*/

			propertyError(group, testData, state)
		}

	}

	successMessage(states, info)
}

/*
	-------------------------------- Grammar --------------------------------

	describe(string)            add a description to a property group. Concatanative property.

	over([string])              the parametres to bind random variables to.
	                            Overriding property.

	over_(string_)              the parametres to bind random variables to.
	                            Overriding property.

	when(Function, [Function])  when a predicate is true, assert that several other
	                            predicates are also true. Concatanative property.

	when_(Function_)            when a predicate is true, assert that several other
	                            predicates are also true. Concatanative property.

	run(number)                 triggers the start of a test, specifies how long the test runs for.
*/

const describe = function (info) {

	var self  = joinTest(this, {
		info : info,
		type : 'describe'
	})

	return self
}

/*
	Bind random variables to test over.

	@param {[string]} strs. An array of strings.
*/

const over = function (strs) {

	var self  = joinTest(this, {
		params 	: strs,
		type   	: 'over'
	})

	return self
}

/*

*/

const over_ = function () {

	const args = Array.prototype.slice.call(arguments)

	var self  = joinTest(this, {
		params 	: args,
		type   	: 'over'
	})

	return self
}

/*
	When a predicate is true of a test-case, ensure several other predicates are true too.

	@param {Function}   pred:  a predicate function. This function tests if a test-case
	    is suitable to be given to a set of properties.

	@param {[Function]} preds: an array of predicate functions. These functions are
	    properties that must hold true for an test-case that matches `pred`.

	@return {object}
*/

const when = function (pred, preds) {

	var self  = joinTest(this, {
		whenProperty : [pred].concat(preds),
		type         : 'when'
	})

	return self
}

/*

*/

const when_ = function () {

	const args = Array.prototype.slice.call(arguments)

	var self  = joinTest(this, {
		whenProperty : args,
		type         : 'when'
	})

	return self
}

/*
	Run a test.

	@param {number} num. The number of seconds testing should continue for.
*/

const run = function (num) {

	var self  = joinTest(this, {
		time : num,
		type : 'run'
	})

	return self
}

const _forallProto = {
	run      : run,

	over     : over,
	over_    : over_,

	when     : when,
	when_    : when_,

	describe : describe
}

/*
	Test if an object is the global 'this' object.
*/

const isGlobalThis = function (obj) {
	return obj.GLOBAL || obj.window
}

/*
	JoinTest

	JoinTest takes the 'this' passed to a grammar method, and some
	new data as its right argument. It then updates i
*/

const joinTest = function (acc, right) {

	if (isGlobalThis(acc)) {
		var acc = Object.create(_forallProto)
	}

	const override = function (key) {
		return function () {

			acc[key] = right[key]
			return acc

		}
	}

	const join = function (key) {
		return function () {

			if (acc[key]) {
				acc[key] = acc[key].concat( [right[key]] )
			} else {
				acc[key] = [right[key]]
			}

			return acc
		}
	}

	const responses = {
		describe : join('info'),
		over     : override('params'),
		when     : join('whenProperty'),
		run      : function () {

			acc.time = right.time

			executeTest(acc)
		}
	}

	for (type in responses) {

		if (right.type === type) {
			return responses[type]()
		}
	}

}

over_('a', 'b') .

describe('addition is commutative') .
when_(
	function (a, b) {
		return typeof a === 'number' && a === a &&
		typeof b === 'number' && b === b
	},
	function (a, b) {
		return a + b === b + a + 1
	}
) .

run(1)
<|endoftext|>


<commit_before>const { PromptNode } = require('discord.js-prompts')
const commonPrompts = require('./prompts/common/index.js')
const Article = require('../structs/Article.js')
const FeedFetcher = require('../util/FeedFetcher.js')
const ArticleTestMessage = require('../structs/ArticleTestMessage.js')
const Translator = require('../structs/Translator.js')
const Profile = require('../structs/db/Profile.js')
const FailRecord = require('../structs/db/FailRecord.js')
const FeedData = require('../structs/FeedData.js')
const runWithFeedGuild = require('./prompts/runner/run.js')

module.exports = async (message, command) => {
  const simple = message.content.endsWith('simple')
  const profile = await Profile.get(message.guild.id)
  const translate = Translator.createProfileTranslator(profile)
  const selectFeedNode = new PromptNode(commonPrompts.selectFeed.prompt)
  const data = await runWithFeedGuild(selectFeedNode, message)
  const { selectedFeed: feed } = data
  if (!feed) {
    return
  }
  if (await FailRecord.hasFailed(feed.url)) {
    return message.channel.send(translate('commands.test.failed'))
  }
  const grabMsg = await message.channel.send(translate('commands.test.grabbingRandom'))
  const article = await FeedFetcher.fetchRandomArticle(feed.url)
  if (!article) {
    return message.channel.send(translate('commands.test.noArticles'))
  }
  const feedData = await FeedData.ofFeed(feed)

  if (!simple) {
    const parsedArticle = new Article(article, feedData)
    const testText = parsedArticle.createTestText()
    await message.channel.send(testText, {
      split: {
        prepend: '```md\n',
        append: '```'
      }
    })
  }

  const articleMessage = new ArticleTestMessage(message.client, article, feedData)
  articleMessage.feed.channel = message.channel.id

  await articleMessage.send()
  await grabMsg.delete()
}
<commit_msg>Fix prefix not converted in string<commit_after>const { PromptNode } = require('discord.js-prompts')
const commonPrompts = require('./prompts/common/index.js')
const Article = require('../structs/Article.js')
const FeedFetcher = require('../util/FeedFetcher.js')
const ArticleTestMessage = require('../structs/ArticleTestMessage.js')
const Translator = require('../structs/Translator.js')
const Profile = require('../structs/db/Profile.js')
const FailRecord = require('../structs/db/FailRecord.js')
const FeedData = require('../structs/FeedData.js')
const runWithFeedGuild = require('./prompts/runner/run.js')
const getConfig = require('../config.js').get

module.exports = async (message, command) => {
  const simple = message.content.endsWith('simple')
  const profile = await Profile.get(message.guild.id)
  const translate = Translator.createProfileTranslator(profile)
  const selectFeedNode = new PromptNode(commonPrompts.selectFeed.prompt)
  const data = await runWithFeedGuild(selectFeedNode, message)
  const { selectedFeed: feed } = data
  if (!feed) {
    return
  }
  const config = getConfig()
  const prefix = profile && profile.prefix ? profile.prefix : config.bot.prefix
  if (await FailRecord.hasFailed(feed.url)) {
    return message.channel.send(translate('commands.test.failed'), {
      prefix
    })
  }
  const grabMsg = await message.channel.send(translate('commands.test.grabbingRandom'))
  const article = await FeedFetcher.fetchRandomArticle(feed.url)
  if (!article) {
    return message.channel.send(translate('commands.test.noArticles'))
  }
  const feedData = await FeedData.ofFeed(feed)

  if (!simple) {
    const parsedArticle = new Article(article, feedData)
    const testText = parsedArticle.createTestText()
    await message.channel.send(testText, {
      split: {
        prepend: '```md\n',
        append: '```'
      }
    })
  }

  const articleMessage = new ArticleTestMessage(message.client, article, feedData)
  articleMessage.feed.channel = message.channel.id

  await articleMessage.send()
  await grabMsg.delete()
}
<|endoftext|>


<commit_before>var ThreeDDrawing = AbstractDrawing.extend(function(base) {
    return {
        init: function(scene, originX, originY, originZ) {
            base.init.call(this, scene);

            this.originX = originX;
            this.originY = originY;
            this.originZ = originZ;

            this.particleSystem = null;
            this.proximalLines = null;
        },

        setLayerDimensions: function(layerDimensions, reshape) {
            if (layerDimensions.length > 3) {
                throw new Error("ThreeDVisualization only supports up to 3-dimensional layers");
            }

            while (layerDimensions.length < 3) {
                layerDimensions.push(1);
            }

            if (reshape) {
                layerDimensions = this.reshape3Dimensions(layerDimensions);
            }

            base.setLayerDimensions.call(this, layerDimensions);
        },

        /* Public */

        setup: function() {
            var paddingX = 100,
                paddingY = 100,
                paddingZ = 25,
                dimensions = this.layerDimensions;

            if (dimensions.length != 3) {
                throw new Error("ThreeDVisualization only supports 3-dimensional layers");
            }

            var numX = dimensions[0],
                numY = dimensions[1],
                numZ = dimensions[2],
                originX = this.originX + (-(numX * paddingX) / 2),
                originY = this.originY + (-(numY * paddingY) / 2),
                originZ = this.originZ + (-(numZ * paddingZ) / 2);

            var particles = new THREE.Geometry(),
                material = new THREE.ParticleBasicMaterial({
                    size: 20,
                    map: THREE.ImageUtils.loadTexture(
                        "img/particle.png"
                    ),
                    blending: THREE.NormalBlending,
                    transparent: true,
                    vertexColors: true
                }),
                particleSystem = new THREE.ParticleSystem(particles, material);

            particleSystem.sortParticles = true;

            for (var x = 0; x < numX; x++) {
                for (var y = 0; y < numY; y++) {
                    for (var z = 0; z < numZ; z++) {
                        var pX = originX + x * paddingX,
                            pY = originY + y * paddingY,
                            pZ = originZ + z * paddingZ,
                            particle = new THREE.Vector3(pX, pY, pZ);

                        particles.vertices.push(particle);
                        particles.colors.push(new THREE.Color(0xAAAAAA));
                    }
                }
            }

            this.scene.add(particleSystem);

            this.particleSystem = particleSystem;
        },

        clear: function() {
            if (!this.particleSystem) return;

            this.scene.remove(this.particleSystem);
        },

        updateCells: function() {
            if (!this.particleSystem) return;

            var dimensions = this.layerDimensions,
                numZ = dimensions[2],
                particles = this.particleSystem.geometry,
                activeColumns = this.activeColumns,
                activeCells = this.activeCells,
                predictedCells = this.predictedCells,
                showActiveColumns = this.showActiveColumns,
                showActiveCells = this.showActiveCells,
                showPredictedCells = this.showPredictedCells;

            var activeColumnsCache = {},
                activeCellsCache = {},
                predictedCellsCache = {};

            for (var i = 0; i < particles.vertices.length; i++) {
                var column = Math.floor(i / numZ),
                    color = 0x222222;

                if (showActiveColumns && _.fastContains(activeColumns, column, activeColumnsCache)) {
                    color = 0xFFFFFF;
                }

                if (showPredictedCells && _.fastContains(predictedCells, i, predictedCellsCache)) {
                    color = 0xAA0000;
                }

                if (showActiveCells && _.fastContains(activeCells, i, activeCellsCache)) {
                    color = 0x006400;
                }

                particles.colors[i].setHex(color);
            }
        },

        updateProximalSynapses: function() {
            if (!this.particleSystem) return;

            var inputDrawing = this.inputDrawing,
                particles = this.particleSystem.geometry.vertices,
                inputParticles = inputDrawing.getParticles(),
                proximalSynapses = this.proximalSynapses,
                showProximalSynapses = this.showProximalSynapses;

            if (this.proximalLines) this.scene.remove(this.proximalLines);

            if (showProximalSynapses && inputDrawing) {
                var geometry = new THREE.Geometry(),
                    material = new THREE.LineBasicMaterial({vertexColors: THREE.VertexColors});

                for (var i = 0; i < proximalSynapses.length; i++) {
                    var synapse = proximalSynapses[i],
                        toIndex = synapse[0],
                        fromIndex = synapse[1],
                        permanence = synapse[2],
                        toParticle = particles[toIndex],
                        fromParticle = inputParticles[fromIndex],
                        toColor = new THREE.Color(0x0000FF).multiplyScalar(permanence),
                        fromColor = new THREE.Color(0xFF0000).multiplyScalar(permanence);

                    geometry.vertices.push(toParticle);
                    geometry.vertices.push(fromParticle);

                    geometry.colors.push(toColor);
                    geometry.colors.push(fromColor);
                }

                var line = new THREE.Line(geometry, material, THREE.LinePieces);

                this.scene.add(line);

                this.proximalLines = line;
            }
        },

        getParticles: function() {
            return this.particleSystem.geometry.vertices;
        }
    };
});
<commit_msg>Addresses chetan51/nupic.cerebro2#3. Adjusted colors and particle size.<commit_after>var ThreeDDrawing = AbstractDrawing.extend(function(base) {
    return {
        init: function(scene, originX, originY, originZ) {
            base.init.call(this, scene);

            this.originX = originX;
            this.originY = originY;
            this.originZ = originZ;

            this.particleSystem = null;
            this.proximalLines = null;
        },

        setLayerDimensions: function(layerDimensions, reshape) {
            if (layerDimensions.length > 3) {
                throw new Error("ThreeDVisualization only supports up to 3-dimensional layers");
            }

            while (layerDimensions.length < 3) {
                layerDimensions.push(1);
            }

            if (reshape) {
                layerDimensions = this.reshape3Dimensions(layerDimensions);
            }

            base.setLayerDimensions.call(this, layerDimensions);
        },

        /* Public */

        setup: function() {
            var paddingX = 100,
                paddingY = 100,
                paddingZ = 25,
                dimensions = this.layerDimensions;

            if (dimensions.length != 3) {
                throw new Error("ThreeDVisualization only supports 3-dimensional layers");
            }

            var numX = dimensions[0],
                numY = dimensions[1],
                numZ = dimensions[2],
                originX = this.originX + (-(numX * paddingX) / 2),
                originY = this.originY + (-(numY * paddingY) / 2),
                originZ = this.originZ + (-(numZ * paddingZ) / 2);

            var particles = new THREE.Geometry(),
                material = new THREE.ParticleBasicMaterial({
                    size: 80,
                    map: THREE.ImageUtils.loadTexture(
                        "img/particle.png"
                    ),
                    blending: THREE.NormalBlending,
                    transparent: true,
                    vertexColors: true
                }),
                particleSystem = new THREE.ParticleSystem(particles, material);

            particleSystem.sortParticles = true;

            for (var x = 0; x < numX; x++) {
                for (var y = 0; y < numY; y++) {
                    for (var z = 0; z < numZ; z++) {
                        var pX = originX + x * paddingX,
                            pY = originY + y * paddingY,
                            pZ = originZ + z * paddingZ,
                            particle = new THREE.Vector3(pX, pY, pZ);

                        particles.vertices.push(particle);
                        particles.colors.push(new THREE.Color(0xAAAAAA));
                    }
                }
            }

            this.scene.add(particleSystem);

            this.particleSystem = particleSystem;
        },

        clear: function() {
            if (!this.particleSystem) return;

            this.scene.remove(this.particleSystem);
        },

        updateCells: function() {
            if (!this.particleSystem) return;

            var dimensions = this.layerDimensions,
                numZ = dimensions[2],
                particles = this.particleSystem.geometry,
                activeColumns = this.activeColumns,
                activeCells = this.activeCells,
                predictedCells = this.predictedCells,
                showActiveColumns = this.showActiveColumns,
                showActiveCells = this.showActiveCells,
                showPredictedCells = this.showPredictedCells;

            var activeColumnsCache = {},
                activeCellsCache = {},
                predictedCellsCache = {};

            for (var i = 0; i < particles.vertices.length; i++) {
                var column = Math.floor(i / numZ),
                    color = 0x222222;

                if (showActiveColumns && _.fastContains(activeColumns, column, activeColumnsCache)) {
                    color = 0xFFFFFF;
                }

                if (showPredictedCells && _.fastContains(predictedCells, i, predictedCellsCache)) {
                    color = 0xAA0000;
                }

                if (showActiveCells && _.fastContains(activeCells, i, activeCellsCache)) {
                    color = 0x73c12d;
                }

                particles.colors[i].setHex(color);
            }
        },

        updateProximalSynapses: function() {
            if (!this.particleSystem) return;

            var inputDrawing = this.inputDrawing,
                particles = this.particleSystem.geometry.vertices,
                inputParticles = inputDrawing.getParticles(),
                proximalSynapses = this.proximalSynapses,
                showProximalSynapses = this.showProximalSynapses;

            if (this.proximalLines) this.scene.remove(this.proximalLines);

            if (showProximalSynapses && inputDrawing) {
                var geometry = new THREE.Geometry(),
                    material = new THREE.LineBasicMaterial({vertexColors: THREE.VertexColors});

                for (var i = 0; i < proximalSynapses.length; i++) {
                    var synapse = proximalSynapses[i],
                        toIndex = synapse[0],
                        fromIndex = synapse[1],
                        permanence = synapse[2],
                        toParticle = particles[toIndex],
                        fromParticle = inputParticles[fromIndex],
                        toColor = new THREE.Color(0x666666).multiplyScalar(permanence),
                        fromColor = new THREE.Color(0x528a20).multiplyScalar(permanence);

                    geometry.vertices.push(toParticle);
                    geometry.vertices.push(fromParticle);

                    geometry.colors.push(toColor);
                    geometry.colors.push(fromColor);
                }

                var line = new THREE.Line(geometry, material, THREE.LinePieces);

                this.scene.add(line);

                this.proximalLines = line;
            }
        },

        getParticles: function() {
            return this.particleSystem.geometry.vertices;
        }
    };
});
<|endoftext|>


<commit_before>/**
 * @author  Hamza Waqas <hamzawaqas@live.com>
 * @since   1/14/14
 */

(function() {

    var _ = require('lodash');

    var Main = function(appId, appSecret, callback, state) {
        var _services = ['connections', 'companies', 'companies_search', 'people', 'group']
            , Inherits = require('./inherits')
            , self = this;

        // Make some configuration;
        this.options = {
            api_url: "https://api.linkedin.com/v1/",
            format: 'json'
        };

        this.auth = require('./auth')(Inherits, {
            appId: appId,
            appSecret: appSecret,
            callback: callback,
            state: state
        });
        this.init = function(accessToken, options) {
            if (typeof accessToken === 'string') {
                this.options.accessToken = {
                    token: accessToken,
                    version: 2
                };
            } else {
                this.options.accessToken = accessToken;
            }

            options = options || {};
            this.options.timeout = options.timeout;

            _.forEach(_services, function(service) {
                /**
                 * @exports service
                 * @type {*}
                 */
                module.exports[service] = require(__dirname + '/services/' + service)(Inherits, self.options);
            });
            return module.exports;
        }

        return this;
    }.bind(this);

    module.exports = Main;
}).call(this);
<commit_msg>Added setCallback functino<commit_after>/**
 * @author  Hamza Waqas <hamzawaqas@live.com>
 * @since   1/14/14
 */

(function() {

    var _ = require('lodash');

    var Main = function(appId, appSecret, callback, state) {
        var _services = ['connections', 'companies', 'companies_search', 'people', 'group']
            , Inherits = require('./inherits')
            , self = this;

        // Make some configuration;
        this.options = {
            api_url: "https://api.linkedin.com/v1/",
            format: 'json'
        };

        this.auth = require('./auth')(Inherits, {
            appId: appId,
            appSecret: appSecret,
            callback: callback,
            state: state
        });
        this.init = function(accessToken, options) {
            if (typeof accessToken === 'string') {
                this.options.accessToken = {
                    token: accessToken,
                    version: 2
                };
            } else {
                this.options.accessToken = accessToken;
            }

            options = options || {};
            this.options.timeout = options.timeout;

            _.forEach(_services, function(service) {
                /**
                 * @exports service
                 * @type {*}
                 */
                module.exports[service] = require(__dirname + '/services/' + service)(Inherits, self.options);
            });
            return module.exports;
        };

        /*
         *  Set Callback
         *
         *  @param {String} 'url' to be set
         *
         * */
        this.setCallback = function(cb){
          return callback = cb || callback;
        };

        return this;
    }.bind(this);

    module.exports = Main;
}).call(this);
<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import Button from 'react-mdl/lib/Button';
import _ from 'lodash';

import ProfileTab from "../util/ProfileTab";
import { generateNewEducation } from "../util/util";
import {
  toggleEducationLevel,
  openEducationForm,
  closeEducationForm,
  clearProfileEdit
} from '../actions';
import Grid, { Cell } from 'react-mdl/lib/Grid';
import Switch from 'react-mdl/lib/Switch';
import FABButton from 'react-mdl/lib/FABButton';
import Icon from 'react-mdl/lib/Icon';
import Dialog from 'material-ui/Dialog';

class EducationTab extends ProfileTab {
  constructor(props) {
    super(props);
    this.educationLevelLabels = {};
    this.educationLevelOptions.forEach(level => {
      this.educationLevelLabels[level.value] = level.label;
    });
    this.openNewEducationForm = this.openNewEducationForm.bind(this);
    this.handleCloseDialog = this.handleCloseDialog.bind(this);
  }
  nextUrl = "/profile/professional";

  static propTypes = {
    educationLevels: React.PropTypes.object,
    educationDialog: React.PropTypes.object,
    profile: React.PropTypes.object,
    saveProfile: React.PropTypes.func,
    updateProfile: React.PropTypes.func,
    errors: React.PropTypes.object,
    dispatch: React.PropTypes.func.isRequired
  };

  static defaultProps = {
    requiredFields: [],
    validationMessages: {
      'degree_name': 'Degree level',
      'graduation_date': 'Graduation Date',
      'field_of_study': 'Field of study',
      'online_degree': 'Online Degree',
      'school_name': 'School name',
      'school_city': 'City',
      'school_state_or_territory': 'State',
      'school_country': 'Country'
    }
  };

  static nestedValidationKeys = [
    'degree_name',
    'graduation_date',
    'field_of_study',
    'online_degree',
    'school_name',
    'school_city',
    'school_state_or_territory',
    'school_country'
  ];

  static validation(profile, requiredFields) {
    let nestedFields = (index) => {
      let keySet = (key) => ['education', index, key];
      return EducationTab.nestedValidationKeys.map(key => keySet(key));
    };
    return requiredFields.concat(
      ...profile.education.map((v, i) => nestedFields(i))
    );
  }

  openNewEducationForm(level, index) {
    const {dispatch, profile, updateProfile} = this.props;
    let newIndex = index;
    if (index === null){
      newIndex = profile['education'].length;
    }
    /* add empty education */
    let clone = Object.assign({}, profile);
    clone['education'] = clone['education'].concat(generateNewEducation(level));
    updateProfile(clone);
    dispatch(openEducationForm(level, newIndex));
  }

  printAddDegree(level){
    const { educationLevels } = this.props;
    if (educationLevels[level.value]){
      return <Grid key={"add-"+level.value}>
        <Cell col={11}></Cell>
        <Cell col={1}>
          <FABButton mini onClick={this.openNewEducationForm.bind(this, level.value, null )} raised ripple>
            <Icon name="add" />
          </FABButton>
        </Cell>
      </Grid>;
    }
    return null;
  }

  printExistingEducations(level) {
    const {profile} = this.props;
    return profile['education'].map(education => {
      if (education.degree_name === level.value && 'id' in education) {
        return <Grid key={"education-row-" + education.id} className="existing-education-grid">
          <Cell col={3}>{this.educationLevelLabels[education.degree_name]}</Cell>
          <Cell col={7}>{education.graduation_date}</Cell>
          <Cell col={1}>
            <Button onClick={this.openEditEducationForm.bind(this, education.degree_name, education.id)}>
              <Icon name="edit"/>
            </Button>
          </Cell>
          <Cell col={1}>
            <Button ><Icon name="delete"/></Button>
          </Cell>
        </Grid>;
      }
    });
  }

  openEditEducationForm(level, educationId){
    const { dispatch, profile } = this.props;

    let index = profile['education'].findIndex((education) => {
      return educationId === education.id;
    });
    dispatch(openEducationForm(level, index));
  }

  saveEducationForm(nestedValidationCallback){
    const { dispatch, saveProfile, profile, requiredFields, validationMessages } = this.props;
    let fields;
    if (_.isFunction(nestedValidationCallback)) {
      fields = nestedValidationCallback(profile, requiredFields);
    } else {
      fields = requiredFields;
    }
    saveProfile(profile, fields, validationMessages ).then(() => {
      dispatch(closeEducationForm());
    });
  }

  handleSwitchClick(level){
    const {dispatch, educationLevels} = this.props;
    let newState = Object.assign({}, educationLevels);
    newState[level] = !educationLevels[level];
    dispatch(toggleEducationLevel(newState));
  }

  handleCloseDialog(){
    const { dispatch } = this.props;
    dispatch(closeEducationForm());
    dispatch(clearProfileEdit());
  }

  render() {
    let { profile, educationDialog, educationLevels} = this.props;

    if (profile['education'] === undefined){
      return null;
    }

    let levelsGrid = this.educationLevelOptions.map(level =>{
      return <Cell col={12} key={level.value} >
        <Grid key={level.value} className="education-level-header">
          <Cell col={11}>
{level.label}
</Cell>
          <Cell col={1}>
            <Switch ripple onChange={()=>{this.handleSwitchClick(level.value);}}
              checked={educationLevels[level.value]}/>
          </Cell>
        </Grid>
        { this.printAddDegree(level)}
        { this.printExistingEducations(level)}
      </Cell>;
    });

    let keySet = (key) =>['education', educationDialog.educationIndex, key];

    let actions = [
      <Button key="save" type='button' onClick={()=>{this.saveEducationForm(EducationTab.validation);}}>Save</Button>,
      <Button key="cancel" type='button' onClick={this.handleCloseDialog}>Cancel</Button>
    ];

    return <Grid className="profile-tab-grid">
      <Dialog
        open={educationDialog.openDialog}
        className="profile-form-dialog"
        onRequestClose={this.handleCloseDialog}
        title={this.educationLevelLabels[educationDialog.degreeLevel]}
        actions={actions}
      >
        <Grid>
          <Cell col={6}>
            {this.boundTextField(keySet('field_of_study'), 'Field of Study')}
          </Cell>
          <Cell col={6}>
            {this.boundMonthYearField(keySet('graduation_date'), 'Graduation Date')}
          </Cell>
        </Grid>
        <Grid>
          <Cell col={6}>
            {this.boundTextField(keySet('school_name'), 'School Name')}
          </Cell>
          <Cell col={6}>
          </Cell>
        </Grid>
        <Grid>
          <Cell col={4}>
            {this.boundSelectField(keySet('school_country'), 'Country', this.countryOptions)}
          </Cell>
          <Cell col={4}>
            {this.boundTextField(keySet('school_state_or_territory'), 'State')}
          </Cell>
          <Cell col={4}>
            {this.boundTextField(keySet('school_city'), 'City')}
          </Cell>
        </Grid>
      </Dialog>

      {levelsGrid}

     <Button raised onClick={this.saveAndContinue}>
        Save and continue
     </Button>
    </Grid>;
  }
}

const mapStateToProps = state => ({
  educationDialog: state.educationDialog,
  educationLevels: state.educationLevels
});

export default connect(mapStateToProps)(EducationTab);
<commit_msg>Used state select field for education tab<commit_after>import React from 'react';
import { connect } from 'react-redux';
import Button from 'react-mdl/lib/Button';
import _ from 'lodash';

import ProfileTab from "../util/ProfileTab";
import { generateNewEducation } from "../util/util";
import {
  toggleEducationLevel,
  openEducationForm,
  closeEducationForm,
  clearProfileEdit
} from '../actions';
import Grid, { Cell } from 'react-mdl/lib/Grid';
import Switch from 'react-mdl/lib/Switch';
import FABButton from 'react-mdl/lib/FABButton';
import Icon from 'react-mdl/lib/Icon';
import Dialog from 'material-ui/Dialog';

class EducationTab extends ProfileTab {
  constructor(props) {
    super(props);
    this.educationLevelLabels = {};
    this.educationLevelOptions.forEach(level => {
      this.educationLevelLabels[level.value] = level.label;
    });
    this.openNewEducationForm = this.openNewEducationForm.bind(this);
    this.handleCloseDialog = this.handleCloseDialog.bind(this);
  }
  nextUrl = "/profile/professional";

  static propTypes = {
    educationLevels: React.PropTypes.object,
    educationDialog: React.PropTypes.object,
    profile: React.PropTypes.object,
    saveProfile: React.PropTypes.func,
    updateProfile: React.PropTypes.func,
    errors: React.PropTypes.object,
    dispatch: React.PropTypes.func.isRequired
  };

  static defaultProps = {
    requiredFields: [],
    validationMessages: {
      'degree_name': 'Degree level',
      'graduation_date': 'Graduation Date',
      'field_of_study': 'Field of study',
      'online_degree': 'Online Degree',
      'school_name': 'School name',
      'school_city': 'City',
      'school_state_or_territory': 'State',
      'school_country': 'Country'
    }
  };

  static nestedValidationKeys = [
    'degree_name',
    'graduation_date',
    'field_of_study',
    'online_degree',
    'school_name',
    'school_city',
    'school_state_or_territory',
    'school_country'
  ];

  static validation(profile, requiredFields) {
    let nestedFields = (index) => {
      let keySet = (key) => ['education', index, key];
      return EducationTab.nestedValidationKeys.map(key => keySet(key));
    };
    return requiredFields.concat(
      ...profile.education.map((v, i) => nestedFields(i))
    );
  }

  openNewEducationForm(level, index) {
    const {dispatch, profile, updateProfile} = this.props;
    let newIndex = index;
    if (index === null){
      newIndex = profile['education'].length;
    }
    /* add empty education */
    let clone = Object.assign({}, profile);
    clone['education'] = clone['education'].concat(generateNewEducation(level));
    updateProfile(clone);
    dispatch(openEducationForm(level, newIndex));
  }

  printAddDegree(level){
    const { educationLevels } = this.props;
    if (educationLevels[level.value]){
      return <Grid key={"add-"+level.value}>
        <Cell col={11}></Cell>
        <Cell col={1}>
          <FABButton mini onClick={this.openNewEducationForm.bind(this, level.value, null )} raised ripple>
            <Icon name="add" />
          </FABButton>
        </Cell>
      </Grid>;
    }
    return null;
  }

  printExistingEducations(level) {
    const {profile} = this.props;
    return profile['education'].map(education => {
      if (education.degree_name === level.value && 'id' in education) {
        return <Grid key={"education-row-" + education.id} className="existing-education-grid">
          <Cell col={3}>{this.educationLevelLabels[education.degree_name]}</Cell>
          <Cell col={7}>{education.graduation_date}</Cell>
          <Cell col={1}>
            <Button onClick={this.openEditEducationForm.bind(this, education.degree_name, education.id)}>
              <Icon name="edit"/>
            </Button>
          </Cell>
          <Cell col={1}>
            <Button ><Icon name="delete"/></Button>
          </Cell>
        </Grid>;
      }
    });
  }

  openEditEducationForm(level, educationId){
    const { dispatch, profile } = this.props;

    let index = profile['education'].findIndex((education) => {
      return educationId === education.id;
    });
    dispatch(openEducationForm(level, index));
  }

  saveEducationForm(nestedValidationCallback){
    const { dispatch, saveProfile, profile, requiredFields, validationMessages } = this.props;
    let fields;
    if (_.isFunction(nestedValidationCallback)) {
      fields = nestedValidationCallback(profile, requiredFields);
    } else {
      fields = requiredFields;
    }
    saveProfile(profile, fields, validationMessages ).then(() => {
      dispatch(closeEducationForm());
    });
  }

  handleSwitchClick(level){
    const {dispatch, educationLevels} = this.props;
    let newState = Object.assign({}, educationLevels);
    newState[level] = !educationLevels[level];
    dispatch(toggleEducationLevel(newState));
  }

  handleCloseDialog(){
    const { dispatch } = this.props;
    dispatch(closeEducationForm());
    dispatch(clearProfileEdit());
  }

  render() {
    let { profile, educationDialog, educationLevels} = this.props;

    if (profile['education'] === undefined){
      return null;
    }

    let levelsGrid = this.educationLevelOptions.map(level =>{
      return <Cell col={12} key={level.value} >
        <Grid key={level.value} className="education-level-header">
          <Cell col={11}>
{level.label}
</Cell>
          <Cell col={1}>
            <Switch ripple onChange={()=>{this.handleSwitchClick(level.value);}}
              checked={educationLevels[level.value]}/>
          </Cell>
        </Grid>
        { this.printAddDegree(level)}
        { this.printExistingEducations(level)}
      </Cell>;
    });

    let keySet = (key) =>['education', educationDialog.educationIndex, key];

    let actions = [
      <Button key="save" type='button' onClick={()=>{this.saveEducationForm(EducationTab.validation);}}>Save</Button>,
      <Button key="cancel" type='button' onClick={this.handleCloseDialog}>Cancel</Button>
    ];

    return <Grid className="profile-tab-grid">
      <Dialog
        open={educationDialog.openDialog}
        className="profile-form-dialog"
        onRequestClose={this.handleCloseDialog}
        title={this.educationLevelLabels[educationDialog.degreeLevel]}
        actions={actions}
      >
        <Grid>
          <Cell col={6}>
            {this.boundTextField(keySet('field_of_study'), 'Field of Study')}
          </Cell>
          <Cell col={6}>
            {this.boundMonthYearField(keySet('graduation_date'), 'Graduation Date')}
          </Cell>
        </Grid>
        <Grid>
          <Cell col={6}>
            {this.boundTextField(keySet('school_name'), 'School Name')}
          </Cell>
          <Cell col={6}>
          </Cell>
        </Grid>
        <Grid>
          <Cell col={4}>
            {this.boundSelectField(keySet('school_country'), 'Country', this.countryOptions)}
          </Cell>
          <Cell col={4}>
            {this.boundStateSelectField(
              keySet('school_state_or_territory'),
              keySet('school_country'),
              'State'
            )}
          </Cell>
          <Cell col={4}>
            {this.boundTextField(keySet('school_city'), 'City')}
          </Cell>
        </Grid>
      </Dialog>

      {levelsGrid}

     <Button raised onClick={this.saveAndContinue}>
        Save and continue
     </Button>
    </Grid>;
  }
}

const mapStateToProps = state => ({
  educationDialog: state.educationDialog,
  educationLevels: state.educationLevels
});

export default connect(mapStateToProps)(EducationTab);
<|endoftext|>


<commit_before>var tc = tc || {};
tc.gam = tc.gam || {};
tc.gam.project_widgets = tc.gam.project_widgets || {};

tc.gam.project_widgets.need_form = function(options) {
    tc.util.log('project.need_form');
    var dom = options.dom,
        cached_events = [],
        self = {};

        //Helper function to make the jqDropDown plugin more robust
        //since you can't set multiple classes at a time.
        //  id - the selector for the select element, also used to
        //       identify the generated markup
        //  defaultVal - Used to identify the unselectable default value
        var initDropDown = function(id, defaultVal) {
          //Apply jqDropDown to our select element
          tc.jQ('#' + id).jqDropDown({
            toggleBtnName:'ddSelect',
            optionListName:'ddSelectOptions',
            containerName:'dd-' + id,
            optionChanged: function() {
              //This is not valid if we select the default
              if ($('#' + id).val() === defaultVal) {
                $('.dd-' + id + ' .ddSelect').addClass('not-valid has-been-focused').removeClass('valid');
              } else {
                $('.dd-' + id + ' .ddSelect').addClass('valid has-been-focused').removeClass('not-valid');
              }
            }
          });

          //Add the default container css class (important, common styles on this guy)
          tc.jQ('.dd-' + id).addClass('ddSelectContainer');

          //There's no default value, something is always selected, so it's always valid
          if (!defaultVal) {
            tc.jQ('.dd-' + id).addClass('ddNoDefault');
            tc.jQ('.dd-' + id + ' .ddSelect').addClass('valid has-been-focused').removeClass('not-valid');
          }
        };

    /**
     * Function: initMerlin
     * Initialize the merlin object for validation of the modal dialog.
     */
    var initMerlin = function(need_id) {
        var merlin;

        //We are using merlin only for the built-in validation in this case.
        merlin =  new tc.merlin(options.app, {
            name:'need_form',
            dom:tc.jQ('.add-need.merlin'),
            next_button:tc.jQ('a.need-submit'),
            first_step:'need_form',
            use_hashchange:false,
            data: {
              type:'volunteer',
              request:null,
              quantity:null,
              description:null,
              date:null,
              time:null,
              duration:null,
              project_id:null,
              address:null
            },
            steps: {
                'need_form': {
                    selector: '.step.add-need-step',
                    next_step:'need-submit',
                    inputs: {
                        'quantity': {
                            selector: '#vol-quantity',
                            validators: ['required', 'numeric'],
                            hint:'Qty'
                        },
                        'request': {
                            selector: '#vol-job',
                            validators: ['required', 'max-100'],
                            hint:'Job Title - DJ, Cashier, etc'
                        },
                        'description': {
                          selector: '#vol-desc',
                          validators: ['required', 'max-200'],
                          hint:'Write a brief description of the volunteer tasks and skills.',
                          counter:{
                            selector:'.charlimit.title',
                            limit:200
                          }
                        },
                        'duration': {
                          selector: '#vol-hours',
                          validators: ['required', 'numeric'],
                          hint:''
                        },
                        'address': {
                          selector: '#vol-street',
                          validators: ['required'],
                          hint:'Address'
                        },
                        'month': {
                          selector: '#vol-month',
                          validators: function(input, element, step, submit) {

                            if (submit) {
                              $('.ddSelect').addClass('not-valid has-been-focused has-attempted-submit').removeClass('valid');
                            }

                            if ($(element).val() === 'Month') {
                              $('.ddSelect').addClass('not-valid').removeClass('valid');
                              return {
                                valid: false,
                                errors: ['Must select a month.']
                              }
                            } else {
                              $('.ddSelect').addClass('valid').removeClass('not-valid');
                              return {valid: true}
                            }
                          },
                          hint:'Month'
                        },
                        'day': {
                          selector: '#vol-day',
                          validators: ['required', 'numeric'],
                          hint:'Day'
                        },
                        'time': {
                          selector: '#vol-time',
                          validators: ['required'],
                          hint:'Time'
                        }
                    },
                    init:function(merlin, dom) {
                      // Set up the fancy jqDropDown for month
                      initDropDown('vol-month', 'Month');
                      initDropDown('event-list', 'Link to an event');

                      if (need_id) {
                        tc.jQ.each(merlin.current_step.inputs, function(key, input) {
                          if (input.default_val) {
                            input.dom.val(input.default_val);
                          }
                        });
                        merlin.validate(true);
                      }
                    },
                    finish:function(merlin, dom) {
                      var d = new Date();
                      var needDate = d.getFullYear()
                              + '-' + (parseInt(merlin.current_step.inputs.month.dom.val())+1)
                              + '-' + merlin.current_step.inputs.day.dom.val();
                      merlin.options.data = tc.jQ.extend(merlin.options.data,{
                        type:'volunteer',
                        request:merlin.current_step.inputs.request.dom.val(),
                        quantity:merlin.current_step.inputs.quantity.dom.val(),
                        description:merlin.current_step.inputs.description.dom.val(),
                        date:needDate,
                        time:merlin.current_step.inputs.time.dom.val(),
                        duration:merlin.current_step.inputs.duration.dom.val(),
                        project_id:merlin.app.app_page.data.project.project_id,
                        address:merlin.current_step.inputs.address.dom.val()
                      });
                    }
                },
                'need-submit':{
                  selector:'.step.submit-need-step',
                  init:function(merlin,dom){
                    var need_data = merlin.options.data;

                    var success = function(data,tx,xhr){
                      if(data == 'False'){
                        return false;
                      }
                      window.location.hash = 'show,needs';
                      window.location.reload();
                    };
                    if (need_id === undefined) {
                      tc.gam.project_data.createNeed(need_data, success);
                    } else {
                      tc.gam.project_data.updateNeed(need_id, need_data, success);
                    }
                  }
                }
            }
        });

        merlin.show_step('need_form');
    };

    var mergeTemplate = function(need_details) {
        var new_details = tc.jQ.extend(true, {
                day: function() { return this.date ? (new Date(this.date).getUTCDate()) : ''; },
                monthOpts: function() {
                  var needDate = this.date ? (new Date(this.date).getUTCMonth()) : '';
                  var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
                  var options = '';
                  for (var i = 0; i < months.length; i++) {
                    if (i === needDate) {
                      options += '<option value="' + i + '" selected>' + months[i] + '</option>';
                    } else {
                      options += '<option value="' + i + '">' + months[i] + '</option>';
                    }
                  }
                  return options;
                }
            }, need_details),
            $html = ich.need_form_tmpl(new_details);

        $html.find('#event-list').html(ich.event_list_tmpl({events: cached_events}));

        dom.find('.add-need-step').html($html);
    };

    var initForm = function(need_id, callback) {
      tc.gam.project_data.getEvents(function(events) {
        cached_events = events;

        if (need_id) {
            tc.gam.project_data.getNeedDetails(need_id, function(data){
                mergeTemplate(data);
                if (callback) {
                    callback();
                }
                initMerlin(need_id);
            });
        } else {
            mergeTemplate();
            if (callback) {
                callback();
            }
            initMerlin();
        }
      });
    };

    /**
     * Function: bindEvents
     * Bind events for this widget
     */
    var bindEvents = function() {
        tc.jQ(tc).bind('show-project-widget', function(event, widgetName, id) {
            if (options.name === widgetName) {
                tc.util.log('&&& showing ' + options.name);

                initForm(id, function(){
                    dom.show();
                });

            } else {
                tc.util.log('&&& hiding ' + options.name);
                dom.hide();
            }
        });
    };

    bindEvents();
    return self;
};
<commit_msg>handle dd validation in merlin, not dd onchange<commit_after>var tc = tc || {};
tc.gam = tc.gam || {};
tc.gam.project_widgets = tc.gam.project_widgets || {};

tc.gam.project_widgets.need_form = function(options) {
    tc.util.log('project.need_form');
    var dom = options.dom,
        cached_events = [],
        self = {};

        //Helper function to make the jqDropDown plugin more robust
        //since you can't set multiple classes at a time.
        //  id - the selector for the select element, also used to
        //       identify the generated markup
        //  defaultVal - Used to identify the unselectable default value
        var initDropDown = function(id, defaultVal) {
          //Apply jqDropDown to our select element
          tc.jQ('#' + id).jqDropDown({
            toggleBtnName:'ddSelect',
            optionListName:'ddSelectOptions',
            containerName:'dd-' + id,
            optionChanged: function() {
              //manually trigger the change event on the select element
              //so that Merlin validation will trigger properly
              tc.jQ('#' + id).change();
            }
          });

          //Add the default container css class (important, common styles on this guy)
          tc.jQ('.dd-' + id).addClass('ddSelectContainer');

          //There's no default value, something is always selected, so it's always valid
          if (!defaultVal) {
            tc.jQ('.dd-' + id).addClass('ddNoDefault');
            tc.jQ('.dd-' + id + ' .ddSelect').addClass('valid has-been-focused').removeClass('not-valid');
          }
        };

    /**
     * Function: initMerlin
     * Initialize the merlin object for validation of the modal dialog.
     */
    var initMerlin = function(need_id) {
        var merlin;

        //We are using merlin only for the built-in validation in this case.
        merlin =  new tc.merlin(options.app, {
            name:'need_form',
            dom:tc.jQ('.add-need.merlin'),
            next_button:tc.jQ('a.need-submit'),
            first_step:'need_form',
            use_hashchange:false,
            data: {
              type:'volunteer',
              request:null,
              quantity:null,
              description:null,
              date:null,
              time:null,
              duration:null,
              project_id:null,
              address:null
            },
            steps: {
                'need_form': {
                    selector: '.step.add-need-step',
                    next_step:'need-submit',
                    inputs: {
                        'quantity': {
                            selector: '#vol-quantity',
                            validators: ['required', 'numeric'],
                            hint:'Qty'
                        },
                        'request': {
                            selector: '#vol-job',
                            validators: ['required', 'max-100'],
                            hint:'Job Title - DJ, Cashier, etc'
                        },
                        'description': {
                          selector: '#vol-desc',
                          validators: ['required', 'max-200'],
                          hint:'Write a brief description of the volunteer tasks and skills.',
                          counter:{
                            selector:'.charlimit.title',
                            limit:200
                          }
                        },
                        'duration': {
                          selector: '#vol-hours',
                          validators: ['required', 'numeric'],
                          hint:''
                        },
                        'address': {
                          selector: '#vol-street',
                          validators: ['required'],
                          hint:'Address'
                        },
                        'month': {
                          selector: '#vol-month',
                          validators: function(input, element, step, submit) {
                            var $ddSelect = element.next('.ddSelectContainer').find('.ddSelect');

                            if (submit) {
                              $ddSelect.addClass('not-valid has-been-focused has-attempted-submit').removeClass('valid');
                            }

                            if ($(element).val() === 'Month') {
                              $ddSelect.addClass('not-valid').removeClass('valid');
                              return {
                                valid: false,
                                errors: ['Must select a month.']
                              }
                            } else {
                              $ddSelect.addClass('valid').removeClass('not-valid');
                              return {valid: true}
                            }
                          },
                          hint:'Month'
                        },
                        'day': {
                          selector: '#vol-day',
                          validators: ['required', 'numeric'],
                          hint:'Day'
                        },
                        'time': {
                          selector: '#vol-time',
                          validators: ['required'],
                          hint:'Time'
                        },
                        'event_link': {
                          selector: '#event-list',
                          validators: function(merlinInput, $element, step, onSubmit) {

                          }
                        }
                    },
                    init:function(merlin, dom) {
                      // Set up the fancy jqDropDown for month
                      initDropDown('vol-month', 'Month');
                      initDropDown('event-list', 'Link to an event');

                      if (need_id) {
                        tc.jQ.each(merlin.current_step.inputs, function(key, input) {
                          if (input.default_val) {
                            input.dom.val(input.default_val);
                          }
                        });
                        merlin.validate(true);
                      }
                    },
                    finish:function(merlin, dom) {
                      var d = new Date();
                      var needDate = d.getFullYear()
                              + '-' + (parseInt(merlin.current_step.inputs.month.dom.val())+1)
                              + '-' + merlin.current_step.inputs.day.dom.val();
                      merlin.options.data = tc.jQ.extend(merlin.options.data,{
                        type:'volunteer',
                        request:merlin.current_step.inputs.request.dom.val(),
                        quantity:merlin.current_step.inputs.quantity.dom.val(),
                        description:merlin.current_step.inputs.description.dom.val(),
                        date:needDate,
                        time:merlin.current_step.inputs.time.dom.val(),
                        duration:merlin.current_step.inputs.duration.dom.val(),
                        project_id:merlin.app.app_page.data.project.project_id,
                        address:merlin.current_step.inputs.address.dom.val()
                      });
                    }
                },
                'need-submit':{
                  selector:'.step.submit-need-step',
                  init:function(merlin,dom){
                    var need_data = merlin.options.data;

                    var success = function(data,tx,xhr){
                      if(data == 'False'){
                        return false;
                      }
                      window.location.hash = 'show,needs';
                      window.location.reload();
                    };
                    if (need_id === undefined) {
                      tc.gam.project_data.createNeed(need_data, success);
                    } else {
                      tc.gam.project_data.updateNeed(need_id, need_data, success);
                    }
                  }
                }
            }
        });

        merlin.show_step('need_form');
    };

    var mergeTemplate = function(need_details) {
        var new_details = tc.jQ.extend(true, {
                day: function() { return this.date ? (new Date(this.date).getUTCDate()) : ''; },
                monthOpts: function() {
                  var needDate = this.date ? (new Date(this.date).getUTCMonth()) : '';
                  var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
                  var options = '';
                  for (var i = 0; i < months.length; i++) {
                    if (i === needDate) {
                      options += '<option value="' + i + '" selected>' + months[i] + '</option>';
                    } else {
                      options += '<option value="' + i + '">' + months[i] + '</option>';
                    }
                  }
                  return options;
                }
            }, need_details),
            $html = ich.need_form_tmpl(new_details);

        $html.find('#event-list').html(ich.event_list_tmpl({events: cached_events}));

        dom.find('.add-need-step').html($html);
    };

    var initForm = function(need_id, callback) {
      tc.gam.project_data.getEvents(function(events) {
        cached_events = events;

        if (need_id) {
            tc.gam.project_data.getNeedDetails(need_id, function(data){
                mergeTemplate(data);
                if (callback) {
                    callback();
                }
                initMerlin(need_id);
            });
        } else {
            mergeTemplate();
            if (callback) {
                callback();
            }
            initMerlin();
        }
      });
    };

    /**
     * Function: bindEvents
     * Bind events for this widget
     */
    var bindEvents = function() {
        tc.jQ(tc).bind('show-project-widget', function(event, widgetName, id) {
            if (options.name === widgetName) {
                tc.util.log('&&& showing ' + options.name);

                initForm(id, function(){
                    dom.show();
                });

            } else {
                tc.util.log('&&& hiding ' + options.name);
                dom.hide();
            }
        });
    };

    bindEvents();
    return self;
};
<|endoftext|>


<commit_before>module.exports = {
	api: '/api',
	debug: true,
	PAGE_SIZE: 3,
	name: '客服工单系统',
	storage_prefix: 'wop$',
	local: {
		user: 'user',
		loginInfo: 'loginInfo'
	},
	formItemLayout: {
		labelCol: { span: 4 },
		wrapperCol: { span: 12 }
	},
	userType: {
		doctor: 'doctor', worker: 'worker'
	},
	/**
 	* 根据委托单名称定义表头的显示项
 	*/
	ritField: {
		key: 'key', name: 'name', sex: 'sex', birthday: 'birthday', tel: 'tell',
		disease: 'disease', cardDate: 'cardDate', drugs: 'drugs'
	}
}<commit_msg>config update<commit_after>module.exports = {
	api: '/api',
	debug: true,
	PAGE_SIZE: 3,
	name: '客服工单系统',
	storage_prefix: 'wop$',
	local: {
		user: 'user',
		loginInfo: 'loginInfo'
	},
	formItemLayout: {
		labelCol: { span: 4 },
		wrapperCol: { span: 12 }
	},
	userType: {
		doctor: 'doctor', worker: 'worker'
	},
	/**
 	* 根据委托单名称定义表头的显示项
 	*/
	ritField: {
		key: 'key', name: 'name', sex: 'sex', birthday: 'birthday', tel: 'tell', present: 'present',
		disease: 'disease', cardDate: 'cardDate', drugs: 'drugs', notice: 'notice', operation: 'operation',
		booking: 'booking', remark: 'remark'
	}
}<|endoftext|>


<commit_before>'use babel';

import { CompositeDisposable } from 'atom'

class Main {
  constructor() {

    // initialize members
    this.active = false
    this.toggled = false
    this.interval = null
    this.image_dir = ''
  }

  activate() {
    if (this.active) return

    this.interval = atom.config.get('slide-show.updateInterval') * 1000;
    this.image_dir = atom.config.get('slide-show.imageDir')

    if (atom.config.get('slide-show.autoToggle')) {this.toggle()}
  }

  deactivate() {
    if (!this.active) return
  }

  serialize() {
  }

  toggle() {
    if (this.toggled) {
      this.toggled = false
    } else {
      this.toggled = true

      fs = require('fs');
      path = require('path');
      fileList = [];
      files = fs.readdirSync(this.image_dir);
      images = files.filter((f) => /\.jpg|\.jpeg|\.png/.test(path.extname(f)));
      images = images.map((f) => path.join(this.image_dir, f));

      i = 0;
      element = document.getElementsByTagName('atom-workspace')[0];
      setInterval(function() {
        element.style.backgroundImage = `url(${images[i]})`;
        i = (i + 1) % images.length;
      }, this.interval);
    }
  }
}

export default new Main()
<commit_msg>remove semicolons<commit_after>'use babel'

import { CompositeDisposable } from 'atom'

class Main {
  constructor() {
    this.active = false
    this.toggled = false
    this.interval = null
    this.image_dir = ''
    this.task = null
    this.subscription = null
  }

  activate() {
    if (this.active) return

    this.interval = atom.config.get('slide-show.updateInterval') * 1000
    this.image_dir = atom.config.get('slide-show.imageDir')

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'slide-show:toggle': () => this.toggle()
    }));

    if (atom.config.get('slide-show.autoToggle')) {this.toggle()}
  }

  deactivate() {
    if (!this.active) return
    this.subscriptions.dispose();
  }

  serialize() {
  }

  toggle() {
    if (this.toggled) {
      this.toggled = false
      clearInterval(this.task)
    } else {
      this.toggled = true

      fs = require('fs')
      path = require('path')
      fileList = []
      files = fs.readdirSync(this.image_dir)
      images = files.filter((f) => /\.jpg|\.jpeg|\.png/.test(path.extname(f)))
      images = images.map((f) => path.join(this.image_dir, f))

      i = 0
      element = document.getElementsByTagName('atom-workspace')[0]
      this.task = setInterval(function() {
        element.style.backgroundImage = `url(${images[i]})`
        i = (i + 1) % images.length
      }, this.interval)
    }
  }
}

export default new Main()
<|endoftext|>