<commit_before>/**
 * jQuery Sparkle (balupton edition) - Simple Rich Effects
 * Copyright (C) 2009 <NAME>
 * http://jquery.com/plugins/project/jquerylightbox_bal
 *
 * This file is part of jQuery Sparkle (balupton edition).
 * 
 * jQuery Sparkle (balupton edition) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * jQuery Sparkle (balupton edition) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with jQuery Lightbox (balupton edition).  If not, see <http://www.gnu.org/licenses/>.
 *
 * @name jquery_sparkle: jquery.sparkle.js
 * @package jQuery Sparkle (balupton edition)
 * @version 1.0.0-dev
 * @date August 11, 2009
 * @category jQuery plugin
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009 <NAME> {@link http://www.balupton.com}
 * @license GNU Affero General Public License - {@link http://www.gnu.org/licenses/agpl.html}
 * @example Visit {@link http://jquery.com/plugins/project/jquerylightbox_bal} for more information.
 */

(function($){
	
	// Debug
	if (typeof console === 'undefined') {
		console = typeof window.console !== 'undefined' ? window.console : {};
	}
	console.log			= console.log 			|| function(){};
	console.debug		= console.debug 		|| console.log;
	console.warn		= console.warn			|| console.log;
	console.error		= console.error			|| function(){var args = [];for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); } alert(args.join("\n")); };
	console.trace		= console.trace			|| console.log;
	console.group		= console.group			|| console.log;
	console.groupEnd	= console.groupEnd		|| console.log;
	console.profile		= console.profile		|| console.log;
	console.profileEnd	= console.profileEnd	|| console.log;
	
	// Prototypes
	Number.prototype.padLeft = String.prototype.padLeft = String.prototype.padLeft ||function(ch, num){
		var val = String(this);
		var re = new RegExp(".{" + num + "}$");
		var pad = "";
		if ( !ch && ch !== 0 ) ch = " ";
		do  {
			pad += ch;
		} while(pad.length < num);
		return re.exec(pad + val)[0];
	};
	Number.prototype.padRight = String.prototype.padRight = String.prototype.padRight ||function(ch, num){
		var val = String(this);
		var re = new RegExp("^.{" + num + "}");
		var pad = "";
		if ( !ch && ch !== 0 ) ch = " ";
		do {
			pad += ch;
		} while (pad.length < num);
		return re.exec(val + pad)[0];
	};
	Date.prototype.setDatetimestr = Date.prototype.setDatetimestr || function(timestamp){
		var pieces = timestamp.split(/[\-\s\:]/g);
		var year = pieces[0];
		var month = pieces[1];
		var day = pieces[2];
		var hour = pieces[3]||0;
		var min = pieces[4]||0;
		var sec = pieces[5]||0;
		this.setUTCFullYear(year,month-1,day);
		this.setUTCHours(hour);
		this.setUTCMinutes(min);
		this.setUTCSeconds(sec);
		return this;
	};
	Date.prototype.setDatestr = Date.prototype.setDatestr || function(timestamp){
		var pieces = timestamp.split(/[\-\s\:]/g);
		var year = pieces[0]||1978;
		var month = pieces[1]||0;
		var day = pieces[2]||1;
		this.setUTCFullYear(year,month-1,day);
		return this;
	};
	Date.prototype.setTimestr = Date.prototype.setTimestr || function(timestamp){
		var pieces = timestamp.split(/[\-\s\:]/g);
		var hour = pieces[0]||0;
		var min = pieces[1]||0;
		var sec = pieces[2]||0;
		this.setUTCHours(hour);
		this.setUTCMinutes(min);
		this.setUTCSeconds(sec);
		return this;
	};
	Date.prototype.getDatetimestr = Date.prototype.getDatetimestr || function() {
		var date = this;
		return date.getDatestr()+' '+date.getTimestr();
	}
	Date.prototype.getDatestr = Date.prototype.getDatestr || function() {
		var date = this;
		var year = date.getUTCFullYear();
		var month = (this.getUTCMonth() + 1).padLeft(0,2);
		var date = this.getUTCDate().padLeft(0,2);
		return year+'-'+month+'-'+date;
	}
	Date.prototype.getTimestr = Date.prototype.getTimestr || function(){
		var date = this;
		var hours = date.getUTCHours().padLeft(0,2);
		var minutes = date.getUTCMinutes().padLeft(0,2);
		var seconds = date.getUTCSeconds().padLeft(0,2);
		return hours+':'+minutes+':'+seconds;
	}
	
	// Prototypes
	$.fn.findAndSelf = $.fn.findAndSelf || function(selector){
		var $this = $(this);
		return $this.find(selector).andSelf().filter(selector);
	};
	$.fn.value = function(value){
		var $input = $(this).firstInput(), result;
		if ( value ) {
			$input.val(value);
			if ( $input.is('select') ) {
				$input.find('option[value=' + value + ']:first').attr('selected', 'selected');
			}
			result = $input;
		} else {
			var val = $input.val();
			if ( $input.is('select') ) {
				val = $input.find('option:selected').text();
			}
			result = val;
		}
		return result;
	};
	$.fn.once = $.fn.once || function(event, data, callback){
		var $this = $(this);
		// Handle
		if ( (callback||false) ) {
			$this.unbind(event, callback);
			$this.bind(event, data, callback);
		} else {
			callback = data;
			$this.unbind(event, callback);
			$this.bind(event, callback);
		}
		// Chain
		return $this;
	};
	
	// jQuery Events
	$.event.special.singleclick = $.event.special.singleclick || {
		setup: function( data, namespaces ) {
			$(this).bind('click', $.event.special.singleclick.handler);
		},
		teardown: function( namespaces ) {
			$(this).unbind('click', $.event.special.singleclick.handler);
		},
		handler: function( event ) {
			// Prepare
			var $el = $(this);
			// Setup
			$el.data('clicking', $el.data('clicking')||'no');
			if ( $el.data('clicking') === 'yes' ) {
				return;
			} else {
				$el.data('clicking', 'yes');
				setTimeout(function(){
					$el.data('clicking', 'no');
				},	500);
			}
			// Fire
			event.type = 'singleclick';
			$.event.handle.apply(this, arguments);
			return true;
		}
	};
	
	// Timepicker
	$.fn.timepicker = $.fn.timepicker || function(options){
		return $(this).each(function(){
			var $input = $(this);
			$input.hide();
			// Prepare
			if ( $input.hasClass('jquery-time-has') ) return $input; // already done
			$input.addClass('jquery-time').addClass('jquery-time-has');
			// Generate
			var $hours = $('<select class="jquery-time-hours" />');
			for ( var hours=12,hour=1; hour<=hours; ++hour ) {
				$hours.append('<option value="'+hour+'">'+hour.padLeft('0',2)+'</option>');
			}
			var $minutes = $('<select class="jquery-time-minutes" />');
			for ( var mins=60,min=5; min<=mins; min+=5) {
				$minutes.append('<option value="'+min+'">'+min.padLeft('0',2)+'</option>');
			}
			var $meridian = $('<select class="jquery-time-meridian" />');
			$meridian.append('<option>am</option>');
			$meridian.append('<option>pm</option>');
			// Defaults
			var value = $input.val();
			var date = new Date(); date.setTimestr(value);
			var hours = date.getUTCHours();
			var minutes = date.getUTCMinutes();
			var meridian = 'am';
			if ( hours > 12 ) {
				hours -= 12; meridian = 'pm';
			}
			// Append
			$meridian.insertAfter($input);
			$minutes.insertAfter($input);
			$hours.insertAfter($input);
			// Apply
			if ( hours > 12 && meridian == 'pm' ) hours -= 12;
			$hours.value(hours);
			$minutes.value(minutes);
			$meridian.value(meridian);
			// Bind
			var updateFunction = function(){
				var hours = parseInt($hours.val(),10);
				var minutes = $minutes.val();
				var meridian = $meridian.val();
				if ( meridian == 'pm' ) hours += 12;
				if ( hours >= 24 ) hours = 0;
				var value = hours.padLeft(0,2)+':'+minutes.padLeft(0,2)+':00';
				$input.val(value).trigger('change');
			};
			$hours.add($minutes).add($meridian).change(updateFunction);
			$input.parent('form:first').submit(updateFunction);
			// Done
			return $input;
		});
	};
	$.fn.datetimepicker = $.fn.datetimepicker || function(){
		return $(this).each(function(){
			var $input = $(this);
			$input.hide();
			// Prepare
			if ( $input.hasClass('jquery-datetime-has') ) return $input; // already done
			$input.addClass('jquery-datetime').addClass('jquery-datetime-has');
			// Create date part
			var $date = $('<input type="text" class="jquery-date"/>');
			var $sep = $('<span class="jquery-datetime-sep"> @ </span>');
			var $time = $('<input type="text" class="jquery-time"/>');
			// Defaults
			var value = $input.val();
			var date = new Date(); date.setDatetimestr(value);
			var datestr = date.getDatestr();
			var timestr = date.getTimestr();
			// Append
			$time.insertAfter($input);
			$sep.insertAfter($input);
			$date.insertAfter($input);
			// Apply
			$date.value(datestr);
			$time.value(timestr);
			// Bind
			var updateFunction = function(){
				var value = $date.val()+' '+$time.val();
				$input.val(value).trigger('change');
			};
			$date.add($time).change(updateFunction);
			// Sparkle
			$date.add($time).sparkle();
			// Done
			return $input;
		});
	};
	
	// BalClass
	$.BalClass = $.BalClass || function(config){
		this.construct(config);
	};
	$.extend($.BalClass.prototype, {
		config: {
			'default': {}
		},
		construct: function(config){
			this.configure(config);
			return true;
		},
		configure: function(config){
			var Me = this;
			Me.config = Me.config||{};
			Me.config = $.extend({},Me.config,config||{}); // we want to clone
			return Me;
		},
		addConfig: function(name, config){
			var Me = this;
			if ( typeof config === 'undefined' ) {
				if ( typeof name === 'object' ) {
					// Series
					for ( var i in name ) {
						Me.applyConfig(i, name[i]);
					}
				}
				return false;
			} else if ( typeof config === 'object' ) {
				// Single
				Me.applyConfig(name, config);
			}
			return Me;
		},
		applyConfig: function(name,config){
			var Me = this;
			Me.config[name] = Me.config[name]||{};
			$.extend(Me.config[name],config||{});
			return Me;
		},
		getConfig: function(name){
			var Me = this;
			if ( typeof name !== 'string' ) {
				return this.config;
			}
			return this.getConfigWith(name);
		},
		getConfigWith: function(name,config){
			var Me = this;
			if ( typeof name !== 'string' ) {
				if ( typeof config === 'undefined' ) {
					config = name;
				}
				name = 'default';
			}
			if ( typeof config !== 'object' ) {
				config = {};
			}
			return $.extend({}, Me.config[name]||{}, config||{}); // clone
		},
		getConfigWithDefault: function(name,config){
			var Me = this;
			return Me.getConfigWith('default',Me.getConfigWith(name,config));
		}
	});
	
	// SparkleClass
	$.SparkleClass = function(config){
		this.construct(config);
	};
	$.extend($.SparkleClass.prototype, $.BalClass.prototype, {
		add: function(name, func, config) {
			var Sparkle = $.Sparkle;
			if ( name === 'object' ) {
				// Series
				for ( var i in name ) {
					Sparkle.add(i, name[i]);
				}
			} else {
				// Individual
				var Extension = {
					config: {},
					extension: false
				};
				// Discover
				if ( typeof func === 'object' && typeof func.config !== 'undefined' ) {
					Extension.config = func.config;
					Extension.extension = func.extension;
				} else {
					Extension.extension = func;
				}
				// Apply
				Sparkle.addConfig(name, Extension);
			}
			return true;
		},
		fn: function(extension){
			var $this = $(this); var Sparkle = $.Sparkle;
			if ( extension ) {
				// Individual
				Sparkle.trigger.apply($this, [extension]);
			} else {
				// Series
				Sparkle.cycle.apply($this, []);
			}
			return $this;
		},
		cycle: function(){
			var $this = $(this); var Sparkle = $.Sparkle;
			var Extensions = Sparkle.getConfig();
			for ( extension in Extensions ) {
				Sparkle.trigger.apply($this, [extension]);
			}
			return $this;
		},
		trigger: function(extension){
			var $this = $(this); var Sparkle = $.Sparkle;
			var Extension = Sparkle.getConfigWithDefault(extension);
			if ( typeof Extension.extension !== 'undefined' ) {
				// We are not just a config object but an actual extension
				return Extension.extension.apply($this, [Sparkle, Extension.config, Extension]);
			}
			return false;
		},
		construct: function(config){
			var Sparkle = this;
			Sparkle.configure(config);
			$(function(){
				$.fn.sparkle = Sparkle.fn;
				$(document.body).sparkle();
			});
			return true;
		}
	});
	
	// Sparkle
	$.Sparkle = new $.SparkleClass({
		'date': {
			config: {
				selector: '.jquery-date',
				dateformat: 'yy-mm-dd'
			},
			extension: function(Sparkle, config){
				var $this = $(this);
				var $item = $this.findAndSelf(config.selector);
				return typeof $item.datepicker === 'undefined' ? $item : $item.datepicker({
					dateFormat: config.dateformat
				});
			}
		},
		'time': {
			config: {
				selector: '.jquery-time',
				timeconvention: 24
			},
			extension: function(Sparkle, config){
				var $this = $(this);
				var $item = $this.findAndSelf(config.selector);
				return typeof $item.timepicker === 'undefined' ? $item : $item.timepicker({
					convention: config.timeconvention
				});
			}
		},
		'datetime': {
			config: {
				selector: '.jquery-datetime',
				dateformat: 'yy-mm-dd',
				timeconvention: 24
			},
			extension: function(Sparkle, config){
				var $this = $(this);
				var $item = $this.findAndSelf(config.selector);
				return typeof $item.datetimepicker === 'undefined' ? $item : $item.datetimepicker({
					dateFormat: config.dateformat,
					convention: config.timeconvention
				});
			}
		},
		'hide-if-empty': {
			config: {
				selector: '.jquery-hide-if-empty:empty'
			},
			extension: function(Sparkle, config) {
				var $this = $(this);
				return $this.findAndSelf(config.selector).hide();
			}
		},
		'hide': {
			config: {
				selector: '.jquery-hide'
			},
			extension: function(Sparkle, config) {
				var $this = $(this);
				return $this.findAndSelf(config.selector).hide();
			}
		},
		'subtle': {
			config: {
				selector: '.jquery-subtle',
				css: {
					'font-size': '80%'
				},
				inSpeed: 200,
				inCss: {
					'opacity': 1
				},
				outSpeed: 400,
				outCss: {
					'opacity': 0.5
				}
			},
			extension: function(Sparkle, config) {
				var $this = $(this);
				var $subtle = $this.findAndSelf(config.selector);
				return $subtle.css(config.css).hover(function() {
					// Over
					$(this).stop(true, false).animate(config.inCss, config.inSpeed);
				}, function() {
					// Out
					$(this).stop(true, false).animate(config.outCss, config.outSpeed);
				});
			}
		},
		'panelshower': {
			config: {
				selectorSwitch: '.jquery-panelshower-switch',
				selectorPanel: '.jquery-panelshower-panel',
				inSpeed: 200,
				outSpeed: 200
			},
			extension: function(Sparkle, config) {<commit_msg>* Updated documentation to reflect new url structure of upcoming balupton.com website<commit_after>/**
 * jQuery Sparkle (balupton edition) - Simple Rich Effects
 * Copyright (C) 2009 <NAME>
 * http://www.balupton.com/projects/jquery-sparkle
 *
 * This file is part of jQuery Sparkle (balupton edition).
 * 
 * jQuery Sparkle (balupton edition) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * jQuery Sparkle (balupton edition) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with jQuery Lightbox (balupton edition).  If not, see <http://www.gnu.org/licenses/>.
 *
 * @name jquery_sparkle: jquery.sparkle.js
 * @package jQuery Sparkle (balupton edition)
 * @version 1.0.0-dev
 * @date August 11, 2009
 * @category jQuery plugin
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2009 <NAME> {@link http://www.balupton.com}
 * @license GNU Affero General Public License - {@link http://www.gnu.org/licenses/agpl.html}
 * @example Visit {@link http://www.balupton.com/projects/jquery-sparkle} for more information.
 */

(function($){
	
	// Debug
	if (typeof console === 'undefined') {
		console = typeof window.console !== 'undefined' ? window.console : {};
	}
	console.log			= console.log 			|| function(){};
	console.debug		= console.debug 		|| console.log;
	console.warn		= console.warn			|| console.log;
	console.error		= console.error			|| function(){var args = [];for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); } alert(args.join("\n")); };
	console.trace		= console.trace			|| console.log;
	console.group		= console.group			|| console.log;
	console.groupEnd	= console.groupEnd		|| console.log;
	console.profile		= console.profile		|| console.log;
	console.profileEnd	= console.profileEnd	|| console.log;
	
	// Prototypes
	Number.prototype.padLeft = String.prototype.padLeft = String.prototype.padLeft ||function(ch, num){
		var val = String(this);
		var re = new RegExp(".{" + num + "}$");
		var pad = "";
		if ( !ch && ch !== 0 ) ch = " ";
		do  {
			pad += ch;
		} while(pad.length < num);
		return re.exec(pad + val)[0];
	};
	Number.prototype.padRight = String.prototype.padRight = String.prototype.padRight ||function(ch, num){
		var val = String(this);
		var re = new RegExp("^.{" + num + "}");
		var pad = "";
		if ( !ch && ch !== 0 ) ch = " ";
		do {
			pad += ch;
		} while (pad.length < num);
		return re.exec(val + pad)[0];
	};
	Date.prototype.setDatetimestr = Date.prototype.setDatetimestr || function(timestamp){
		var pieces = timestamp.split(/[\-\s\:]/g);
		var year = pieces[0];
		var month = pieces[1];
		var day = pieces[2];
		var hour = pieces[3]||0;
		var min = pieces[4]||0;
		var sec = pieces[5]||0;
		this.setUTCFullYear(year,month-1,day);
		this.setUTCHours(hour);
		this.setUTCMinutes(min);
		this.setUTCSeconds(sec);
		return this;
	};
	Date.prototype.setDatestr = Date.prototype.setDatestr || function(timestamp){
		var pieces = timestamp.split(/[\-\s\:]/g);
		var year = pieces[0]||1978;
		var month = pieces[1]||0;
		var day = pieces[2]||1;
		this.setUTCFullYear(year,month-1,day);
		return this;
	};
	Date.prototype.setTimestr = Date.prototype.setTimestr || function(timestamp){
		var pieces = timestamp.split(/[\-\s\:]/g);
		var hour = pieces[0]||0;
		var min = pieces[1]||0;
		var sec = pieces[2]||0;
		this.setUTCHours(hour);
		this.setUTCMinutes(min);
		this.setUTCSeconds(sec);
		return this;
	};
	Date.prototype.getDatetimestr = Date.prototype.getDatetimestr || function() {
		var date = this;
		return date.getDatestr()+' '+date.getTimestr();
	}
	Date.prototype.getDatestr = Date.prototype.getDatestr || function() {
		var date = this;
		var year = date.getUTCFullYear();
		var month = (this.getUTCMonth() + 1).padLeft(0,2);
		var date = this.getUTCDate().padLeft(0,2);
		return year+'-'+month+'-'+date;
	}
	Date.prototype.getTimestr = Date.prototype.getTimestr || function(){
		var date = this;
		var hours = date.getUTCHours().padLeft(0,2);
		var minutes = date.getUTCMinutes().padLeft(0,2);
		var seconds = date.getUTCSeconds().padLeft(0,2);
		return hours+':'+minutes+':'+seconds;
	}
	
	// Prototypes
	$.fn.findAndSelf = $.fn.findAndSelf || function(selector){
		var $this = $(this);
		return $this.find(selector).andSelf().filter(selector);
	};
	$.fn.value = function(value){
		var $input = $(this).firstInput(), result;
		if ( value ) {
			$input.val(value);
			if ( $input.is('select') ) {
				$input.find('option[value=' + value + ']:first').attr('selected', 'selected');
			}
			result = $input;
		} else {
			var val = $input.val();
			if ( $input.is('select') ) {
				val = $input.find('option:selected').text();
			}
			result = val;
		}
		return result;
	};
	$.fn.once = $.fn.once || function(event, data, callback){
		var $this = $(this);
		// Handle
		if ( (callback||false) ) {
			$this.unbind(event, callback);
			$this.bind(event, data, callback);
		} else {
			callback = data;
			$this.unbind(event, callback);
			$this.bind(event, callback);
		}
		// Chain
		return $this;
	};
	
	// jQuery Events
	$.event.special.singleclick = $.event.special.singleclick || {
		setup: function( data, namespaces ) {
			$(this).bind('click', $.event.special.singleclick.handler);
		},
		teardown: function( namespaces ) {
			$(this).unbind('click', $.event.special.singleclick.handler);
		},
		handler: function( event ) {
			// Prepare
			var $el = $(this);
			// Setup
			$el.data('clicking', $el.data('clicking')||'no');
			if ( $el.data('clicking') === 'yes' ) {
				return;
			} else {
				$el.data('clicking', 'yes');
				setTimeout(function(){
					$el.data('clicking', 'no');
				},	500);
			}
			// Fire
			event.type = 'singleclick';
			$.event.handle.apply(this, arguments);
			return true;
		}
	};
	
	// Timepicker
	$.fn.timepicker = $.fn.timepicker || function(options){
		return $(this).each(function(){
			var $input = $(this);
			$input.hide();
			// Prepare
			if ( $input.hasClass('jquery-time-has') ) return $input; // already done
			$input.addClass('jquery-time').addClass('jquery-time-has');
			// Generate
			var $hours = $('<select class="jquery-time-hours" />');
			for ( var hours=12,hour=1; hour<=hours; ++hour ) {
				$hours.append('<option value="'+hour+'">'+hour.padLeft('0',2)+'</option>');
			}
			var $minutes = $('<select class="jquery-time-minutes" />');
			for ( var mins=60,min=5; min<=mins; min+=5) {
				$minutes.append('<option value="'+min+'">'+min.padLeft('0',2)+'</option>');
			}
			var $meridian = $('<select class="jquery-time-meridian" />');
			$meridian.append('<option>am</option>');
			$meridian.append('<option>pm</option>');
			// Defaults
			var value = $input.val();
			var date = new Date(); date.setTimestr(value);
			var hours = date.getUTCHours();
			var minutes = date.getUTCMinutes();
			var meridian = 'am';
			if ( hours > 12 ) {
				hours -= 12; meridian = 'pm';
			}
			// Append
			$meridian.insertAfter($input);
			$minutes.insertAfter($input);
			$hours.insertAfter($input);
			// Apply
			if ( hours > 12 && meridian == 'pm' ) hours -= 12;
			$hours.value(hours);
			$minutes.value(minutes);
			$meridian.value(meridian);
			// Bind
			var updateFunction = function(){
				var hours = parseInt($hours.val(),10);
				var minutes = $minutes.val();
				var meridian = $meridian.val();
				if ( meridian == 'pm' ) hours += 12;
				if ( hours >= 24 ) hours = 0;
				var value = hours.padLeft(0,2)+':'+minutes.padLeft(0,2)+':00';
				$input.val(value).trigger('change');
			};
			$hours.add($minutes).add($meridian).change(updateFunction);
			$input.parent('form:first').submit(updateFunction);
			// Done
			return $input;
		});
	};
	$.fn.datetimepicker = $.fn.datetimepicker || function(){
		return $(this).each(function(){
			var $input = $(this);
			$input.hide();
			// Prepare
			if ( $input.hasClass('jquery-datetime-has') ) return $input; // already done
			$input.addClass('jquery-datetime').addClass('jquery-datetime-has');
			// Create date part
			var $date = $('<input type="text" class="jquery-date"/>');
			var $sep = $('<span class="jquery-datetime-sep"> @ </span>');
			var $time = $('<input type="text" class="jquery-time"/>');
			// Defaults
			var value = $input.val();
			var date = new Date(); date.setDatetimestr(value);
			var datestr = date.getDatestr();
			var timestr = date.getTimestr();
			// Append
			$time.insertAfter($input);
			$sep.insertAfter($input);
			$date.insertAfter($input);
			// Apply
			$date.value(datestr);
			$time.value(timestr);
			// Bind
			var updateFunction = function(){
				var value = $date.val()+' '+$time.val();
				$input.val(value).trigger('change');
			};
			$date.add($time).change(updateFunction);
			// Sparkle
			$date.add($time).sparkle();
			// Done
			return $input;
		});
	};
	
	// BalClass
	$.BalClass = $.BalClass || function(config){
		this.construct(config);
	};
	$.extend($.BalClass.prototype, {
		config: {
			'default': {}
		},
		construct: function(config){
			this.configure(config);
			return true;
		},
		configure: function(config){
			var Me = this;
			Me.config = Me.config||{};
			Me.config = $.extend({},Me.config,config||{}); // we want to clone
			return Me;
		},
		addConfig: function(name, config){
			var Me = this;
			if ( typeof config === 'undefined' ) {
				if ( typeof name === 'object' ) {
					// Series
					for ( var i in name ) {
						Me.applyConfig(i, name[i]);
					}
				}
				return false;
			} else if ( typeof config === 'object' ) {
				// Single
				Me.applyConfig(name, config);
			}
			return Me;
		},
		applyConfig: function(name,config){
			var Me = this;
			Me.config[name] = Me.config[name]||{};
			$.extend(Me.config[name],config||{});
			return Me;
		},
		getConfig: function(name){
			var Me = this;
			if ( typeof name !== 'string' ) {
				return this.config;
			}
			return this.getConfigWith(name);
		},
		getConfigWith: function(name,config){
			var Me = this;
			if ( typeof name !== 'string' ) {
				if ( typeof config === 'undefined' ) {
					config = name;
				}
				name = 'default';
			}
			if ( typeof config !== 'object' ) {
				config = {};
			}
			return $.extend({}, Me.config[name]||{}, config||{}); // clone
		},
		getConfigWithDefault: function(name,config){
			var Me = this;
			return Me.getConfigWith('default',Me.getConfigWith(name,config));
		}
	});
	
	// SparkleClass
	$.SparkleClass = function(config){
		this.construct(config);
	};
	$.extend($.SparkleClass.prototype, $.BalClass.prototype, {
		add: function(name, func, config) {
			var Sparkle = $.Sparkle;
			if ( name === 'object' ) {
				// Series
				for ( var i in name ) {
					Sparkle.add(i, name[i]);
				}
			} else {
				// Individual
				var Extension = {
					config: {},
					extension: false
				};
				// Discover
				if ( typeof func === 'object' && typeof func.config !== 'undefined' ) {
					Extension.config = func.config;
					Extension.extension = func.extension;
				} else {
					Extension.extension = func;
				}
				// Apply
				Sparkle.addConfig(name, Extension);
			}
			return true;
		},
		fn: function(extension){
			var $this = $(this); var Sparkle = $.Sparkle;
			if ( extension ) {
				// Individual
				Sparkle.trigger.apply($this, [extension]);
			} else {
				// Series
				Sparkle.cycle.apply($this, []);
			}
			return $this;
		},
		cycle: function(){
			var $this = $(this); var Sparkle = $.Sparkle;
			var Extensions = Sparkle.getConfig();
			for ( extension in Extensions ) {
				Sparkle.trigger.apply($this, [extension]);
			}
			return $this;
		},
		trigger: function(extension){
			var $this = $(this); var Sparkle = $.Sparkle;
			var Extension = Sparkle.getConfigWithDefault(extension);
			if ( typeof Extension.extension !== 'undefined' ) {
				// We are not just a config object but an actual extension
				return Extension.extension.apply($this, [Sparkle, Extension.config, Extension]);
			}
			return false;
		},
		construct: function(config){
			var Sparkle = this;
			Sparkle.configure(config);
			$(function(){
				$.fn.sparkle = Sparkle.fn;
				$(document.body).sparkle();
			});
			return true;
		}
	});
	
	// Sparkle
	$.Sparkle = new $.SparkleClass({
		'date': {
			config: {
				selector: '.sparkle-date',
				dateformat: 'yy-mm-dd'
			},
			extension: function(Sparkle, config){
				var $this = $(this);
				var $item = $this.findAndSelf(config.selector);
				return typeof $item.datepicker === 'undefined' ? $item : $item.datepicker({
					dateFormat: config.dateformat
				});
			}
		},
		'time': {
			config: {
				selector: '.sparkle-time',
				timeconvention: 24
			},
			extension: function(Sparkle, config){
				var $this = $(this);
				var $item = $this.findAndSelf(config.selector);
				return typeof $item.timepicker === 'undefined' ? $item : $item.timepicker({
					convention: config.timeconvention
				});
			}
		},
		'datetime': {
			config: {
				selector: '.sparkle-datetime',
				dateformat: 'yy-mm-dd',
				timeconvention: 24
			},
			extension: function(Sparkle, config){
				var $this = $(this);
				var $item = $this.findAndSelf(config.selector);
				return typeof $item.datetimepicker === 'undefined' ? $item : $item.datetimepicker({
					dateFormat: config.dateformat,
					convention: config.timeconvention
				});
			}
		},
		'hide-if-empty': {
			config: {
				selector: '.sparkle-hide-if-empty:empty'
			},
			extension: function(Sparkle, config) {
				var $this = $(this);
				return $this.findAndSelf(config.selector).hide();
			}
		},
		'hide': {
			config: {
				selector: '.sparkle-hide'
			},
			extension: function(Sparkle, config) {
				var $this = $(this);
				return $this.findAndSelf(config.selector).hide();
			}
		},
		'subtle': {
			config: {
				selector: '.sparkle-subtle',
				css: {
					'font-size': '80%'
				},
				inSpeed: 200,
				inCss: {
					'opacity': 1
				},
				outSpeed: 400,
				outCss: {
					'opacity': 0.5
				}
			},
			extension: function(Sparkle, config) {
				var $this = $(this);
				var $subtle = $this.findAndSelf(config.selector);
				return $subtle.css(config.css).hover(function() {
					// Over
					$(this).stop(true, false).animate(config.inCss, config.inSpeed);
				}, function() {
					// Out
					$(this).stop(true, false).animate(config.outCss, config.outSpeed);
				});
			}
		},
		'panelshower': {
			config: {
				selectorSwitch: '.sparkle-panelshower-switch',
				selectorPanel: '.sparkle-panelshower-panel',
				inSpeed: 200,
				outSpeed: 200
			},
			extension: function(Sparkle, config) {
{'fraction_non_alphanumeric': 0.18222252173327044, 'fraction_numerical': 0.007817238358379944, 'mean_word_length': 3.199660393377671, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 10, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1187667', 'n_tokens_mistral': 11992, 'n_tokens_neox': 10057, 'n_words': 2197}