<commit_before>

/**
 *
 * ISO 8601 date functions
 *
 * parsing originally from dojo.date.serialize
 *
 * according to http://svn.dojotoolkit.org/src/trunk/LICENSE :
 *    Dojo is availble under *either* the terms of the modified BSD license *or* the
 *    Academic Free License version 2.1.
 *
 *
 * formatting from http://delete.me.uk/2005/03/iso8601.html
 *
 *   "This code is available under the AFL. This should mean
 *    you can use it pretty much anyway you want."
 */

/* - repackaged for mjt
 * - inlined dojo.string.pad
 * - return NaN rather than null for consistency with builtin Date.parse()
 * but not much else done hopefully */

(function (mjt) {

var setIso8601 = function(/*Date*/dateObject, /*String*/formattedString){
	// summary: sets a Date object based on an ISO 8601 formatted string (uses date and time)
	var comps = (formattedString.indexOf("T") == -1) ? formattedString.split(" ") : formattedString.split("T");
	dateObject = setIso8601Date(dateObject, comps[0]);
	if(comps.length == 2){ dateObject = setIso8601Time(dateObject, comps[1]); }
	return dateObject; /* Date or null */
};

var fromIso8601 = function(/*String*/formattedString){
	// summary: returns a Date object based on an ISO 8601 formatted string (uses date and time)
	return setIso8601(new Date(0, 0), formattedString);
};

var setIso8601Date = function(/*String*/dateObject, /*String*/formattedString){
	// summary: sets a Date object based on an ISO 8601 formatted string (date only)
	var regexp = "^(-?[0-9]{4})((-?([0-9]{2})(-?([0-9]{2}))?)|" +
			"(-?([0-9]{3}))|(-?W([0-9]{2})(-?([1-7]))?))?$";
	var d = formattedString.match(new RegExp(regexp));
	if(!d){
		mjt.log("invalid date string: " + formattedString);
		return NaN;
	}
	var year = d[1];
	var month = d[4];
	var date = d[6];
	var dayofyear = d[8];
	var week = d[10];
	var dayofweek = d[12] || 1;

	dateObject.setFullYear(year);

	if(dayofyear){
		dateObject.setMonth(0);
		dateObject.setDate(Number(dayofyear));
	}
	else if(week){
		dateObject.setMonth(0);
		dateObject.setDate(1);
		var day = dateObject.getDay() || 7;
		var offset = Number(dayofweek) + (7 * Number(week));

		if(day <= 4){ dateObject.setDate(offset + 1 - day); }
		else{ dateObject.setDate(offset + 8 - day); }
	} else{
		if(month){
			dateObject.setDate(1);
			dateObject.setMonth(month - 1);
		}
		if(date){ dateObject.setDate(date); }
	}

	return dateObject; // Date
};

var fromIso8601Date = function(/*String*/formattedString){
	// summary: returns a Date object based on an ISO 8601 formatted string (date only)
	return setIso8601Date(new Date(0, 0), formattedString);
};

var setIso8601Time = function(/*Date*/dateObject, /*String*/formattedString){
	// summary: sets a Date object based on an ISO 8601 formatted string (time only)

	// first strip timezone info from the end
	var timezone = "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$";
	var d = formattedString.match(new RegExp(timezone));

	var offset = 0; // local time if no tz info
	if(d){
		if(d[0] != 'Z'){
			offset = (Number(d[3]) * 60) + Number(d[5] || 0);
			if(d[2] != '-'){ offset *= -1; }
		}
		offset -= dateObject.getTimezoneOffset();
		formattedString = formattedString.substr(0, formattedString.length - d[0].length);
	}

	// then work out the time
	var regexp = "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$";
	d = formattedString.match(new RegExp(regexp));
	if(!d){
		mjt.log("invalid time string: " + formattedString);
		return NaN;
	}
	var hours = d[1];
	var mins = Number(d[3] || 0);
	var secs = d[5] || 0;
	var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0;

	dateObject.setHours(hours);
	dateObject.setMinutes(mins);
	dateObject.setSeconds(secs);
	dateObject.setMilliseconds(ms);

	if(offset !== 0){
		dateObject.setTime(dateObject.getTime() + offset * 60000);
	}
	return dateObject; // Date
};

var fromIso8601Time = function(/*String*/formattedString){
	// summary: returns a Date object based on an ISO 8601 formatted string (date only)
	return setIso8601Time(new Date(0, 0), formattedString);
};

/* RFC-3339 Date Functions
 *************************/

var toRfc3339 = function(/*Date?*/dateObject, /*String?*/selector){
//	summary:
//		Format a JavaScript Date object as a string according to RFC 3339
//
//	dateObject:
//		A JavaScript date, or the current date and time, by default
//
//	selector:
//		"dateOnly" or "timeOnly" to format selected portions of the Date object.
//		Date and time will be formatted by default.

//FIXME: tolerate Number, string input?
	if(!dateObject){
		dateObject = new Date();
	}

        // inlined from dojo.string.pad()
	var _ = function(/* string */str, /* integer */len/*=2*/, /* string */ c/*='0'*/, /* integer */dir/*=1*/) {
	//	summary
	//	Pad 'str' to guarantee that it is at least 'len' length with the character 'c' at either the
	//	start (dir=1) or end (dir=-1) of the string
	var out = String(str);
	if(!c) {
		c = '0';
	}
	if(!dir) {
		dir = 1;
	}
	while(out.length < len) {
		if(dir > 0) {
			out = c + out;
		} else {
			out += c;
		}
	}
	return out;	//	string
        }
	var formattedDate = [];
	if(selector != "timeOnly"){
		var date = [_(dateObject.getFullYear(),4), _(dateObject.getMonth()+1,2), _(dateObject.getDate(),2)].join('-');
		formattedDate.push(date);
	}
	if(selector != "dateOnly"){
		var time = [_(dateObject.getHours(),2), _(dateObject.getMinutes(),2), _(dateObject.getSeconds(),2)].join(':');
		var timezoneOffset = dateObject.getTimezoneOffset();
		time += (timezoneOffset > 0 ? "-" : "+") +
					_(Math.floor(Math.abs(timezoneOffset)/60),2) + ":" +
					_(Math.abs(timezoneOffset)%60,2);
		formattedDate.push(time);
	}
	return formattedDate.join('T'); // String
};

var fromRfc3339 = function(/*String*/rfcDate){
//	summary:
//		Create a JavaScript Date object from a string formatted according to RFC 3339
//
//	rfcDate:
//		A string such as 2005-06-30T08:05:00-07:00
//		"any" is also supported in place of a time.

	// backwards compatible support for use of "any" instead of just not
	// including the time
	if(rfcDate.indexOf("Tany")!=-1){
		rfcDate = rfcDate.replace("Tany","");
	}
	var dateObject = new Date();
	return setIso8601(dateObject, rfcDate); // Date or null
};

////////////////////////////////////////////////////////////////////////////

/**
 *  from  http://delete.me.uk/2005/03/iso8601.html
 *  which is the original source of the dojo parsing too.
 *
 */

var toISO8601String = function (date, format, offset) {
 /* accepted values for the format [1-6]:
 1 Year:
 YYYY (eg 1997)
 2 Year and month:
 YYYY-MM (eg 1997-07)
 3 Complete date:
 YYYY-MM-DD (eg 1997-07-16)
 4 Complete date plus hours and minutes:
 YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
 5 Complete date plus hours, minutes and seconds:
 YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
 6 Complete date plus hours, minutes, seconds and a decimal
 fraction of a second
 YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
 */
    if (!format) { format = 6; }
    if (!offset) {
        offset = 'Z';
    } else {
        var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
        var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
        offsetnum *= ((d[1] == '-') ? -1 : 1);
        date = new Date(Number(Number(date) + (offsetnum * 60000)));
    }

    var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; };

    var str = "";
    str += date.getUTCFullYear();
    if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
    if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
    if (format > 3) {
        str += "T" + zeropad(date.getUTCHours()) +
               ":" + zeropad(date.getUTCMinutes());
    }
    if (format > 5) {
        var secs = Number(date.getUTCSeconds() + "." +
                   ((date.getUTCMilliseconds() < 100) ? '0' : '') +
                   zeropad(date.getUTCMilliseconds()));
        str += ":" + zeropad(secs);
    } else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }

    if (format > 3) { str += offset; }
    return str;
};

////////////////////////////////////////////////////////////////////////////

/**
 *  convert a date specified as an ISO8601 / W3C formatted string
 *  to a javascript Date object.
 */
mjt.freebase.date_from_iso = function (isodate) {
    if (typeof isodate == 'undefined' || isodate === null)
        return NaN;
    return fromIso8601(isodate.toString());
};

/**
 *  convert a a javascript Date object to a string containing
 *  an ISO8601 / W3C formatted representation.
 */

mjt.freebase.date_to_iso = function (d) {
    return toISO8601String(d);
};

})(mjt);
<commit_msg>Issue 101440043: OD-5779: Fix displaying topics with just time in the timestamp field<commit_after>

/**
 *
 * ISO 8601 date functions
 *
 * parsing originally from dojo.date.serialize
 *
 * according to http://svn.dojotoolkit.org/src/trunk/LICENSE :
 *    Dojo is availble under *either* the terms of the modified BSD license *or* the
 *    Academic Free License version 2.1.
 *
 *
 * formatting from http://delete.me.uk/2005/03/iso8601.html
 *
 *   "This code is available under the AFL. This should mean
 *    you can use it pretty much anyway you want."
 */

/* - repackaged for mjt
 * - inlined dojo.string.pad
 * - return NaN rather than null for consistency with builtin Date.parse()
 * but not much else done hopefully */

(function (mjt) {

var setIso8601 = function(/*Date*/dateObject, /*String*/formattedString){
	// summary: sets a Date object based on an ISO 8601 formatted string (uses date and time)
	var comps = (formattedString.indexOf("T") == -1) ? formattedString.split(" ") : formattedString.split("T");
	if (!comps[0]) {
		// For Hours like "T06:00Z", just fail to parse with NaN.
		return NaN;
	}
	dateObject = setIso8601Date(dateObject, comps[0]);
	if(comps.length == 2){ dateObject = setIso8601Time(dateObject, comps[1]); }
	return dateObject; /* Date or null */
};

var fromIso8601 = function(/*String*/formattedString){
	// summary: returns a Date object based on an ISO 8601 formatted string (uses date and time)
	return setIso8601(new Date(0, 0), formattedString);
};

var setIso8601Date = function(/*String*/dateObject, /*String*/formattedString){
	// summary: sets a Date object based on an ISO 8601 formatted string (date only)
	var regexp = "^(-?[0-9]{4})((-?([0-9]{2})(-?([0-9]{2}))?)|" +
			"(-?([0-9]{3}))|(-?W([0-9]{2})(-?([1-7]))?))?$";
	var d = formattedString.match(new RegExp(regexp));
	if(!d){
		mjt.log("invalid date string: " + formattedString);
		return NaN;
	}
	var year = d[1];
	var month = d[4];
	var date = d[6];
	var dayofyear = d[8];
	var week = d[10];
	var dayofweek = d[12] || 1;

	dateObject.setFullYear(year);

	if(dayofyear){
		dateObject.setMonth(0);
		dateObject.setDate(Number(dayofyear));
	}
	else if(week){
		dateObject.setMonth(0);
		dateObject.setDate(1);
		var day = dateObject.getDay() || 7;
		var offset = Number(dayofweek) + (7 * Number(week));

		if(day <= 4){ dateObject.setDate(offset + 1 - day); }
		else{ dateObject.setDate(offset + 8 - day); }
	} else{
		if(month){
			dateObject.setDate(1);
			dateObject.setMonth(month - 1);
		}
		if(date){ dateObject.setDate(date); }
	}

	return dateObject; // Date
};

var fromIso8601Date = function(/*String*/formattedString){
	// summary: returns a Date object based on an ISO 8601 formatted string (date only)
	return setIso8601Date(new Date(0, 0), formattedString);
};

var setIso8601Time = function(/*Date*/dateObject, /*String*/formattedString){
	// summary: sets a Date object based on an ISO 8601 formatted string (time only)

	// first strip timezone info from the end
	var timezone = "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$";
	var d = formattedString.match(new RegExp(timezone));

	var offset = 0; // local time if no tz info
	if(d){
		if(d[0] != 'Z'){
			offset = (Number(d[3]) * 60) + Number(d[5] || 0);
			if(d[2] != '-'){ offset *= -1; }
		}
		offset -= dateObject.getTimezoneOffset();
		formattedString = formattedString.substr(0, formattedString.length - d[0].length);
	}

	// then work out the time
	var regexp = "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$";
	d = formattedString.match(new RegExp(regexp));
	if(!d){
		mjt.log("invalid time string: " + formattedString);
		return NaN;
	}
	var hours = d[1];
	var mins = Number(d[3] || 0);
	var secs = d[5] || 0;
	var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0;

	dateObject.setHours(hours);
	dateObject.setMinutes(mins);
	dateObject.setSeconds(secs);
	dateObject.setMilliseconds(ms);

	if(offset !== 0){
		dateObject.setTime(dateObject.getTime() + offset * 60000);
	}
	return dateObject; // Date
};

var fromIso8601Time = function(/*String*/formattedString){
	// summary: returns a Date object based on an ISO 8601 formatted string (date only)
	return setIso8601Time(new Date(0, 0), formattedString);
};

/* RFC-3339 Date Functions
 *************************/

var toRfc3339 = function(/*Date?*/dateObject, /*String?*/selector){
//	summary:
//		Format a JavaScript Date object as a string according to RFC 3339
//
//	dateObject:
//		A JavaScript date, or the current date and time, by default
//
//	selector:
//		"dateOnly" or "timeOnly" to format selected portions of the Date object.
//		Date and time will be formatted by default.

//FIXME: tolerate Number, string input?
	if(!dateObject){
		dateObject = new Date();
	}

        // inlined from dojo.string.pad()
	var _ = function(/* string */str, /* integer */len/*=2*/, /* string */ c/*='0'*/, /* integer */dir/*=1*/) {
	//	summary
	//	Pad 'str' to guarantee that it is at least 'len' length with the character 'c' at either the
	//	start (dir=1) or end (dir=-1) of the string
	var out = String(str);
	if(!c) {
		c = '0';
	}
	if(!dir) {
		dir = 1;
	}
	while(out.length < len) {
		if(dir > 0) {
			out = c + out;
		} else {
			out += c;
		}
	}
	return out;	//	string
        }
	var formattedDate = [];
	if(selector != "timeOnly"){
		var date = [_(dateObject.getFullYear(),4), _(dateObject.getMonth()+1,2), _(dateObject.getDate(),2)].join('-');
		formattedDate.push(date);
	}
	if(selector != "dateOnly"){
		var time = [_(dateObject.getHours(),2), _(dateObject.getMinutes(),2), _(dateObject.getSeconds(),2)].join(':');
		var timezoneOffset = dateObject.getTimezoneOffset();
		time += (timezoneOffset > 0 ? "-" : "+") +
					_(Math.floor(Math.abs(timezoneOffset)/60),2) + ":" +
					_(Math.abs(timezoneOffset)%60,2);
		formattedDate.push(time);
	}
	return formattedDate.join('T'); // String
};

var fromRfc3339 = function(/*String*/rfcDate){
//	summary:
//		Create a JavaScript Date object from a string formatted according to RFC 3339
//
//	rfcDate:
//		A string such as 2005-06-30T08:05:00-07:00
//		"any" is also supported in place of a time.

	// backwards compatible support for use of "any" instead of just not
	// including the time
	if(rfcDate.indexOf("Tany")!=-1){
		rfcDate = rfcDate.replace("Tany","");
	}
	var dateObject = new Date();
	return setIso8601(dateObject, rfcDate); // Date or null
};

////////////////////////////////////////////////////////////////////////////

/**
 *  from  http://delete.me.uk/2005/03/iso8601.html
 *  which is the original source of the dojo parsing too.
 *
 */

var toISO8601String = function (date, format, offset) {
 /* accepted values for the format [1-6]:
 1 Year:
 YYYY (eg 1997)
 2 Year and month:
 YYYY-MM (eg 1997-07)
 3 Complete date:
 YYYY-MM-DD (eg 1997-07-16)
 4 Complete date plus hours and minutes:
 YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
 5 Complete date plus hours, minutes and seconds:
 YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
 6 Complete date plus hours, minutes, seconds and a decimal
 fraction of a second
 YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
 */
    if (!format) { format = 6; }
    if (!offset) {
        offset = 'Z';
    } else {
        var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
        var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
        offsetnum *= ((d[1] == '-') ? -1 : 1);
        date = new Date(Number(Number(date) + (offsetnum * 60000)));
    }

    var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; };

    var str = "";
    str += date.getUTCFullYear();
    if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
    if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
    if (format > 3) {
        str += "T" + zeropad(date.getUTCHours()) +
               ":" + zeropad(date.getUTCMinutes());
    }
    if (format > 5) {
        var secs = Number(date.getUTCSeconds() + "." +
                   ((date.getUTCMilliseconds() < 100) ? '0' : '') +
                   zeropad(date.getUTCMilliseconds()));
        str += ":" + zeropad(secs);
    } else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }

    if (format > 3) { str += offset; }
    return str;
};

////////////////////////////////////////////////////////////////////////////

/**
 *  convert a date specified as an ISO8601 / W3C formatted string
 *  to a javascript Date object.
 */
mjt.freebase.date_from_iso = function (isodate) {
    if (typeof isodate == 'undefined' || isodate === null)
        return NaN;
    return fromIso8601(isodate.toString());
};

/**
 *  convert a a javascript Date object to a string containing
 *  an ISO8601 / W3C formatted representation.
 */

mjt.freebase.date_to_iso = function (d) {
    return toISO8601String(d);
};

})(mjt);
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');

gulp.task('clean', function(cb) {
  require('rimraf')('dist', cb);
});

gulp.task('lint', function() {
  var jshint = require('gulp-jshint');

  return gulp.src('app/js/**/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

gulp.task('images', function(){
  return gulp.src('app/img/{,*/}*.{png,jpg,jpeg,gif,webp,svg}')
    .pipe(gulp.dest('dist/img'));
});

gulp.task('html', function(){
  var uglify = require('gulp-uglify'),
    minifyCss = require('gulp-minify-css'),
    useref = require('gulp-useref'),
    gulpif = require('gulp-if');

  return gulp.src('app/*.html')
    .pipe(useref.assets())
    .pipe(gulpif('*.js', uglify()))
    .pipe(gulpif('*.css', minifyCss()))
    .pipe(useref.restore())
    .pipe(useref())
    .pipe(gulp.dest('dist'));
});

// inject bower components
gulp.task('wiredep', function () {
  var wiredep = require('wiredep').stream;

  gulp.src('app/*.html')
    .pipe(wiredep({
      directory: 'app/bower_components'
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('connect', function() {
  var connect = require('connect');
  var app = connect()
    .use(require('connect-livereload')({ port: 35729 }))
    .use(connect.static('app'))
    .use(connect.directory('app'));

  require('http').createServer(app)
    .listen(9000)
    .on('listening', function() {
      console.log('Started connect web server on http://localhost:9000');

      require('opn')('http://localhost:9000');
    });
});

gulp.task('serve', ['connect'], function () {
  var livereload = require('gulp-livereload');

  livereload.listen();

  // watch for changes
  gulp.watch([
    'app/*.html',
    'app/css/**/*.css',
    'app/js/**/*.js',
    'app/img/**/*'
  ]).on('change', livereload.changed);

  gulp.watch('bower.json', ['wiredep']);
});

gulp.task('build', ['lint', 'html', 'images']);

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});
<commit_msg>Update to new useref API.<commit_after>'use strict';

var gulp = require('gulp');

gulp.task('clean', function(cb) {
  require('rimraf')('dist', cb);
});

gulp.task('lint', function() {
  var jshint = require('gulp-jshint');

  return gulp.src('app/js/**/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

gulp.task('images', function(){
  return gulp.src('app/img/{,*/}*.{png,jpg,jpeg,gif,webp,svg}')
    .pipe(gulp.dest('dist/img'));
});

gulp.task('html', function(){
  var uglify = require('gulp-uglify'),
    minifyCss = require('gulp-minify-css'),
    useref = require('gulp-useref'),
    gulpif = require('gulp-if'),
    assets = useref.assets();

  return gulp.src('app/*.html')
    .pipe(assets)
    .pipe(gulpif('*.js', uglify()))
    .pipe(gulpif('*.css', minifyCss()))
    .pipe(assets.restore())
    .pipe(useref())
    .pipe(gulp.dest('dist'));
});

// inject bower components
gulp.task('wiredep', function () {
  var wiredep = require('wiredep').stream;

  gulp.src('app/*.html')
    .pipe(wiredep({
      directory: 'app/bower_components'
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('connect', function() {
  var connect = require('connect');
  var app = connect()
    .use(require('connect-livereload')({ port: 35729 }))
    .use(connect.static('app'))
    .use(connect.directory('app'));

  require('http').createServer(app)
    .listen(9000)
    .on('listening', function() {
      console.log('Started connect web server on http://localhost:9000');

      require('opn')('http://localhost:9000');
    });
});

gulp.task('serve', ['connect'], function () {
  var livereload = require('gulp-livereload');

  livereload.listen();

  // watch for changes
  gulp.watch([
    'app/*.html',
    'app/css/**/*.css',
    'app/js/**/*.js',
    'app/img/**/*'
  ]).on('change', livereload.changed);

  gulp.watch('bower.json', ['wiredep']);
});

gulp.task('build', ['lint', 'html', 'images']);

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});
<|endoftext|>


<commit_before>'use strict';

angular.module('users').controller('AuthenticationController', ['$scope', '$state', '$http', '$location', '$window', '$timeout', 'Authentication',
  function ($scope, $state, $http, $location, $window, $timeout, Authentication) {
    $scope.authentication = Authentication;

    // Get an eventual error defined in the URL query string:
    $scope.error = $location.search().err;

    //// If user is signed in then redirect back home
    //if ($scope.authentication.user) {
    //  $location.path('/');
    //}

    $scope.signup = function (isValid) {
      $scope.error = null;

      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'userForm');

        return false;
      }

      $http.post('/api/auth/signup', $scope.credentials).success(function (response) {
        // If successful we assign the response to the global user model

        $state.go('settings.picture');

        $scope.authentication.user = response;

        // And redirect to the previous or home page

      }).error(function (response) {
        $scope.error = response.message;
      });
    };

    //be sure to inject $scope and $location
    $scope.changeLocation = function (url, forceReload) {
      $scope = $scope || angular.element(document).scope();
      if (forceReload || $scope.$$phase) {
        window.location = url;
      }
      else {
        //only use this if you want to replace the history stack
        //$location.path(url).replace();

        //this this if you want to change the URL and add it to the history stack
        $location.path(url);
        $scope.$apply();
      }
    };

    $scope.signin = function (isValid) {
      $scope.error = null;

      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'userForm');

        return false;
      }

      $http.post('/api/auth/signin', $scope.credentials).success(function (response) {
        // If successful we assign the response to the global user model
        $scope.authentication.user = response;

          $scope.authentication.user.imageURL  = '/modules/users/client/img/profile/saveme-placeholder.png';

        // And redirect to the previous or home page
        $state.go($state.previous.state.name || 'home', $state.previous.params);
      }).error(function (response) {
        $scope.error = response.message;
      });

    };

    // OAuth provider request
    $scope.callOauthProvider = function (url) {
      if ($state.previous && $state.previous.href) {
        url += '?redirect_to=' + encodeURIComponent($state.previous.href);
      }

      // Effectively call OAuth authentication route:
      $window.location.href = url;
    };
  }
]);
<commit_msg>Registration fixed.<commit_after>'use strict';

angular.module('users').controller('AuthenticationController', ['$scope', '$state', '$http', '$location', '$window', '$timeout', 'Authentication',
  function ($scope, $state, $http, $location, $window, $timeout, Authentication) {
    $scope.authentication = Authentication;

    // Get an eventual error defined in the URL query string:
    $scope.error = $location.search().err;

    //// If user is signed in then redirect back home
    //if ($scope.authentication.user) {
    //  $location.path('/');
    //}

    $scope.signup = function (isValid) {
      $scope.error = null;

      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'userForm');

        return false;
      }

      $http.post('/api/auth/signup', $scope.credentials).success(function (response) {
        // If successful we assign the response to the global user model

        $state.go('home');

        $scope.authentication.user = response;

        // And redirect to the previous or home page

      }).error(function (response) {
        $scope.error = response.message;
      });
    };

    //be sure to inject $scope and $location
    $scope.changeLocation = function (url, forceReload) {
      $scope = $scope || angular.element(document).scope();
      if (forceReload || $scope.$$phase) {
        window.location = url;
      }
      else {
        //only use this if you want to replace the history stack
        //$location.path(url).replace();

        //this this if you want to change the URL and add it to the history stack
        $location.path(url);
        $scope.$apply();
      }
    };

    $scope.signin = function (isValid) {
      $scope.error = null;

      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'userForm');

        return false;
      }

      $http.post('/api/auth/signin', $scope.credentials).success(function (response) {
        // If successful we assign the response to the global user model
        $scope.authentication.user = response;

          $scope.authentication.user.imageURL  = '/modules/users/client/img/profile/saveme-placeholder.png';

        // And redirect to the previous or home page
        $state.go($state.previous.state.name || 'home', $state.previous.params);
      }).error(function (response) {
        $scope.error = response.message;
      });

    };

    // OAuth provider request
    $scope.callOauthProvider = function (url) {
      if ($state.previous && $state.previous.href) {
        url += '?redirect_to=' + encodeURIComponent($state.previous.href);
      }

      // Effectively call OAuth authentication route:
      $window.location.href = url;
    };
  }
]);
<|endoftext|>


<commit_before>/**
 * Manage files associated with datasets. When uploading a file creates a new dataset
 * @param collectionId
 * @param data
 * @param field - JSON data key ('versions')
 * @param idField - HTML id for the template ('version' or 'correction')
 */

function editDatasetVersion(collectionId, data, field, idField) {
  var downloadExtensions, uriUpload, file;
  var lastIndex;
  if (data[field]) {
    lastIndex = data[field].length;
  } else {
    lastIndex = 0;
    data[field] = [];
  }
  var uploadedNotSaved = {uploaded: false, saved: false, fileUrl: "", oldLabel: data.description.versionLabel};
  $(".workspace-edit").scrollTop(Florence.globalVars.pagePos);
  //Add
  if (data.type === 'timeseries_dataset') {
    downloadExtensions = /\.csdb$/;
  } else if (data.type === 'dataset') {
    downloadExtensions = /\.csv$|.xls$|.zip$/;
  }

  var ajaxRequest = [];
  var templateData = $.extend(true, {}, data);
  $(templateData[field]).each(function (index, version) {
    var dfd = $.Deferred();
    if (version.correctionNotice) {
      templateData[field][index].type = true;
    } else {
      templateData[field][index].type = false;
    }
    templateData[field][index].label = version.label;
    dfd.resolve();
    ajaxRequest.push(dfd);
  });

  $.when.apply($, ajaxRequest).then(function () {
    var html = templates.editorCorrection({idField: idField});
    $('#' + idField).replaceWith(html);
    initialiseDatasetVersion(collectionId, data, templateData, field, idField);
  });

  $("#add-" + idField).one('click', function () {
    addTheVersion();
  });

  function addTheVersion() {
    var position = $(".workspace-edit").scrollTop();
    Florence.globalVars.pagePos = position + 200;
    $('#' + idField + '-section').append(
      '
' +
      '  <form id="UploadForm">' +
      '    <textarea class="auto-size" type="text" placeholder="Add a label here (E.g. Revised, Final, etc" id="label"></textarea>' +
      '    <input type="file" title="Select a file and click Submit" name="files">' +
      '
' +
      '    <button type="submit" form="UploadForm" value="submit">Submit</button>' +
      '    <button class="btn-page-cancel" id="file-cancel">Cancel</button>' +
      '  </form>' +
      '

' +
      '

' +
      '
');

    $('#file-cancel').one('click', function (e) {
      e.preventDefault();
      $('#' + lastIndex).remove();
      if (uploadedNotSaved.uploaded === true && uploadedNotSaved.saved === false) {
        data.description.versionLabel = uploadedNotSaved.oldLabel;
        deleteContent(collectionId, uploadedNotSaved.fileUrl,
          onSuccess = function () {
          },
          onError = function (error) {
            handleApiError(error);
          }
        );
      }
      initialiseDatasetVersion(collectionId, data, templateData, field, idField);
    });

    $('#UploadForm').submit(function (e) {
      e.preventDefault();
      e.stopImmediatePropagation();

      var formdata = new FormData();

      function showUploadedItem(source) {
        $('#list').append(source);
      }

      var versionLabel = this[0].value;
      file = this[1].files[0];
      if (!file) {
        alert('Please select a file to upload.');
        return;
      }

      document.getElementById("response").innerHTML = "Uploading . . .";

      var fileNameNoSpace = file.name.replace(/\s*/g, "").toLowerCase();
      uriUpload = data.uri + '/' + fileNameNoSpace;
      var safeUriUpload = checkPathSlashes(uriUpload);

      if (!!file.name.match(downloadExtensions)) {
        showUploadedItem(fileNameNoSpace);
        if (formdata) {
          formdata.append("name", file);
        }
      } else {
        alert('This file type is not supported');
        $('#' + lastIndex).remove();
        editDatasetVersion(collectionId, data, field, idField);
        return;
      }

      if (versionLabel.length < 4) {
        alert("This is not a valid file title");
        return;
      }

      if (formdata) {
        $.ajax({
          url: "/zebedee/content/" + collectionId + "?uri=" + safeUriUpload,
          type: 'POST',
          data: formdata,
          cache: false,
          processData: false,
          contentType: false,
          success: function () {
            document.getElementById("response").innerHTML = "File uploaded successfully";
            uploadedNotSaved.uploaded = true;
            uploadedNotSaved.fileUrl = safeUriUpload;
            // create the new version/correction
            saveNewCorrection(collectionId, data.uri,
              function (response) {
                var tmpDate = (new Date()).toISOString();           // it could use releaseDate
                if (idField === "correction") {
                  data[field].push({
                    correctionNotice: " ",
                    updateDate: data.description.releaseDate,
                    uri: response,
                    label: versionLabel
                  });
                } else {
                  data[field].push({
                    correctionNotice: "",
                    updateDate: data.description.releaseDate,
                    uri: response,
                    label: versionLabel
                  });
                }
                data.downloads = [{file: fileNameNoSpace}];
                data.description.releaseDate = tmpDate;
                data.description.versionLabel = versionLabel;
                uploadedNotSaved.saved = true;
                $("#" + idField).find('.edit-section__content').prepend('
');
                $("#" + idField + '-section').remove();
                saveDatasetVersion(collectionId, data.uri, data, field, idField);
              }, function (response) {
                if (response.status === 409) {
                  alert("You can add only one " + idField + " before publishing.");
                }
                else if (response.status === 404) {
                  alert("You can only add " + idField + "s to content that has been published.");
                }
                else {
                  handleApiError(response);
                }
              }
            );
          },
          error: function (response) {
            console.log("Error in creating the version");
            handleApiError(response);
          }
        });
      }
    });
  }
}

function refreshDatasetVersion(collectionId, data, field, idField) {
  var ajaxRequest = [];
  var templateData = $.extend(true, {}, data);
  $(templateData[field]).each(function (index, version) {
    var dfd = $.Deferred();
    if (version.correctionNotice) {
      templateData[field][index].type = true;
    } else {
      templateData[field][index].type = false;
    }
    templateData[field][index].label = version.label;
    dfd.resolve();
    ajaxRequest.push(dfd);
  });

  $.when.apply($, ajaxRequest).then(function () {
    initialiseDatasetVersion(collectionId, data, templateData, field, idField);
  });

}

function initialiseDatasetVersion(collectionId, data, templateData, field, idField) {
  // Load
  var list = templateData[field];
  var correction;
  if (idField === 'correction') {
    correction = true;
  } else {
    correction = false;
  }
  var dataTemplate = {list: list, idField: idField, correction: correction};
  var html = templates.workEditT8CorrectionList(dataTemplate);
  $('#sortable-' + idField).replaceWith(html);
  $(data[field]).each(function (index) {
    dateTmp = data[field][index].updateDate;
    var dateTmpFormatted = $.datepicker.formatDate('dd MM yy', new Date(dateTmp));
    $('#' + idField + '-date_' + index).val(dateTmpFormatted).datepicker({dateFormat: 'dd MM yy'}).on('change', function () {
      data[field][index].updateDate = new Date($('#' + idField + '-date_' + index).datepicker('getDate')).toISOString();
      saveDatasetVersion(collectionId, data.uri, data, field, idField);
    });
    if (idField === 'correction') {
      $('#' + idField + '-edit_' + index).click(function () {
        var editedSectionValue = $('#' + idField + '-markdown_' + index).val();
        var saveContent = function (updatedContent) {
          data[field][index].correctionNotice = updatedContent;
          saveDatasetVersion(collectionId, data.uri, data, field, idField);
        };
        loadMarkdownEditor(editedSectionValue, saveContent, data, 'notEmpty');
      });
    }
    $('#' + idField + '-edit-label_' + index).click(function () {
      var editedSectionValue = $('#' + idField + '-markdown-label_' + index).val();
      var saveContent = function (updatedContent) {
        data[field][index].label = updatedContent;
        saveDatasetVersion(collectionId, data.uri, data, field, idField);
      };
      loadMarkdownEditor(editedSectionValue, saveContent, data);
    });
    // Delete
    $('#' + idField + '-delete_' + index).click(function () {
      var result = confirm("Are you sure you want to delete this " + idField + "?");
      if (result === true) {
        var pathToDelete = data.uri;
        var fileToDelete = data.downloads[0].file;  //Saves always the latest
        var uriToDelete = $(this).parent().children('#' + idField + '-edition_' + index).attr(idField + '-url');
        deleteUnpublishedVersion(collectionId, uriToDelete, function () {
          var position = $(".workspace-edit").scrollTop();
          Florence.globalVars.pagePos = position;
          $(this).parent().remove();
          // delete uploaded file
          deleteContent(collectionId, fileToDelete, function () {
            console.log("File deleted");
          }, function (error) {
            handleApiError(error);
          });
          // delete modified data.json and revert to pubished
          deleteContent(collectionId, pathToDelete, function () {
            loadPageDataIntoEditor(pathToDelete, collectionId);
            refreshPreview(pathToDelete);
          }, function (error) {
            handleApiError(error);
          });
        }, function (response) {
          if (response.status === 404) {
            alert("You cannot delete a " + idField + " that has been published.");
          }
          else {
            handleApiError(response);
          }
        });
      }
    });
  });
}

function saveDatasetVersion(collectionId, path, data, field, idField) {
  postContent(collectionId, path, JSON.stringify(data),
    function () {
      Florence.Editor.isDirty = false;
      refreshDatasetVersion(collectionId, data, field, idField);
      refreshPreview(path);
    },
    function (response) {
      if (response.status === 400) {
        alert("Cannot edit this page. It is already part of another collection.");
      }
      else {
        handleApiError(response);
      }
    }
  );
}

<commit_msg>Delete uploaded files on error<commit_after>/**
 * Manage files associated with datasets. When uploading a file creates a new dataset
 * @param collectionId
 * @param data
 * @param field - JSON data key ('versions')
 * @param idField - HTML id for the template ('version' or 'correction')
 */

function editDatasetVersion(collectionId, data, field, idField) {
  var downloadExtensions, uriUpload, file;
  var lastIndex;
  if (data[field]) {
    lastIndex = data[field].length;
  } else {
    lastIndex = 0;
    data[field] = [];
  }
  var uploadedNotSaved = {uploaded: false, saved: false, fileUrl: "", oldLabel: data.description.versionLabel};
  $(".workspace-edit").scrollTop(Florence.globalVars.pagePos);
  //Add
  if (data.type === 'timeseries_dataset') {
    downloadExtensions = /\.csdb$/;
  } else if (data.type === 'dataset') {
    downloadExtensions = /\.csv$|.xls$|.zip$/;
  }

  var ajaxRequest = [];
  var templateData = $.extend(true, {}, data);
  $(templateData[field]).each(function (index, version) {
    var dfd = $.Deferred();
    if (version.correctionNotice) {
      templateData[field][index].type = true;
    } else {
      templateData[field][index].type = false;
    }
    templateData[field][index].label = version.label;
    dfd.resolve();
    ajaxRequest.push(dfd);
  });

  $.when.apply($, ajaxRequest).then(function () {
    var html = templates.editorCorrection({idField: idField});
    $('#' + idField).replaceWith(html);
    initialiseDatasetVersion(collectionId, data, templateData, field, idField);
  });

  $("#add-" + idField).one('click', function () {
    addTheVersion();
  });

  function addTheVersion() {
    var position = $(".workspace-edit").scrollTop();
    Florence.globalVars.pagePos = position + 200;
    $('#' + idField + '-section').append(
      '
' +
      '  <form id="UploadForm">' +
      '    <textarea class="auto-size" type="text" placeholder="Add a label here (E.g. Revised, Final, etc" id="label"></textarea>' +
      '    <input type="file" title="Select a file and click Submit" name="files">' +
      '
' +
      '    <button type="submit" form="UploadForm" value="submit">Submit</button>' +
      '    <button class="btn-page-cancel" id="file-cancel">Cancel</button>' +
      '  </form>' +
      '

' +
      '

' +
      '
');

    $('#file-cancel').one('click', function (e) {
      e.preventDefault();
      $('#' + lastIndex).remove();
      if (uploadedNotSaved.uploaded === true && uploadedNotSaved.saved === false) {
        data.description.versionLabel = uploadedNotSaved.oldLabel;
        deleteContent(collectionId, uploadedNotSaved.fileUrl,
          onSuccess = function () {
          },
          onError = function (error) {
            handleApiError(error);
          }
        );
      }
      initialiseDatasetVersion(collectionId, data, templateData, field, idField);
    });

    $('#UploadForm').submit(function (e) {
      e.preventDefault();
      e.stopImmediatePropagation();

      var formdata = new FormData();

      function showUploadedItem(source) {
        $('#list').append(source);
      }

      var versionLabel = this[0].value;
      file = this[1].files[0];
      if (!file) {
        alert('Please select a file to upload.');
        return;
      }

      document.getElementById("response").innerHTML = "Uploading . . .";

      var fileNameNoSpace = file.name.replace(/\s*/g, "").toLowerCase();
      uriUpload = data.uri + '/' + fileNameNoSpace;
      var safeUriUpload = checkPathSlashes(uriUpload);

      if (!!file.name.match(downloadExtensions)) {
        showUploadedItem(fileNameNoSpace);
        if (formdata) {
          formdata.append("name", file);
        }
      } else {
        alert('This file type is not supported');
        $('#' + lastIndex).remove();
        editDatasetVersion(collectionId, data, field, idField);
        return;
      }

      if (versionLabel.length < 4) {
        alert("This is not a valid file title");
        return;
      }

      if (formdata) {
        $.ajax({
          url: "/zebedee/content/" + collectionId + "?uri=" + safeUriUpload,
          type: 'POST',
          data: formdata,
          cache: false,
          processData: false,
          contentType: false,
          success: function () {
            document.getElementById("response").innerHTML = "File uploaded successfully";
            uploadedNotSaved.uploaded = true;
            uploadedNotSaved.fileUrl = safeUriUpload;
            // create the new version/correction
            saveNewCorrection(collectionId, data.uri,
              function (response) {
                var tmpDate = (new Date()).toISOString();           // it could use releaseDate
                if (idField === "correction") {
                  data[field].push({
                    correctionNotice: " ",
                    updateDate: data.description.releaseDate,
                    uri: response,
                    label: versionLabel
                  });
                } else {
                  data[field].push({
                    correctionNotice: "",
                    updateDate: data.description.releaseDate,
                    uri: response,
                    label: versionLabel
                  });
                }
                data.downloads = [{file: fileNameNoSpace}];
                data.description.releaseDate = tmpDate;
                data.description.versionLabel = versionLabel;
                uploadedNotSaved.saved = true;
                $("#" + idField).find('.edit-section__content').prepend('
');
                $("#" + idField + '-section').remove();
                saveDatasetVersion(collectionId, data.uri, data, field, idField);
              }, function (response) {
                if (response.status === 409) {
                  alert("You can add only one " + idField + " before publishing.");
                  deleteContent(collectionId, uploadedNotSaved.fileUrl,
                    onSuccess = function () {
                    },
                    onError = function (error) {
                      handleApiError(error);
                    }
                  );
                }
                else if (response.status === 404) {
                  alert("You can only add " + idField + "s to content that has been published.");
                  deleteContent(collectionId, uploadedNotSaved.fileUrl,
                    onSuccess = function () {
                    },
                    onError = function (error) {
                      handleApiError(error);
                    }
                  );
                }
                else {
                  handleApiError(response);
                }
              }
            );
          },
          error: function (response) {
            console.log("Error in uploading this file");
            handleApiError(response);
          }
        });
      }
    });
  }
}

function refreshDatasetVersion(collectionId, data, field, idField) {
  var ajaxRequest = [];
  var templateData = $.extend(true, {}, data);
  $(templateData[field]).each(function (index, version) {
    var dfd = $.Deferred();
    if (version.correctionNotice) {
      templateData[field][index].type = true;
    } else {
      templateData[field][index].type = false;
    }
    templateData[field][index].label = version.label;
    dfd.resolve();
    ajaxRequest.push(dfd);
  });

  $.when.apply($, ajaxRequest).then(function () {
    initialiseDatasetVersion(collectionId, data, templateData, field, idField);
  });

}

function initialiseDatasetVersion(collectionId, data, templateData, field, idField) {
  // Load
  var list = templateData[field];
  var correction;
  if (idField === 'correction') {
    correction = true;
  } else {
    correction = false;
  }
  var dataTemplate = {list: list, idField: idField, correction: correction};
  var html = templates.workEditT8VersionList(dataTemplate);
  $('#sortable-' + idField).replaceWith(html);
  $(data[field]).each(function (index) {
    dateTmp = data[field][index].updateDate;
    var dateTmpFormatted = $.datepicker.formatDate('dd MM yy', new Date(dateTmp));
    $('#' + idField + '-date_' + index).val(dateTmpFormatted).datepicker({dateFormat: 'dd MM yy'}).on('change', function () {
      data[field][index].updateDate = new Date($('#' + idField + '-date_' + index).datepicker('getDate')).toISOString();
      saveDatasetVersion(collectionId, data.uri, data, field, idField);
    });
    if (idField === 'correction') {
      $('#' + idField + '-edit_' + index).click(function () {
        var editedSectionValue = $('#' + idField + '-markdown_' + index).val();
        var saveContent = function (updatedContent) {
          data[field][index].correctionNotice = updatedContent;
          saveDatasetVersion(collectionId, data.uri, data, field, idField);
        };
        loadMarkdownEditor(editedSectionValue, saveContent, data, 'notEmpty');
      });
    }
    $('#' + idField + '-edit-label_' + index).click(function () {
      var editedSectionValue = $('#' + idField + '-markdown-label_' + index).val();
      var saveContent = function (updatedContent) {
        data[field][index].label = updatedContent;
        saveDatasetVersion(collectionId, data.uri, data, field, idField);
      };
      loadMarkdownEditor(editedSectionValue, saveContent, data);
    });
    // Delete
    $('#' + idField + '-delete_' + index).click(function () {
      var result = confirm("Are you sure you want to delete this " + idField + "?");
      if (result === true) {
        var pathToDelete = data.uri;
        var fileToDelete = pathToDelete + data.downloads[0].file;  //Saves always the latest
        var uriToDelete = $(this).parent().children('#' + idField + '-edition_' + index).attr(idField + '-url');
        deleteUnpublishedVersion(collectionId, uriToDelete, function () {
          var position = $(".workspace-edit").scrollTop();
          Florence.globalVars.pagePos = position;
          $(this).parent().remove();
          // delete uploaded file
          deleteContent(collectionId, fileToDelete, function () {
            console.log("File deleted");
          }, function (error) {
            handleApiError(error);
          });
          // delete modified data.json and revert to pubished
          deleteContent(collectionId, pathToDelete, function () {
            loadPageDataIntoEditor(pathToDelete, collectionId);
            refreshPreview(pathToDelete);
          }, function (error) {
            handleApiError(error);
          });
        }, function (response) {
          if (response.status === 404) {
            alert("You cannot delete a " + idField + " that has been published.");
          }
          else {
            handleApiError(response);
          }
        });
      }
    });
  });
}

function saveDatasetVersion(collectionId, path, data, field, idField) {
  postContent(collectionId, path, JSON.stringify(data),
    function () {
      Florence.Editor.isDirty = false;
      refreshDatasetVersion(collectionId, data, field, idField);
      refreshPreview(path);
    },
    function (response) {
      if (response.status === 400) {
        alert("Cannot edit this page. It is already part of another collection.");
      }
      else {
        handleApiError(response);
      }
    }
  );
}

<|endoftext|>


<commit_before>'use strict';

const $ = require('jquery');
const Chart = require('chart.js');

module.exports = function ($http, $location, resultsService) {

	this.averageWaitTime = 0;
	this.averageTasksPerWorker = 0;
	this.workerColorMap = {};
	this.taskColorMap = {};
	this.hexColorList = ['#d9d9d9', '#a6a6a6', '#404040', '#bfbfbf',
    	 '#262626', '#8c8c8c', '#737373', '#595959'];
    this.hexColorIndex = 0;
    this.totalCompletedTasks = 0;

	this.advancedConfig = () => {

        $location.path('/advanced');

    };

	/*
	 * Get unique grayscale for given seed
	 */
	this.getGrayScale = (seed) => {

		// if a color has not been generated for this seed, do so
		if (this.taskColorMap[seed] == null) {

			this.taskColorMap[seed] = this.hexColorList[this.hexColorIndex];
			++this.hexColorIndex;
		}

		// return the color
		return this.taskColorMap[seed];
	};

	this.buildChartData = () => {

		// Already sorted by period of completion
		const tasks = resultsService.getSimulationResults().completedTasks;
		let taskLables = [];
		let taskWaitTime = [];
		let taskBarColors = [];

		// Build label and wait time list for tasks
		let totalWait = 0;
		let currentTaskConfigurationCode = 0;
		let taskConfigurationData = [];
		let startTaskConfigurationIndex = 0;

		for (let i = 0; i < tasks.length; ++i) {

			if (i == 0) {

				// First iteration - set the current config id
				currentTaskConfigurationCode = tasks[i].configHashCode;

			} else if (currentTaskConfigurationCode != tasks[i].configHashCode) {

				// next config reached - update current config id
				currentTaskConfigurationCode = tasks[i].configHashCode;

				// create a config data object
				taskConfigurationData.push({
					colorCode: this.getGrayScale(currentTaskConfigurationCode),
					startPeriod: startTaskConfigurationIndex,
					endPeriod: i,
					totalCompleted: i - startTaskConfigurationIndex
				});

				// update start index
				startTaskConfigurationIndex = i;

			} else if (i == tasks.length - 1) {

				// end of task list - create final task data object
				taskConfigurationData.push({
					colorCode: this.getGrayScale(currentTaskConfigurationCode),
					startPeriod: startTaskConfigurationIndex,
					endPeriod: i,
					totalCompleted: i - startTaskConfigurationIndex
				});

			}

			// add task data to tracked values
			taskLables.push('Arrival: ' + tasks[i].arrivalPeriod);
			taskWaitTime.push(tasks[i].periodsInQueue);
			taskBarColors.push(this.getGrayScale(currentTaskConfigurationCode));
			totalWait += tasks[i].periodsInQueue;
		}

		this.totalCompletedTasks = tasks.length;
		this.averageWaitTime = totalWait / tasks.length;

		// const taskBarChart = new Chart($('#taskBarChart'), {
		//  	type: 'bar',
		//  	data: {
		//  		labels: taskLables,
		// 	 	datasets: [
		// 	 		{
		// 	 			label: 'Wait Time',
		// 	 			data: taskWaitTime,
		// 	 			backgroundColor: taskBarColors
		// 	 		}
		// 	 	]
		//  	},
		//  	options: {
		//  		scales: {
		//  			xAxes: [{
		//  				stacked: true,
		//  				barPercentage: .3,
		//  				display: false
		//  			}],
		//  			yAxes: [{
		//  				scaleLabel: {
		//  					display: true,
		//  					labelString: 'Wait Time'
		//  				}
		//  			}]
		//  		}
		//  	}
		// });

		const taskLineChart = new Chart($('#taskLineChart'), {
		 	type: 'line',
		 	data: {
		 		labels: taskLables,
			 	datasets: [
			 		{
			 			label: 'Wait Time',
			 			data: taskWaitTime
			 		}
			 	]
		 	}
		});

		// get the workers list for the simulation
		const workers = resultsService.getSimulationResults().workers;
		let workerLables = [];
		let workerTotals = [];
		let workerColors =[];

		this.workerColorMap[-1] = '#333333';
		this.workerColorMap[0] = '#808080';
		this.workerColorMap[1] = '#cccccc';

		// Count tasks completed and assign values/labels
		let totalTasksCompleted = 0;
		let tempWorkerLabel = '';
		let srCount = 0;
		let jrCount = 0;
		let stCount = 0;
		for (let i = 0; i < workers.length; ++i) {

			if (workers[i].periodsToCompleteTask == -1) {
				tempWorkerLabel = 'Senior Worker ' + ++srCount;
			} else if (workers[i].periodsToCompleteTask == 1) {
				tempWorkerLabel = 'Junior Worker ' + ++jrCount;
			} else {
				tempWorkerLabel = 'Worker ' + ++stCount;
			}

			workerLables.push(tempWorkerLabel);
			workerTotals.push(workers[i].tasksCompleted);
			workerColors.push(this.workerColorMap[workers[i].periodsToCompleteTask]);
			totalTasksCompleted += workers[i].tasksCompleted;
		}

		// calculate average
		this.averageTasksPerWorker = totalTasksCompleted / workers.length

		const workerPieChart = new Chart($('#workerPieChart'), {
		 	type: 'pie',
		 	data: {
		 		labels: workerLables,
		 		datasets: [
		 			{
		 				label: 'Tasks Completed',
		 				data: workerTotals,
		 				backgroundColor: workerColors
		 			}
		 		]
		 	},
		 	options: {
		 		legend: {
		 			display: false
		 		}
		 	}
		 });

		const workerBarChart = new Chart($('#workerBarChart'), {
		 	type: 'bar',
		 	data: {
		 		labels: workerLables,
		 		datasets: [
		 			{
		 				label: 'Tasks Completed',
		 				data: workerTotals,
		 				backgroundColor: workerColors
		 			}
		 		]
		 	},
		 	options: {
		 		scales: {
		 			yAxes: [{
		 				ticks: {
		 					suggestedMin: 0,
		 					beginAtZero: true
		 				}
		 			}]
		 		}
		 	}
		});

	};

	this.cloneArray = (arrayToClone) => {

	    let clone = [];

	    for(let i = 0; i < arrayToClone.length; ++i) {

	    	clone.push(arrayToClone[i]);

	    }

	    return clone;
	};

	this.buildChartData();

};<commit_msg>now tracks # completed for each task<commit_after>'use strict';

const $ = require('jquery');
const Chart = require('chart.js');

module.exports = function ($http, $location, resultsService) {

	this.totalPeriodsBuffering = 0;
	this.averageWaitTime = 0;
	this.averageTasksPerWorker = 0;
	this.workerColorMap = {};
	this.taskColorMap = {};
	this.hexColorList = ['#d9d9d9', '#a6a6a6', '#404040', '#bfbfbf',
    	 '#262626', '#8c8c8c', '#737373', '#595959'];
    this.hexColorIndex = 0;
    this.totalCompletedTasks = 0;
    this.taskConfigurationData = [];
    this.tempConfigArray = [];

	this.advancedConfig = () => {

        $location.path('/advanced');

    };

	/*
	 * Get unique grayscale for given seed
	 */
	this.getGrayScale = (seed) => {

		// if a color has not been generated for this seed, do so
		if (this.taskColorMap[seed] == null) {

			this.taskColorMap[seed] = this.hexColorList[this.hexColorIndex];
			++this.hexColorIndex;
		}

		// return the color
		return this.taskColorMap[seed];
	};

	this.buildChartData = () => {

		// Already sorted by period of completion
		const tasks = resultsService.getSimulationResults().completedTasks;
		let taskLables = [];
		let taskWaitTime = [];
		let taskBarColors = [];

		// Build label and wait time list for tasks
		let totalWait = 0;
		let currentTaskConfigurationCode = 0;
		let startTaskConfigurationIndex = 0;

		for (let i = 0; i < tasks.length; ++i) {

			if (i == 0) {

				// First iteration - set the current config id
				currentTaskConfigurationCode = tasks[i].configHashCode;
				this.taskConfigurationData.length = 0;

			} else if (currentTaskConfigurationCode != tasks[i].configHashCode) {

				if (this.taskConfigurationData.hasOwnProperty(currentTaskConfigurationCode)) {
					this.taskConfigurationData[currentTaskConfigurationCode]
					  .totalCompleted += (i - startTaskConfigurationIndex);
				} else {

					// create a config data object
					this.taskConfigurationData[currentTaskConfigurationCode] = {
						configurationCode: currentTaskConfigurationCode,
						colorCode: this.getGrayScale(currentTaskConfigurationCode),
						startPeriod: startTaskConfigurationIndex,
						endPeriod: i,
						totalCompleted: i - startTaskConfigurationIndex,
						taskTime: tasks[i].serviceTimeRequired
					};
				}

				// next config reached - update current config id
				currentTaskConfigurationCode = tasks[i].configHashCode;

				// update start index
				startTaskConfigurationIndex = i;

			} else if (i == tasks.length - 1) {

				// end of task list - create final task data object
				if (this.taskConfigurationData.hasOwnProperty(currentTaskConfigurationCode)) {
					this.taskConfigurationData[currentTaskConfigurationCode]
					  .totalCompleted += (i - startTaskConfigurationIndex);
				} else {

					// create a config data object
					this.taskConfigurationData[currentTaskConfigurationCode] ={
						configurationCode: currentTaskConfigurationCode,
						colorCode: this.getGrayScale(currentTaskConfigurationCode),
						startPeriod: startTaskConfigurationIndex,
						endPeriod: i,
						totalCompleted: i - startTaskConfigurationIndex,
						taskTime: tasks[i].serviceTimeRequired
					};
				}
			}

			// add task data to tracked values
			taskLables.push('Arrival: ' + tasks[i].arrivalPeriod);
			taskWaitTime.push(tasks[i].periodsInQueue);
			taskBarColors.push(this.getGrayScale(currentTaskConfigurationCode));
			totalWait += tasks[i].periodsInQueue;
		}

		for (let obj in this.taskConfigurationData) {
			this.tempConfigArray.push(this.taskConfigurationData[obj]);
		}

		this.totalCompletedTasks = tasks.length;
		this.averageWaitTime = totalWait / tasks.length;

		const taskLineChart = new Chart($('#taskLineChart'), {
		 	type: 'line',
		 	data: {
		 		labels: taskLables,
			 	datasets: [
			 		{
			 			label: 'Wait Time',
			 			data: taskWaitTime
			 		}
			 	]
		 	}
		});

		// get the workers list for the simulation
		const workers = resultsService.getSimulationResults().workers;
		let workerLables = [];
		let workerTotals = [];
		let workerColors =[];

		this.workerColorMap[-1] = '#333333';
		this.workerColorMap[0] = '#808080';
		this.workerColorMap[1] = '#cccccc';

		// Count tasks completed and assign values/labels
		let totalTasksCompleted = 0;
		let tempWorkerLabel = '';
		let srCount = 0;
		let jrCount = 0;
		let stCount = 0;
		for (let i = 0; i < workers.length; ++i) {

			if (workers[i].periodsToCompleteTask == -1) {
				tempWorkerLabel = 'Senior Worker ' + ++srCount;
			} else if (workers[i].periodsToCompleteTask == 1) {
				tempWorkerLabel = 'Junior Worker ' + ++jrCount;
			} else {
				tempWorkerLabel = 'Worker ' + ++stCount;
			}

			workerLables.push(tempWorkerLabel);
			workerTotals.push(workers[i].tasksCompleted);
			workerColors.push(this.workerColorMap[workers[i].periodsToCompleteTask]);
			totalTasksCompleted += workers[i].tasksCompleted;
			this.totalPeriodsBuffering += workers[i].totalPeriodsBuffering;
		}

		// calculate average
		this.averageTasksPerWorker = totalTasksCompleted / workers.length

		const workerPieChart = new Chart($('#workerPieChart'), {
		 	type: 'pie',
		 	data: {
		 		labels: workerLables,
		 		datasets: [
		 			{
		 				label: 'Tasks Completed',
		 				data: workerTotals,
		 				backgroundColor: workerColors
		 			}
		 		]
		 	},
		 	options: {
		 		legend: {
		 			display: false
		 		}
		 	}
		 });

		const workerBarChart = new Chart($('#workerBarChart'), {
		 	type: 'bar',
		 	data: {
		 		labels: workerLables,
		 		datasets: [
		 			{
		 				label: 'Tasks Completed',
		 				data: workerTotals,
		 				backgroundColor: workerColors
		 			}
		 		]
		 	},
		 	options: {
		 		scales: {
		 			yAxes: [{
		 				ticks: {
		 					suggestedMin: 0,
		 					beginAtZero: true
		 				}
		 			}]
		 		}
		 	}
		});

	};

	this.cloneArray = (arrayToClone) => {

	    let clone = [];

	    for(let i = 0; i < arrayToClone.length; ++i) {

	    	clone.push(arrayToClone[i]);

	    }

	    return clone;
	};

	this.buildChartData();

};

<|endoftext|>


<commit_before>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;

	self.config = {
		skin: 'cention',
		enterMode: ( CKEDITOR.env.gecko ? CKEDITOR.ENTER_BR : CKEDITOR.ENTER_P),
		shiftEnterMode: CKEDITOR.ENTER_P,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'Cention_SpellCheckLanguageSelector' ],
			[ 'Cention_SpellCheck' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Cention_Image', 'HorizontalRule' ], [ 'PasteFromWord' ], [ 'Youtube' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'Cention_SpellCheckLanguageSelector' ], [ 'Cention_SpellCheck' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Cention_Image', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ], ['Youtube'],
			[ 'Cention_SpellCheckLanguageSelector' ], [ 'Cention_SpellCheck' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [WFServerURI + 'Resources/CSS/jquery.spellchecker.css', WFServerURI + 'Resources/Javascript/ckeditor/contents.css'],
		spellCheckLanguages: []
	};

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = ''+size;
			CKEDITOR.addCss( '.cke_editable{ font-size: '+ size +'; }' );
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = ''+family;
			CKEDITOR.addCss( '.cke_editable{ font-family: '+ family +'; }' );
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
	    if( resize == true )
		self.config.resize_enabled = true;
	    else
		self.config.resize_enabled = false;
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() {};
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.empty = function() {
		if( self.editor ) {
			if( self.editor.getData() )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);
		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}
<commit_msg>Allow native spell checker in web browsers in Ckeditor.<commit_after>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;

	self.config = {
		skin: 'cention',
		enterMode: ( CKEDITOR.env.gecko ? CKEDITOR.ENTER_BR : CKEDITOR.ENTER_P),
		shiftEnterMode: CKEDITOR.ENTER_P,
		disableNativeSpellChecker: false,
		browserContextMenuOnCtrl: true,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'Cention_SpellCheckLanguageSelector' ],
			[ 'Cention_SpellCheck' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Cention_Image', 'HorizontalRule' ], [ 'PasteFromWord' ], [ 'Youtube' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'Cention_SpellCheckLanguageSelector' ], [ 'Cention_SpellCheck' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Cention_Image', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ], ['Youtube'],
			[ 'Cention_SpellCheckLanguageSelector' ], [ 'Cention_SpellCheck' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [WFServerURI + 'Resources/CSS/jquery.spellchecker.css', WFServerURI + 'Resources/Javascript/ckeditor/contents.css'],
		spellCheckLanguages: []
	};

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = ''+size;
			CKEDITOR.addCss( '.cke_editable{ font-size: '+ size +'; }' );
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = ''+family;
			CKEDITOR.addCss( '.cke_editable{ font-family: '+ family +'; }' );
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
	    if( resize == true )
		self.config.resize_enabled = true;
	    else
		self.config.resize_enabled = false;
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() {};
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.empty = function() {
		if( self.editor ) {
			if( self.editor.getData() )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);
		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}
<|endoftext|>


<commit_before>var imgs = document.querySelectorAll('img.avatar');

if (imgs) {
  imgs.forEach(function(e) {
    e.addEventListener('error', defaultAvatar(e));
  });
}

function defaultAvatar(e) {
  e.onerror = null;
  e.src = k.STATIC_URL + 'sumo/img/avatar.png';
}
<commit_msg>Handle avatar if image is missing.<commit_after>var imgs = document.querySelectorAll('img.avatar');

if (imgs) {
  imgs.forEach(function(e) {
    e.addEventListener('error', defaultAvatar);
  });
}

function defaultAvatar() {
  this.onerror = null;
  this.src = k.STATIC_URL + 'sumo/img/avatar.png';
}
<|endoftext|>


<commit_before>describe("Backbone.EntityStore", function () {

  beforeEach(function () {
    var KiwiModel = this.KiwiModel = Backbone.Model.extend({
      url: '/api/kiwis'
    });

    this.KiwiStore = Backbone.EntityStore.extend({
      url: '/api/kiwis',
      model: KiwiModel
    });

    this.entityStore = new this.KiwiStore();
  });

  it("should exist", function () {
    expect(Backbone.EntityStore).toBeDefined();
  });

  describe ("requesting a model", function () {
    beforeEach(function () {
      this.spy = jasmine.createSpy("callback");
    });

    describe("from the collection", function () {
      beforeEach(function () {
        this.entityStore.add(
          { id: 1, name: "kiwi" }
        )
      });

      it("should be able to fetch a model by id", function () {
        var fetchedModel = this.entityStore.request(1);
        fetchedModel.done(this.spy);
        expect(this.spy.mostRecentCall.args[0].get('name')).toBe('kiwi');
      });

      it("should be able to fetch a model by model", function () {
        var model = new this.KiwiModel({id : 1});
        var fetchedModel = this.entityStore.request(model).done(this.spy);
        expect(this.spy.mostRecentCall.args[0].get('name')).toBe('kiwi');
      });

    });

    describe("from the server", function () {
      beforeEach(function () {
        this.xhr = sinon.useFakeXMLHttpRequest();
        var requests = this.requests = []

        this.xhr.onCreate = function (xhr) {
          requests.push(xhr);
        };
      });

      it("should be able to get a model that is not in the collection using an ajax request", function () {
        this.entityStore.request(1).done(this.spy);
        this.requests[0].respond(200, { "Content-type": "application/json" }, '{ "id": 1 }');
        expect(this.spy).toHaveBeenCalled();
      });

      it("it should add the model to the collection after it has been fecthed", function () {
        this.entityStore.request(1);
        this.requests[0].respond(200, { "Content-type": "application/json" }, '{ "id": 1 }');
        expect(this.entityStore.length).toBe(1);
      });

      afterEach(function () {
        this.xhr.restore();
      });
    });
  });

  describe("building a proxy collection", function () {
    beforeEach(function () {
      this.entityStore.add([
        {id: 1, a:1},
        {id: 2, a:2},
        {id: 3, a:3}
      ]);
    });

    describe("mapped collection", function () {

      var mapped;

      beforeEach(function () {
        mapped = this.entityStore.proxyMapped(function (model) {
          return {id: model.id, a: model.get('a')*2};
        });
      });

      it("should be able to build a mapped collection", function () {
        expect(mapped.length).toBe(3);

        expect(mapped.at(0).get('a')).toBe(2);
        expect(mapped.at(1).get('a')).toBe(4);
        expect(mapped.at(2).get('a')).toBe(6);
      });

      it("should be able to add a model to the original collection through the mapped collection", function () {
        mapped.add({a:20});
        expect(this.entityStore.length).toBe(4);
        expect(this.entityStore.at(0).get('a')).toBe(20);
      });

      it("should be able to remove a model on the original collection from the mapped collection", function () {
        var firstModel = mapped.first();
        mapped.remove(firstModel);

        expect(this.entityStore.length).toBe(2);
        expect(this.entityStore.first().id).not.toBe(firstModel.id);
      });
    });
  });
});
<commit_msg>Add specs to confirm that properties are assigned<commit_after>describe("Backbone.EntityStore", function () {

  beforeEach(function () {
    var KiwiModel = this.KiwiModel = Backbone.Model.extend({
      url: '/api/kiwis'
    });

    this.KiwiStore = Backbone.EntityStore.extend({
      url: '/api/kiwis',
      model: KiwiModel
    });

    this.entityStore = new this.KiwiStore();
  });

  describe("startup", function () {
    it("should exist", function () {
      expect(Backbone.EntityStore).toBeDefined();
    });

    it("should be instantiated", function () {
      expect(this.entityStore).toBeTruthy();
    });

    it("should have its properties", function () {
      expect(this.entityStore.url).toBe('/api/kiwis');
      expect(this.entityStore.model).toBe(this.KiwiModel);
    });
  });

  describe ("requesting a model", function () {
    beforeEach(function () {
      this.spy = jasmine.createSpy("callback");
    });

    describe("from the collection", function () {
      beforeEach(function () {
        this.entityStore.add(
          { id: 1, name: "kiwi" }
        )
      });

      it("should be able to fetch a model by id", function () {
        var fetchedModel = this.entityStore.request(1);
        fetchedModel.done(this.spy);
        expect(this.spy.mostRecentCall.args[0].get('name')).toBe('kiwi');
      });

      it("should be able to fetch a model by model", function () {
        var model = new this.KiwiModel({id : 1});
        var fetchedModel = this.entityStore.request(model).done(this.spy);
        expect(this.spy.mostRecentCall.args[0].get('name')).toBe('kiwi');
      });

    });

    describe("from the server", function () {
      beforeEach(function () {
        this.xhr = sinon.useFakeXMLHttpRequest();
        var requests = this.requests = []

        this.xhr.onCreate = function (xhr) {
          requests.push(xhr);
        };
      });

      it("should be able to get a model that is not in the collection using an ajax request", function () {
        this.entityStore.request(1).done(this.spy);
        this.requests[0].respond(200, { "Content-type": "application/json" }, '{ "id": 1 }');
        expect(this.spy).toHaveBeenCalled();
      });

      it("it should add the model to the collection after it has been fecthed", function () {
        this.entityStore.request(1);
        this.requests[0].respond(200, { "Content-type": "application/json" }, '{ "id": 1 }');
        expect(this.entityStore.length).toBe(1);
      });

      afterEach(function () {
        this.xhr.restore();
      });
    });
  });

  describe("building a proxy collection", function () {
    beforeEach(function () {
      this.entityStore.add([
        {id: 1, a:1},
        {id: 2, a:2},
        {id: 3, a:3}
      ]);
    });

    describe("mapped collection", function () {

      var mapped;

      beforeEach(function () {
        mapped = this.entityStore.proxyMapped(function (model) {
          return {id: model.id, a: model.get('a')*2};
        });
      });

      it("should be able to build a mapped collection", function () {
        expect(mapped.length).toBe(3);

        expect(mapped.at(0).get('a')).toBe(2);
        expect(mapped.at(1).get('a')).toBe(4);
        expect(mapped.at(2).get('a')).toBe(6);
      });

      it("should be able to add a model to the original collection through the mapped collection", function () {
        mapped.add({a:20});
        expect(this.entityStore.length).toBe(4);
        expect(this.entityStore.at(0).get('a')).toBe(20);
      });

      it("should be able to remove a model on the original collection from the mapped collection", function () {
        var firstModel = mapped.first();
        mapped.remove(firstModel);

        expect(this.entityStore.length).toBe(2);
        expect(this.entityStore.first().id).not.toBe(firstModel.id);
      });
    });
  });
});
<|endoftext|>