diff --git "a/OpenSC2K-master/lib/fomantic-ui-2.7.1/semantic.js" "b/OpenSC2K-master/lib/fomantic-ui-2.7.1/semantic.js"
new file mode 100644--- /dev/null
+++ "b/OpenSC2K-master/lib/fomantic-ui-2.7.1/semantic.js"
@@ -0,0 +1,26933 @@
+ /*
+ * # Fomantic UI - 2.7.1
+ * https://github.com/fomantic/Fomantic-UI
+ * http://fomantic-ui.com/
+ *
+ * Copyright 2014 Contributors
+ * Released under the MIT license
+ * http://opensource.org/licenses/MIT
+ *
+ */
+/*!
+ * # Semantic UI 2.7.1 - Site
+ * http://github.com/semantic-org/semantic-ui/
+ *
+ *
+ * Released under the MIT license
+ * http://opensource.org/licenses/MIT
+ *
+ */
+
+;(function ($, window, document, undefined) {
+
+$.isFunction = $.isFunction || function(obj) {
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+};
+
+$.site = $.fn.site = function(parameters) {
+ var
+ time = new Date().getTime(),
+ performance = [],
+
+ query = arguments[0],
+ methodInvoked = (typeof query == 'string'),
+ queryArguments = [].slice.call(arguments, 1),
+
+ settings = ( $.isPlainObject(parameters) )
+ ? $.extend(true, {}, $.site.settings, parameters)
+ : $.extend({}, $.site.settings),
+
+ namespace = settings.namespace,
+ error = settings.error,
+
+ eventNamespace = '.' + namespace,
+ moduleNamespace = 'module-' + namespace,
+
+ $document = $(document),
+ $module = $document,
+ element = this,
+ instance = $module.data(moduleNamespace),
+
+ module,
+ returnedValue
+ ;
+ module = {
+
+ initialize: function() {
+ module.instantiate();
+ },
+
+ instantiate: function() {
+ module.verbose('Storing instance of site', module);
+ instance = module;
+ $module
+ .data(moduleNamespace, module)
+ ;
+ },
+
+ normalize: function() {
+ module.fix.console();
+ module.fix.requestAnimationFrame();
+ },
+
+ fix: {
+ console: function() {
+ module.debug('Normalizing window.console');
+ if (console === undefined || console.log === undefined) {
+ module.verbose('Console not available, normalizing events');
+ module.disable.console();
+ }
+ if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') {
+ module.verbose('Console group not available, normalizing events');
+ window.console.group = function() {};
+ window.console.groupEnd = function() {};
+ window.console.groupCollapsed = function() {};
+ }
+ if (typeof console.markTimeline == 'undefined') {
+ module.verbose('Mark timeline not available, normalizing events');
+ window.console.markTimeline = function() {};
+ }
+ },
+ consoleClear: function() {
+ module.debug('Disabling programmatic console clearing');
+ window.console.clear = function() {};
+ },
+ requestAnimationFrame: function() {
+ module.debug('Normalizing requestAnimationFrame');
+ if(window.requestAnimationFrame === undefined) {
+ module.debug('RequestAnimationFrame not available, normalizing event');
+ window.requestAnimationFrame = window.requestAnimationFrame
+ || window.mozRequestAnimationFrame
+ || window.webkitRequestAnimationFrame
+ || window.msRequestAnimationFrame
+ || function(callback) { setTimeout(callback, 0); }
+ ;
+ }
+ }
+ },
+
+ moduleExists: function(name) {
+ return ($.fn[name] !== undefined && $.fn[name].settings !== undefined);
+ },
+
+ enabled: {
+ modules: function(modules) {
+ var
+ enabledModules = []
+ ;
+ modules = modules || settings.modules;
+ $.each(modules, function(index, name) {
+ if(module.moduleExists(name)) {
+ enabledModules.push(name);
+ }
+ });
+ return enabledModules;
+ }
+ },
+
+ disabled: {
+ modules: function(modules) {
+ var
+ disabledModules = []
+ ;
+ modules = modules || settings.modules;
+ $.each(modules, function(index, name) {
+ if(!module.moduleExists(name)) {
+ disabledModules.push(name);
+ }
+ });
+ return disabledModules;
+ }
+ },
+
+ change: {
+ setting: function(setting, value, modules, modifyExisting) {
+ modules = (typeof modules === 'string')
+ ? (modules === 'all')
+ ? settings.modules
+ : [modules]
+ : modules || settings.modules
+ ;
+ modifyExisting = (modifyExisting !== undefined)
+ ? modifyExisting
+ : true
+ ;
+ $.each(modules, function(index, name) {
+ var
+ namespace = (module.moduleExists(name))
+ ? $.fn[name].settings.namespace || false
+ : true,
+ $existingModules
+ ;
+ if(module.moduleExists(name)) {
+ module.verbose('Changing default setting', setting, value, name);
+ $.fn[name].settings[setting] = value;
+ if(modifyExisting && namespace) {
+ $existingModules = $(':data(module-' + namespace + ')');
+ if($existingModules.length > 0) {
+ module.verbose('Modifying existing settings', $existingModules);
+ $existingModules[name]('setting', setting, value);
+ }
+ }
+ }
+ });
+ },
+ settings: function(newSettings, modules, modifyExisting) {
+ modules = (typeof modules === 'string')
+ ? [modules]
+ : modules || settings.modules
+ ;
+ modifyExisting = (modifyExisting !== undefined)
+ ? modifyExisting
+ : true
+ ;
+ $.each(modules, function(index, name) {
+ var
+ $existingModules
+ ;
+ if(module.moduleExists(name)) {
+ module.verbose('Changing default setting', newSettings, name);
+ $.extend(true, $.fn[name].settings, newSettings);
+ if(modifyExisting && namespace) {
+ $existingModules = $(':data(module-' + namespace + ')');
+ if($existingModules.length > 0) {
+ module.verbose('Modifying existing settings', $existingModules);
+ $existingModules[name]('setting', newSettings);
+ }
+ }
+ }
+ });
+ }
+ },
+
+ enable: {
+ console: function() {
+ module.console(true);
+ },
+ debug: function(modules, modifyExisting) {
+ modules = modules || settings.modules;
+ module.debug('Enabling debug for modules', modules);
+ module.change.setting('debug', true, modules, modifyExisting);
+ },
+ verbose: function(modules, modifyExisting) {
+ modules = modules || settings.modules;
+ module.debug('Enabling verbose debug for modules', modules);
+ module.change.setting('verbose', true, modules, modifyExisting);
+ }
+ },
+ disable: {
+ console: function() {
+ module.console(false);
+ },
+ debug: function(modules, modifyExisting) {
+ modules = modules || settings.modules;
+ module.debug('Disabling debug for modules', modules);
+ module.change.setting('debug', false, modules, modifyExisting);
+ },
+ verbose: function(modules, modifyExisting) {
+ modules = modules || settings.modules;
+ module.debug('Disabling verbose debug for modules', modules);
+ module.change.setting('verbose', false, modules, modifyExisting);
+ }
+ },
+
+ console: function(enable) {
+ if(enable) {
+ if(instance.cache.console === undefined) {
+ module.error(error.console);
+ return;
+ }
+ module.debug('Restoring console function');
+ window.console = instance.cache.console;
+ }
+ else {
+ module.debug('Disabling console function');
+ instance.cache.console = window.console;
+ window.console = {
+ clear : function(){},
+ error : function(){},
+ group : function(){},
+ groupCollapsed : function(){},
+ groupEnd : function(){},
+ info : function(){},
+ log : function(){},
+ markTimeline : function(){},
+ warn : function(){}
+ };
+ }
+ },
+
+ destroy: function() {
+ module.verbose('Destroying previous site for', $module);
+ $module
+ .removeData(moduleNamespace)
+ ;
+ },
+
+ cache: {},
+
+ setting: function(name, value) {
+ if( $.isPlainObject(name) ) {
+ $.extend(true, settings, name);
+ }
+ else if(value !== undefined) {
+ settings[name] = value;
+ }
+ else {
+ return settings[name];
+ }
+ },
+ internal: function(name, value) {
+ if( $.isPlainObject(name) ) {
+ $.extend(true, module, name);
+ }
+ else if(value !== undefined) {
+ module[name] = value;
+ }
+ else {
+ return module[name];
+ }
+ },
+ debug: function() {
+ if(settings.debug) {
+ if(settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.debug.apply(console, arguments);
+ }
+ }
+ },
+ verbose: function() {
+ if(settings.verbose && settings.debug) {
+ if(settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.verbose.apply(console, arguments);
+ }
+ }
+ },
+ error: function() {
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
+ module.error.apply(console, arguments);
+ },
+ performance: {
+ log: function(message) {
+ var
+ currentTime,
+ executionTime,
+ previousTime
+ ;
+ if(settings.performance) {
+ currentTime = new Date().getTime();
+ previousTime = time || currentTime;
+ executionTime = currentTime - previousTime;
+ time = currentTime;
+ performance.push({
+ 'Element' : element,
+ 'Name' : message[0],
+ 'Arguments' : [].slice.call(message, 1) || '',
+ 'Execution Time' : executionTime
+ });
+ }
+ clearTimeout(module.performance.timer);
+ module.performance.timer = setTimeout(module.performance.display, 500);
+ },
+ display: function() {
+ var
+ title = settings.name + ':',
+ totalTime = 0
+ ;
+ time = false;
+ clearTimeout(module.performance.timer);
+ $.each(performance, function(index, data) {
+ totalTime += data['Execution Time'];
+ });
+ title += ' ' + totalTime + 'ms';
+ if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
+ console.groupCollapsed(title);
+ if(console.table) {
+ console.table(performance);
+ }
+ else {
+ $.each(performance, function(index, data) {
+ console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
+ });
+ }
+ console.groupEnd();
+ }
+ performance = [];
+ }
+ },
+ invoke: function(query, passedArguments, context) {
+ var
+ object = instance,
+ maxDepth,
+ found,
+ response
+ ;
+ passedArguments = passedArguments || queryArguments;
+ context = element || context;
+ if(typeof query == 'string' && object !== undefined) {
+ query = query.split(/[\. ]/);
+ maxDepth = query.length - 1;
+ $.each(query, function(depth, value) {
+ var camelCaseValue = (depth != maxDepth)
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
+ : query
+ ;
+ if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
+ object = object[camelCaseValue];
+ }
+ else if( object[camelCaseValue] !== undefined ) {
+ found = object[camelCaseValue];
+ return false;
+ }
+ else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
+ object = object[value];
+ }
+ else if( object[value] !== undefined ) {
+ found = object[value];
+ return false;
+ }
+ else {
+ module.error(error.method, query);
+ return false;
+ }
+ });
+ }
+ if ( $.isFunction( found ) ) {
+ response = found.apply(context, passedArguments);
+ }
+ else if(found !== undefined) {
+ response = found;
+ }
+ if(Array.isArray(returnedValue)) {
+ returnedValue.push(response);
+ }
+ else if(returnedValue !== undefined) {
+ returnedValue = [returnedValue, response];
+ }
+ else if(response !== undefined) {
+ returnedValue = response;
+ }
+ return found;
+ }
+ };
+
+ if(methodInvoked) {
+ if(instance === undefined) {
+ module.initialize();
+ }
+ module.invoke(query);
+ }
+ else {
+ if(instance !== undefined) {
+ module.destroy();
+ }
+ module.initialize();
+ }
+ return (returnedValue !== undefined)
+ ? returnedValue
+ : this
+ ;
+};
+
+$.site.settings = {
+
+ name : 'Site',
+ namespace : 'site',
+
+ error : {
+ console : 'Console cannot be restored, most likely it was overwritten outside of module',
+ method : 'The method you called is not defined.'
+ },
+
+ debug : false,
+ verbose : false,
+ performance : true,
+
+ modules: [
+ 'accordion',
+ 'api',
+ 'calendar',
+ 'checkbox',
+ 'dimmer',
+ 'dropdown',
+ 'embed',
+ 'form',
+ 'modal',
+ 'nag',
+ 'popup',
+ 'slider',
+ 'rating',
+ 'shape',
+ 'sidebar',
+ 'state',
+ 'sticky',
+ 'tab',
+ 'toast',
+ 'transition',
+ 'visibility',
+ 'visit'
+ ],
+
+ siteNamespace : 'site',
+ namespaceStub : {
+ cache : {},
+ config : {},
+ sections : {},
+ section : {},
+ utilities : {}
+ }
+
+};
+
+// allows for selection of elements with data attributes
+$.extend($.expr[ ":" ], {
+ data: ($.expr.createPseudo)
+ ? $.expr.createPseudo(function(dataName) {
+ return function(elem) {
+ return !!$.data(elem, dataName);
+ };
+ })
+ : function(elem, i, match) {
+ // support: jQuery < 1.8
+ return !!$.data(elem, match[ 3 ]);
+ }
+});
+
+
+})( jQuery, window, document );
+
+/*!
+ * # Semantic UI 2.7.1 - Form Validation
+ * http://github.com/semantic-org/semantic-ui/
+ *
+ *
+ * Released under the MIT license
+ * http://opensource.org/licenses/MIT
+ *
+ */
+
+;(function ($, window, document, undefined) {
+
+'use strict';
+
+$.isFunction = $.isFunction || function(obj) {
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+};
+
+window = (typeof window != 'undefined' && window.Math == Math)
+ ? window
+ : (typeof self != 'undefined' && self.Math == Math)
+ ? self
+ : Function('return this')()
+;
+
+$.fn.form = function(parameters) {
+ var
+ $allModules = $(this),
+ moduleSelector = $allModules.selector || '',
+
+ time = new Date().getTime(),
+ performance = [],
+
+ query = arguments[0],
+ legacyParameters = arguments[1],
+ methodInvoked = (typeof query == 'string'),
+ queryArguments = [].slice.call(arguments, 1),
+ returnedValue
+ ;
+ $allModules
+ .each(function() {
+ var
+ $module = $(this),
+ element = this,
+
+ formErrors = [],
+ keyHeldDown = false,
+
+ // set at run-time
+ $field,
+ $group,
+ $message,
+ $prompt,
+ $submit,
+ $clear,
+ $reset,
+
+ settings,
+ validation,
+
+ metadata,
+ selector,
+ className,
+ regExp,
+ error,
+
+ namespace,
+ moduleNamespace,
+ eventNamespace,
+
+ instance,
+ module
+ ;
+
+ module = {
+
+ initialize: function() {
+
+ // settings grabbed at run time
+ module.get.settings();
+ if(methodInvoked) {
+ if(instance === undefined) {
+ module.instantiate();
+ }
+ module.invoke(query);
+ }
+ else {
+ if(instance !== undefined) {
+ instance.invoke('destroy');
+ }
+ module.verbose('Initializing form validation', $module, settings);
+ module.bindEvents();
+ module.set.defaults();
+ module.instantiate();
+ }
+ },
+
+ instantiate: function() {
+ module.verbose('Storing instance of module', module);
+ instance = module;
+ $module
+ .data(moduleNamespace, module)
+ ;
+ },
+
+ destroy: function() {
+ module.verbose('Destroying previous module', instance);
+ module.removeEvents();
+ $module
+ .removeData(moduleNamespace)
+ ;
+ },
+
+ refresh: function() {
+ module.verbose('Refreshing selector cache');
+ $field = $module.find(selector.field);
+ $group = $module.find(selector.group);
+ $message = $module.find(selector.message);
+ $prompt = $module.find(selector.prompt);
+
+ $submit = $module.find(selector.submit);
+ $clear = $module.find(selector.clear);
+ $reset = $module.find(selector.reset);
+ },
+
+ submit: function() {
+ module.verbose('Submitting form', $module);
+ $module
+ .submit()
+ ;
+ },
+
+ attachEvents: function(selector, action) {
+ action = action || 'submit';
+ $(selector)
+ .on('click' + eventNamespace, function(event) {
+ module[action]();
+ event.preventDefault();
+ })
+ ;
+ },
+
+ bindEvents: function() {
+ module.verbose('Attaching form events');
+ $module
+ .on('submit' + eventNamespace, module.validate.form)
+ .on('blur' + eventNamespace, selector.field, module.event.field.blur)
+ .on('click' + eventNamespace, selector.submit, module.submit)
+ .on('click' + eventNamespace, selector.reset, module.reset)
+ .on('click' + eventNamespace, selector.clear, module.clear)
+ ;
+ if(settings.keyboardShortcuts) {
+ $module
+ .on('keydown' + eventNamespace, selector.field, module.event.field.keydown)
+ ;
+ }
+ $field
+ .each(function() {
+ var
+ $input = $(this),
+ type = $input.prop('type'),
+ inputEvent = module.get.changeEvent(type, $input)
+ ;
+ $(this)
+ .on(inputEvent + eventNamespace, module.event.field.change)
+ ;
+ })
+ ;
+ },
+
+ clear: function() {
+ $field
+ .each(function () {
+ var
+ $field = $(this),
+ $element = $field.parent(),
+ $fieldGroup = $field.closest($group),
+ $prompt = $fieldGroup.find(selector.prompt),
+ defaultValue = $field.data(metadata.defaultValue) || '',
+ isCheckbox = $element.is(selector.uiCheckbox),
+ isDropdown = $element.is(selector.uiDropdown),
+ isErrored = $fieldGroup.hasClass(className.error)
+ ;
+ if(isErrored) {
+ module.verbose('Resetting error on field', $fieldGroup);
+ $fieldGroup.removeClass(className.error);
+ $prompt.remove();
+ }
+ if(isDropdown) {
+ module.verbose('Resetting dropdown value', $element, defaultValue);
+ $element.dropdown('clear');
+ }
+ else if(isCheckbox) {
+ $field.prop('checked', false);
+ }
+ else {
+ module.verbose('Resetting field value', $field, defaultValue);
+ $field.val('');
+ }
+ })
+ ;
+ },
+
+ reset: function() {
+ $field
+ .each(function () {
+ var
+ $field = $(this),
+ $element = $field.parent(),
+ $fieldGroup = $field.closest($group),
+ $prompt = $fieldGroup.find(selector.prompt),
+ defaultValue = $field.data(metadata.defaultValue),
+ isCheckbox = $element.is(selector.uiCheckbox),
+ isDropdown = $element.is(selector.uiDropdown),
+ isErrored = $fieldGroup.hasClass(className.error)
+ ;
+ if(defaultValue === undefined) {
+ return;
+ }
+ if(isErrored) {
+ module.verbose('Resetting error on field', $fieldGroup);
+ $fieldGroup.removeClass(className.error);
+ $prompt.remove();
+ }
+ if(isDropdown) {
+ module.verbose('Resetting dropdown value', $element, defaultValue);
+ $element.dropdown('restore defaults');
+ }
+ else if(isCheckbox) {
+ module.verbose('Resetting checkbox value', $element, defaultValue);
+ $field.prop('checked', defaultValue);
+ }
+ else {
+ module.verbose('Resetting field value', $field, defaultValue);
+ $field.val(defaultValue);
+ }
+ })
+ ;
+ },
+
+ determine: {
+ isValid: function() {
+ var
+ allValid = true
+ ;
+ $.each(validation, function(fieldName, field) {
+ if( !( module.validate.field(field, fieldName, true) ) ) {
+ allValid = false;
+ }
+ });
+ return allValid;
+ }
+ },
+
+ is: {
+ bracketedRule: function(rule) {
+ return (rule.type && rule.type.match(settings.regExp.bracket));
+ },
+ shorthandFields: function(fields) {
+ var
+ fieldKeys = Object.keys(fields),
+ firstRule = fields[fieldKeys[0]]
+ ;
+ return module.is.shorthandRules(firstRule);
+ },
+ // duck type rule test
+ shorthandRules: function(rules) {
+ return (typeof rules == 'string' || Array.isArray(rules));
+ },
+ empty: function($field) {
+ if(!$field || $field.length === 0) {
+ return true;
+ }
+ else if($field.is('input[type="checkbox"]')) {
+ return !$field.is(':checked');
+ }
+ else {
+ return module.is.blank($field);
+ }
+ },
+ blank: function($field) {
+ return $.trim($field.val()) === '';
+ },
+ valid: function(field) {
+ var
+ allValid = true
+ ;
+ if(field) {
+ module.verbose('Checking if field is valid', field);
+ return module.validate.field(validation[field], field, false);
+ }
+ else {
+ module.verbose('Checking if form is valid');
+ $.each(validation, function(fieldName, field) {
+ if( !module.is.valid(fieldName) ) {
+ allValid = false;
+ }
+ });
+ return allValid;
+ }
+ }
+ },
+
+ removeEvents: function() {
+ $module
+ .off(eventNamespace)
+ ;
+ $field
+ .off(eventNamespace)
+ ;
+ $submit
+ .off(eventNamespace)
+ ;
+ $field
+ .off(eventNamespace)
+ ;
+ },
+
+ event: {
+ field: {
+ keydown: function(event) {
+ var
+ $field = $(this),
+ key = event.which,
+ isInput = $field.is(selector.input),
+ isCheckbox = $field.is(selector.checkbox),
+ isInDropdown = ($field.closest(selector.uiDropdown).length > 0),
+ keyCode = {
+ enter : 13,
+ escape : 27
+ }
+ ;
+ if( key == keyCode.escape) {
+ module.verbose('Escape key pressed blurring field');
+ $field
+ .blur()
+ ;
+ }
+ if(!event.ctrlKey && key == keyCode.enter && isInput && !isInDropdown && !isCheckbox) {
+ if(!keyHeldDown) {
+ $field
+ .one('keyup' + eventNamespace, module.event.field.keyup)
+ ;
+ module.submit();
+ module.debug('Enter pressed on input submitting form');
+ }
+ keyHeldDown = true;
+ }
+ },
+ keyup: function() {
+ keyHeldDown = false;
+ },
+ blur: function(event) {
+ var
+ $field = $(this),
+ $fieldGroup = $field.closest($group),
+ validationRules = module.get.validation($field)
+ ;
+ if( $fieldGroup.hasClass(className.error) ) {
+ module.debug('Revalidating field', $field, validationRules);
+ if(validationRules) {
+ module.validate.field( validationRules );
+ }
+ }
+ else if(settings.on == 'blur') {
+ if(validationRules) {
+ module.validate.field( validationRules );
+ }
+ }
+ },
+ change: function(event) {
+ var
+ $field = $(this),
+ $fieldGroup = $field.closest($group),
+ validationRules = module.get.validation($field)
+ ;
+ if(validationRules && (settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) )) {
+ clearTimeout(module.timer);
+ module.timer = setTimeout(function() {
+ module.debug('Revalidating field', $field, module.get.validation($field));
+ module.validate.field( validationRules );
+ }, settings.delay);
+ }
+ }
+ }
+
+ },
+
+ get: {
+ ancillaryValue: function(rule) {
+ if(!rule.type || (!rule.value && !module.is.bracketedRule(rule))) {
+ return false;
+ }
+ return (rule.value !== undefined)
+ ? rule.value
+ : rule.type.match(settings.regExp.bracket)[1] + ''
+ ;
+ },
+ ruleName: function(rule) {
+ if( module.is.bracketedRule(rule) ) {
+ return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], '');
+ }
+ return rule.type;
+ },
+ changeEvent: function(type, $input) {
+ if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) {
+ return 'change';
+ }
+ else {
+ return module.get.inputEvent();
+ }
+ },
+ inputEvent: function() {
+ return (document.createElement('input').oninput !== undefined)
+ ? 'input'
+ : (document.createElement('input').onpropertychange !== undefined)
+ ? 'propertychange'
+ : 'keyup'
+ ;
+ },
+ fieldsFromShorthand: function(fields) {
+ var
+ fullFields = {}
+ ;
+ $.each(fields, function(name, rules) {
+ if(typeof rules == 'string') {
+ rules = [rules];
+ }
+ fullFields[name] = {
+ rules: []
+ };
+ $.each(rules, function(index, rule) {
+ fullFields[name].rules.push({ type: rule });
+ });
+ });
+ return fullFields;
+ },
+ prompt: function(rule, field) {
+ var
+ ruleName = module.get.ruleName(rule),
+ ancillary = module.get.ancillaryValue(rule),
+ $field = module.get.field(field.identifier),
+ value = $field.val(),
+ prompt = $.isFunction(rule.prompt)
+ ? rule.prompt(value)
+ : rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule,
+ requiresValue = (prompt.search('{value}') !== -1),
+ requiresName = (prompt.search('{name}') !== -1),
+ $label,
+ name
+ ;
+ if(requiresValue) {
+ prompt = prompt.replace('{value}', $field.val());
+ }
+ if(requiresName) {
+ $label = $field.closest(selector.group).find('label').eq(0);
+ name = ($label.length == 1)
+ ? $label.text()
+ : $field.prop('placeholder') || settings.text.unspecifiedField
+ ;
+ prompt = prompt.replace('{name}', name);
+ }
+ prompt = prompt.replace('{identifier}', field.identifier);
+ prompt = prompt.replace('{ruleValue}', ancillary);
+ if(!rule.prompt) {
+ module.verbose('Using default validation prompt for type', prompt, ruleName);
+ }
+ return prompt;
+ },
+ settings: function() {
+ if($.isPlainObject(parameters)) {
+ var
+ keys = Object.keys(parameters),
+ isLegacySettings = (keys.length > 0)
+ ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined)
+ : false,
+ ruleKeys
+ ;
+ if(isLegacySettings) {
+ // 1.x (ducktyped)
+ settings = $.extend(true, {}, $.fn.form.settings, legacyParameters);
+ validation = $.extend({}, $.fn.form.settings.defaults, parameters);
+ module.error(settings.error.oldSyntax, element);
+ module.verbose('Extending settings from legacy parameters', validation, settings);
+ }
+ else {
+ // 2.x
+ if(parameters.fields && module.is.shorthandFields(parameters.fields)) {
+ parameters.fields = module.get.fieldsFromShorthand(parameters.fields);
+ }
+ settings = $.extend(true, {}, $.fn.form.settings, parameters);
+ validation = $.extend({}, $.fn.form.settings.defaults, settings.fields);
+ module.verbose('Extending settings', validation, settings);
+ }
+ }
+ else {
+ settings = $.fn.form.settings;
+ validation = $.fn.form.settings.defaults;
+ module.verbose('Using default form validation', validation, settings);
+ }
+
+ // shorthand
+ namespace = settings.namespace;
+ metadata = settings.metadata;
+ selector = settings.selector;
+ className = settings.className;
+ regExp = settings.regExp;
+ error = settings.error;
+ moduleNamespace = 'module-' + namespace;
+ eventNamespace = '.' + namespace;
+
+ // grab instance
+ instance = $module.data(moduleNamespace);
+
+ // refresh selector cache
+ module.refresh();
+ },
+ field: function(identifier) {
+ module.verbose('Finding field with identifier', identifier);
+ identifier = module.escape.string(identifier);
+ var t;
+ if((t=$field.filter('#' + identifier)).length > 0 ) {
+ return t;
+ }
+ if((t=$field.filter('[name="' + identifier +'"]')).length > 0 ) {
+ return t;
+ }
+ if((t=$field.filter('[name="' + identifier +'[]"]')).length > 0 ) {
+ return t;
+ }
+ if((t=$field.filter('[data-' + metadata.validate + '="'+ identifier +'"]')).length > 0 ) {
+ return t;
+ }
+ return $('');
+ },
+ fields: function(fields) {
+ var
+ $fields = $()
+ ;
+ $.each(fields, function(index, name) {
+ $fields = $fields.add( module.get.field(name) );
+ });
+ return $fields;
+ },
+ validation: function($field) {
+ var
+ fieldValidation,
+ identifier
+ ;
+ if(!validation) {
+ return false;
+ }
+ $.each(validation, function(fieldName, field) {
+ identifier = field.identifier || fieldName;
+ if( module.get.field(identifier)[0] == $field[0] ) {
+ field.identifier = identifier;
+ fieldValidation = field;
+ }
+ });
+ return fieldValidation || false;
+ },
+ value: function (field) {
+ var
+ fields = [],
+ results
+ ;
+ fields.push(field);
+ results = module.get.values.call(element, fields);
+ return results[field];
+ },
+ values: function (fields) {
+ var
+ $fields = Array.isArray(fields)
+ ? module.get.fields(fields)
+ : $field,
+ values = {}
+ ;
+ $fields.each(function(index, field) {
+ var
+ $field = $(field),
+ type = $field.prop('type'),
+ name = $field.prop('name'),
+ value = $field.val(),
+ isCheckbox = $field.is(selector.checkbox),
+ isRadio = $field.is(selector.radio),
+ isMultiple = (name.indexOf('[]') !== -1),
+ isChecked = (isCheckbox)
+ ? $field.is(':checked')
+ : false
+ ;
+ if(name) {
+ if(isMultiple) {
+ name = name.replace('[]', '');
+ if(!values[name]) {
+ values[name] = [];
+ }
+ if(isCheckbox) {
+ if(isChecked) {
+ values[name].push(value || true);
+ }
+ else {
+ values[name].push(false);
+ }
+ }
+ else {
+ values[name].push(value);
+ }
+ }
+ else {
+ if(isRadio) {
+ if(values[name] === undefined || values[name] == false) {
+ values[name] = (isChecked)
+ ? value || true
+ : false
+ ;
+ }
+ }
+ else if(isCheckbox) {
+ if(isChecked) {
+ values[name] = value || true;
+ }
+ else {
+ values[name] = false;
+ }
+ }
+ else {
+ values[name] = value;
+ }
+ }
+ }
+ });
+ return values;
+ }
+ },
+
+ has: {
+
+ field: function(identifier) {
+ module.verbose('Checking for existence of a field with identifier', identifier);
+ identifier = module.escape.string(identifier);
+ if(typeof identifier !== 'string') {
+ module.error(error.identifier, identifier);
+ }
+ if($field.filter('#' + identifier).length > 0 ) {
+ return true;
+ }
+ else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
+ return true;
+ }
+ else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
+ return true;
+ }
+ return false;
+ }
+
+ },
+
+ escape: {
+ string: function(text) {
+ text = String(text);
+ return text.replace(regExp.escape, '\\$&');
+ }
+ },
+
+ add: {
+ // alias
+ rule: function(name, rules) {
+ module.add.field(name, rules);
+ },
+ field: function(name, rules) {
+ var
+ newValidation = {}
+ ;
+ if(module.is.shorthandRules(rules)) {
+ rules = Array.isArray(rules)
+ ? rules
+ : [rules]
+ ;
+ newValidation[name] = {
+ rules: []
+ };
+ $.each(rules, function(index, rule) {
+ newValidation[name].rules.push({ type: rule });
+ });
+ }
+ else {
+ newValidation[name] = rules;
+ }
+ validation = $.extend({}, validation, newValidation);
+ module.debug('Adding rules', newValidation, validation);
+ },
+ fields: function(fields) {
+ var
+ newValidation
+ ;
+ if(fields && module.is.shorthandFields(fields)) {
+ newValidation = module.get.fieldsFromShorthand(fields);
+ }
+ else {
+ newValidation = fields;
+ }
+ validation = $.extend({}, validation, newValidation);
+ },
+ prompt: function(identifier, errors) {
+ var
+ $field = module.get.field(identifier),
+ $fieldGroup = $field.closest($group),
+ $prompt = $fieldGroup.children(selector.prompt),
+ promptExists = ($prompt.length !== 0)
+ ;
+ errors = (typeof errors == 'string')
+ ? [errors]
+ : errors
+ ;
+ module.verbose('Adding field error state', identifier);
+ $fieldGroup
+ .addClass(className.error)
+ ;
+ if(settings.inline) {
+ if(!promptExists) {
+ $prompt = settings.templates.prompt(errors);
+ $prompt
+ .appendTo($fieldGroup)
+ ;
+ }
+ $prompt
+ .html(errors[0])
+ ;
+ if(!promptExists) {
+ if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
+ module.verbose('Displaying error with css transition', settings.transition);
+ $prompt.transition(settings.transition + ' in', settings.duration);
+ }
+ else {
+ module.verbose('Displaying error with fallback javascript animation');
+ $prompt
+ .fadeIn(settings.duration)
+ ;
+ }
+ }
+ else {
+ module.verbose('Inline errors are disabled, no inline error added', identifier);
+ }
+ }
+ },
+ errors: function(errors) {
+ module.debug('Adding form error messages', errors);
+ module.set.error();
+ $message
+ .html( settings.templates.error(errors) )
+ ;
+ }
+ },
+
+ remove: {
+ rule: function(field, rule) {
+ var
+ rules = Array.isArray(rule)
+ ? rule
+ : [rule]
+ ;
+ if(rule == undefined) {
+ module.debug('Removed all rules');
+ validation[field].rules = [];
+ return;
+ }
+ if(validation[field] == undefined || !Array.isArray(validation[field].rules)) {
+ return;
+ }
+ $.each(validation[field].rules, function(index, rule) {
+ if(rules.indexOf(rule.type) !== -1) {
+ module.debug('Removed rule', rule.type);
+ validation[field].rules.splice(index, 1);
+ }
+ });
+ },
+ field: function(field) {
+ var
+ fields = Array.isArray(field)
+ ? field
+ : [field]
+ ;
+ $.each(fields, function(index, field) {
+ module.remove.rule(field);
+ });
+ },
+ // alias
+ rules: function(field, rules) {
+ if(Array.isArray(field)) {
+ $.each(fields, function(index, field) {
+ module.remove.rule(field, rules);
+ });
+ }
+ else {
+ module.remove.rule(field, rules);
+ }
+ },
+ fields: function(fields) {
+ module.remove.field(fields);
+ },
+ prompt: function(identifier) {
+ var
+ $field = module.get.field(identifier),
+ $fieldGroup = $field.closest($group),
+ $prompt = $fieldGroup.children(selector.prompt)
+ ;
+ $fieldGroup
+ .removeClass(className.error)
+ ;
+ if(settings.inline && $prompt.is(':visible')) {
+ module.verbose('Removing prompt for field', identifier);
+ if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
+ $prompt.transition(settings.transition + ' out', settings.duration, function() {
+ $prompt.remove();
+ });
+ }
+ else {
+ $prompt
+ .fadeOut(settings.duration, function(){
+ $prompt.remove();
+ })
+ ;
+ }
+ }
+ }
+ },
+
+ set: {
+ success: function() {
+ $module
+ .removeClass(className.error)
+ .addClass(className.success)
+ ;
+ },
+ defaults: function () {
+ $field
+ .each(function () {
+ var
+ $field = $(this),
+ isCheckbox = ($field.filter(selector.checkbox).length > 0),
+ value = (isCheckbox)
+ ? $field.is(':checked')
+ : $field.val()
+ ;
+ $field.data(metadata.defaultValue, value);
+ })
+ ;
+ },
+ error: function() {
+ $module
+ .removeClass(className.success)
+ .addClass(className.error)
+ ;
+ },
+ value: function (field, value) {
+ var
+ fields = {}
+ ;
+ fields[field] = value;
+ return module.set.values.call(element, fields);
+ },
+ values: function (fields) {
+ if($.isEmptyObject(fields)) {
+ return;
+ }
+ $.each(fields, function(key, value) {
+ var
+ $field = module.get.field(key),
+ $element = $field.parent(),
+ isMultiple = Array.isArray(value),
+ isCheckbox = $element.is(selector.uiCheckbox),
+ isDropdown = $element.is(selector.uiDropdown),
+ isRadio = ($field.is(selector.radio) && isCheckbox),
+ fieldExists = ($field.length > 0),
+ $multipleField
+ ;
+ if(fieldExists) {
+ if(isMultiple && isCheckbox) {
+ module.verbose('Selecting multiple', value, $field);
+ $element.checkbox('uncheck');
+ $.each(value, function(index, value) {
+ $multipleField = $field.filter('[value="' + value + '"]');
+ $element = $multipleField.parent();
+ if($multipleField.length > 0) {
+ $element.checkbox('check');
+ }
+ });
+ }
+ else if(isRadio) {
+ module.verbose('Selecting radio value', value, $field);
+ $field.filter('[value="' + value + '"]')
+ .parent(selector.uiCheckbox)
+ .checkbox('check')
+ ;
+ }
+ else if(isCheckbox) {
+ module.verbose('Setting checkbox value', value, $element);
+ if(value === true) {
+ $element.checkbox('check');
+ }
+ else {
+ $element.checkbox('uncheck');
+ }
+ }
+ else if(isDropdown) {
+ module.verbose('Setting dropdown value', value, $element);
+ $element.dropdown('set selected', value);
+ }
+ else {
+ module.verbose('Setting field value', value, $field);
+ $field.val(value);
+ }
+ }
+ });
+ }
+ },
+
+ validate: {
+
+ form: function(event, ignoreCallbacks) {
+ var
+ values = module.get.values(),
+ apiRequest
+ ;
+
+ // input keydown event will fire submit repeatedly by browser default
+ if(keyHeldDown) {
+ return false;
+ }
+
+ // reset errors
+ formErrors = [];
+ if( module.determine.isValid() ) {
+ module.debug('Form has no validation errors, submitting');
+ module.set.success();
+ if(ignoreCallbacks !== true) {
+ return settings.onSuccess.call(element, event, values);
+ }
+ }
+ else {
+ module.debug('Form has errors');
+ module.set.error();
+ if(!settings.inline) {
+ module.add.errors(formErrors);
+ }
+ // prevent ajax submit
+ if($module.data('moduleApi') !== undefined) {
+ event.stopImmediatePropagation();
+ }
+ if(ignoreCallbacks !== true) {
+ return settings.onFailure.call(element, formErrors, values);
+ }
+ }
+ },
+
+ // takes a validation object and returns whether field passes validation
+ field: function(field, fieldName, showErrors) {
+ showErrors = (showErrors !== undefined)
+ ? showErrors
+ : true
+ ;
+ if(typeof field == 'string') {
+ module.verbose('Validating field', field);
+ fieldName = field;
+ field = validation[field];
+ }
+ var
+ identifier = field.identifier || fieldName,
+ $field = module.get.field(identifier),
+ $dependsField = (field.depends)
+ ? module.get.field(field.depends)
+ : false,
+ fieldValid = true,
+ fieldErrors = []
+ ;
+ if(!field.identifier) {
+ module.debug('Using field name as identifier', identifier);
+ field.identifier = identifier;
+ }
+ if($field.prop('disabled')) {
+ module.debug('Field is disabled. Skipping', identifier);
+ fieldValid = true;
+ }
+ else if(field.optional && module.is.blank($field)){
+ module.debug('Field is optional and blank. Skipping', identifier);
+ fieldValid = true;
+ }
+ else if(field.depends && module.is.empty($dependsField)) {
+ module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField);
+ fieldValid = true;
+ }
+ else if(field.rules !== undefined) {
+ $.each(field.rules, function(index, rule) {
+ if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) {
+ module.debug('Field is invalid', identifier, rule.type);
+ fieldErrors.push(module.get.prompt(rule, field));
+ fieldValid = false;
+ }
+ });
+ }
+ if(fieldValid) {
+ if(showErrors) {
+ module.remove.prompt(identifier, fieldErrors);
+ settings.onValid.call($field);
+ }
+ }
+ else {
+ if(showErrors) {
+ formErrors = formErrors.concat(fieldErrors);
+ module.add.prompt(identifier, fieldErrors);
+ settings.onInvalid.call($field, fieldErrors);
+ }
+ return false;
+ }
+ return true;
+ },
+
+ // takes validation rule and returns whether field passes rule
+ rule: function(field, rule) {
+ var
+ $field = module.get.field(field.identifier),
+ type = rule.type,
+ value = $field.val(),
+ isValid = true,
+ ancillary = module.get.ancillaryValue(rule),
+ ruleName = module.get.ruleName(rule),
+ ruleFunction = settings.rules[ruleName]
+ ;
+ if( !$.isFunction(ruleFunction) ) {
+ module.error(error.noRule, ruleName);
+ return;
+ }
+ // cast to string avoiding encoding special values
+ value = (value === undefined || value === '' || value === null)
+ ? ''
+ : (settings.shouldTrim) ? $.trim(value + '') : String(value + '')
+ ;
+ return ruleFunction.call($field, value, ancillary);
+ }
+ },
+
+ setting: function(name, value) {
+ if( $.isPlainObject(name) ) {
+ $.extend(true, settings, name);
+ }
+ else if(value !== undefined) {
+ settings[name] = value;
+ }
+ else {
+ return settings[name];
+ }
+ },
+ internal: function(name, value) {
+ if( $.isPlainObject(name) ) {
+ $.extend(true, module, name);
+ }
+ else if(value !== undefined) {
+ module[name] = value;
+ }
+ else {
+ return module[name];
+ }
+ },
+ debug: function() {
+ if(!settings.silent && settings.debug) {
+ if(settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.debug.apply(console, arguments);
+ }
+ }
+ },
+ verbose: function() {
+ if(!settings.silent && settings.verbose && settings.debug) {
+ if(settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.verbose.apply(console, arguments);
+ }
+ }
+ },
+ error: function() {
+ if(!settings.silent) {
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
+ module.error.apply(console, arguments);
+ }
+ },
+ performance: {
+ log: function(message) {
+ var
+ currentTime,
+ executionTime,
+ previousTime
+ ;
+ if(settings.performance) {
+ currentTime = new Date().getTime();
+ previousTime = time || currentTime;
+ executionTime = currentTime - previousTime;
+ time = currentTime;
+ performance.push({
+ 'Name' : message[0],
+ 'Arguments' : [].slice.call(message, 1) || '',
+ 'Element' : element,
+ 'Execution Time' : executionTime
+ });
+ }
+ clearTimeout(module.performance.timer);
+ module.performance.timer = setTimeout(module.performance.display, 500);
+ },
+ display: function() {
+ var
+ title = settings.name + ':',
+ totalTime = 0
+ ;
+ time = false;
+ clearTimeout(module.performance.timer);
+ $.each(performance, function(index, data) {
+ totalTime += data['Execution Time'];
+ });
+ title += ' ' + totalTime + 'ms';
+ if(moduleSelector) {
+ title += ' \'' + moduleSelector + '\'';
+ }
+ if($allModules.length > 1) {
+ title += ' ' + '(' + $allModules.length + ')';
+ }
+ if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
+ console.groupCollapsed(title);
+ if(console.table) {
+ console.table(performance);
+ }
+ else {
+ $.each(performance, function(index, data) {
+ console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
+ });
+ }
+ console.groupEnd();
+ }
+ performance = [];
+ }
+ },
+ invoke: function(query, passedArguments, context) {
+ var
+ object = instance,
+ maxDepth,
+ found,
+ response
+ ;
+ passedArguments = passedArguments || queryArguments;
+ context = element || context;
+ if(typeof query == 'string' && object !== undefined) {
+ query = query.split(/[\. ]/);
+ maxDepth = query.length - 1;
+ $.each(query, function(depth, value) {
+ var camelCaseValue = (depth != maxDepth)
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
+ : query
+ ;
+ if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
+ object = object[camelCaseValue];
+ }
+ else if( object[camelCaseValue] !== undefined ) {
+ found = object[camelCaseValue];
+ return false;
+ }
+ else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
+ object = object[value];
+ }
+ else if( object[value] !== undefined ) {
+ found = object[value];
+ return false;
+ }
+ else {
+ return false;
+ }
+ });
+ }
+ if( $.isFunction( found ) ) {
+ response = found.apply(context, passedArguments);
+ }
+ else if(found !== undefined) {
+ response = found;
+ }
+ if(Array.isArray(returnedValue)) {
+ returnedValue.push(response);
+ }
+ else if(returnedValue !== undefined) {
+ returnedValue = [returnedValue, response];
+ }
+ else if(response !== undefined) {
+ returnedValue = response;
+ }
+ return found;
+ }
+ };
+ module.initialize();
+ })
+ ;
+
+ return (returnedValue !== undefined)
+ ? returnedValue
+ : this
+ ;
+};
+
+$.fn.form.settings = {
+
+ name : 'Form',
+ namespace : 'form',
+
+ debug : false,
+ verbose : false,
+ performance : true,
+
+ fields : false,
+
+ keyboardShortcuts : true,
+ on : 'submit',
+ inline : false,
+
+ delay : 200,
+ revalidate : true,
+ shouldTrim : true,
+
+ transition : 'scale',
+ duration : 200,
+
+ onValid : function() {},
+ onInvalid : function() {},
+ onSuccess : function() { return true; },
+ onFailure : function() { return false; },
+
+ metadata : {
+ defaultValue : 'default',
+ validate : 'validate'
+ },
+
+ regExp: {
+ htmlID : /^[a-zA-Z][\w:.-]*$/g,
+ bracket : /\[(.*)\]/i,
+ decimal : /^\d+\.?\d*$/,
+ email : /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,
+ escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|:,=@]/g,
+ flags : /^\/(.*)\/(.*)?/,
+ integer : /^\-?\d+$/,
+ number : /^\-?\d*(\.\d+)?$/,
+ url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i
+ },
+
+ text: {
+ unspecifiedRule : 'Please enter a valid value',
+ unspecifiedField : 'This field'
+ },
+
+ prompt: {
+ empty : '{name} must have a value',
+ checked : '{name} must be checked',
+ email : '{name} must be a valid e-mail',
+ url : '{name} must be a valid url',
+ regExp : '{name} is not formatted correctly',
+ integer : '{name} must be an integer',
+ decimal : '{name} must be a decimal number',
+ number : '{name} must be set to a number',
+ is : '{name} must be "{ruleValue}"',
+ isExactly : '{name} must be exactly "{ruleValue}"',
+ not : '{name} cannot be set to "{ruleValue}"',
+ notExactly : '{name} cannot be set to exactly "{ruleValue}"',
+ contain : '{name} must contain "{ruleValue}"',
+ containExactly : '{name} must contain exactly "{ruleValue}"',
+ doesntContain : '{name} cannot contain "{ruleValue}"',
+ doesntContainExactly : '{name} cannot contain exactly "{ruleValue}"',
+ minLength : '{name} must be at least {ruleValue} characters',
+ length : '{name} must be at least {ruleValue} characters',
+ exactLength : '{name} must be exactly {ruleValue} characters',
+ maxLength : '{name} cannot be longer than {ruleValue} characters',
+ match : '{name} must match {ruleValue} field',
+ different : '{name} must have a different value than {ruleValue} field',
+ creditCard : '{name} must be a valid credit card number',
+ minCount : '{name} must have at least {ruleValue} choices',
+ exactCount : '{name} must have exactly {ruleValue} choices',
+ maxCount : '{name} must have {ruleValue} or less choices'
+ },
+
+ selector : {
+ checkbox : 'input[type="checkbox"], input[type="radio"]',
+ clear : '.clear',
+ field : 'input, textarea, select',
+ group : '.field',
+ input : 'input',
+ message : '.error.message',
+ prompt : '.prompt.label',
+ radio : 'input[type="radio"]',
+ reset : '.reset:not([type="reset"])',
+ submit : '.submit:not([type="submit"])',
+ uiCheckbox : '.ui.checkbox',
+ uiDropdown : '.ui.dropdown'
+ },
+
+ className : {
+ error : 'error',
+ label : 'ui prompt label',
+ pressed : 'down',
+ success : 'success'
+ },
+
+ error: {
+ identifier : 'You must specify a string identifier for each field',
+ method : 'The method you called is not defined.',
+ noRule : 'There is no rule matching the one you specified',
+ oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.'
+ },
+
+ templates: {
+
+ // template that produces error message
+ error: function(errors) {
+ var
+ html = '
'
+ ;
+ $.each(errors, function(index, value) {
+ html += '- ' + value + '
';
+ });
+ html += '
';
+ return $(html);
+ },
+
+ // template that produces label
+ prompt: function(errors) {
+ return $('')
+ .addClass('ui basic red pointing prompt label')
+ .html(errors[0])
+ ;
+ }
+ },
+
+ rules: {
+
+ // is not empty or blank string
+ empty: function(value) {
+ return !(value === undefined || '' === value || Array.isArray(value) && value.length === 0);
+ },
+
+ // checkbox checked
+ checked: function() {
+ return ($(this).filter(':checked').length > 0);
+ },
+
+ // is most likely an email
+ email: function(value){
+ return $.fn.form.settings.regExp.email.test(value);
+ },
+
+ // value is most likely url
+ url: function(value) {
+ return $.fn.form.settings.regExp.url.test(value);
+ },
+
+ // matches specified regExp
+ regExp: function(value, regExp) {
+ if(regExp instanceof RegExp) {
+ return value.match(regExp);
+ }
+ var
+ regExpParts = regExp.match($.fn.form.settings.regExp.flags),
+ flags
+ ;
+ // regular expression specified as /baz/gi (flags)
+ if(regExpParts) {
+ regExp = (regExpParts.length >= 2)
+ ? regExpParts[1]
+ : regExp
+ ;
+ flags = (regExpParts.length >= 3)
+ ? regExpParts[2]
+ : ''
+ ;
+ }
+ return value.match( new RegExp(regExp, flags) );
+ },
+
+ // is valid integer or matches range
+ integer: function(value, range) {
+ var
+ intRegExp = $.fn.form.settings.regExp.integer,
+ min,
+ max,
+ parts
+ ;
+ if( !range || ['', '..'].indexOf(range) !== -1) {
+ // do nothing
+ }
+ else if(range.indexOf('..') == -1) {
+ if(intRegExp.test(range)) {
+ min = max = range - 0;
+ }
+ }
+ else {
+ parts = range.split('..', 2);
+ if(intRegExp.test(parts[0])) {
+ min = parts[0] - 0;
+ }
+ if(intRegExp.test(parts[1])) {
+ max = parts[1] - 0;
+ }
+ }
+ return (
+ intRegExp.test(value) &&
+ (min === undefined || value >= min) &&
+ (max === undefined || value <= max)
+ );
+ },
+
+ // is valid number (with decimal)
+ decimal: function(value) {
+ return $.fn.form.settings.regExp.decimal.test(value);
+ },
+
+ // is valid number
+ number: function(value) {
+ return $.fn.form.settings.regExp.number.test(value);
+ },
+
+ // is value (case insensitive)
+ is: function(value, text) {
+ text = (typeof text == 'string')
+ ? text.toLowerCase()
+ : text
+ ;
+ value = (typeof value == 'string')
+ ? value.toLowerCase()
+ : value
+ ;
+ return (value == text);
+ },
+
+ // is value
+ isExactly: function(value, text) {
+ return (value == text);
+ },
+
+ // value is not another value (case insensitive)
+ not: function(value, notValue) {
+ value = (typeof value == 'string')
+ ? value.toLowerCase()
+ : value
+ ;
+ notValue = (typeof notValue == 'string')
+ ? notValue.toLowerCase()
+ : notValue
+ ;
+ return (value != notValue);
+ },
+
+ // value is not another value (case sensitive)
+ notExactly: function(value, notValue) {
+ return (value != notValue);
+ },
+
+ // value contains text (insensitive)
+ contains: function(value, text) {
+ // escape regex characters
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
+ return (value.search( new RegExp(text, 'i') ) !== -1);
+ },
+
+ // value contains text (case sensitive)
+ containsExactly: function(value, text) {
+ // escape regex characters
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
+ return (value.search( new RegExp(text) ) !== -1);
+ },
+
+ // value contains text (insensitive)
+ doesntContain: function(value, text) {
+ // escape regex characters
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
+ return (value.search( new RegExp(text, 'i') ) === -1);
+ },
+
+ // value contains text (case sensitive)
+ doesntContainExactly: function(value, text) {
+ // escape regex characters
+ text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
+ return (value.search( new RegExp(text) ) === -1);
+ },
+
+ // is at least string length
+ minLength: function(value, requiredLength) {
+ return (value !== undefined)
+ ? (value.length >= requiredLength)
+ : false
+ ;
+ },
+
+ // see rls notes for 2.0.6 (this is a duplicate of minLength)
+ length: function(value, requiredLength) {
+ return (value !== undefined)
+ ? (value.length >= requiredLength)
+ : false
+ ;
+ },
+
+ // is exactly length
+ exactLength: function(value, requiredLength) {
+ return (value !== undefined)
+ ? (value.length == requiredLength)
+ : false
+ ;
+ },
+
+ // is less than length
+ maxLength: function(value, maxLength) {
+ return (value !== undefined)
+ ? (value.length <= maxLength)
+ : false
+ ;
+ },
+
+ // matches another field
+ match: function(value, identifier) {
+ var
+ $form = $(this),
+ matchingValue
+ ;
+ if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
+ matchingValue = $('[data-validate="'+ identifier +'"]').val();
+ }
+ else if($('#' + identifier).length > 0) {
+ matchingValue = $('#' + identifier).val();
+ }
+ else if($('[name="' + identifier +'"]').length > 0) {
+ matchingValue = $('[name="' + identifier + '"]').val();
+ }
+ else if( $('[name="' + identifier +'[]"]').length > 0 ) {
+ matchingValue = $('[name="' + identifier +'[]"]');
+ }
+ return (matchingValue !== undefined)
+ ? ( value.toString() == matchingValue.toString() )
+ : false
+ ;
+ },
+
+ // different than another field
+ different: function(value, identifier) {
+ // use either id or name of field
+ var
+ $form = $(this),
+ matchingValue
+ ;
+ if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
+ matchingValue = $('[data-validate="'+ identifier +'"]').val();
+ }
+ else if($('#' + identifier).length > 0) {
+ matchingValue = $('#' + identifier).val();
+ }
+ else if($('[name="' + identifier +'"]').length > 0) {
+ matchingValue = $('[name="' + identifier + '"]').val();
+ }
+ else if( $('[name="' + identifier +'[]"]').length > 0 ) {
+ matchingValue = $('[name="' + identifier +'[]"]');
+ }
+ return (matchingValue !== undefined)
+ ? ( value.toString() !== matchingValue.toString() )
+ : false
+ ;
+ },
+
+ creditCard: function(cardNumber, cardTypes) {
+ var
+ cards = {
+ visa: {
+ pattern : /^4/,
+ length : [16]
+ },
+ amex: {
+ pattern : /^3[47]/,
+ length : [15]
+ },
+ mastercard: {
+ pattern : /^5[1-5]/,
+ length : [16]
+ },
+ discover: {
+ pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
+ length : [16]
+ },
+ unionPay: {
+ pattern : /^(62|88)/,
+ length : [16, 17, 18, 19]
+ },
+ jcb: {
+ pattern : /^35(2[89]|[3-8][0-9])/,
+ length : [16]
+ },
+ maestro: {
+ pattern : /^(5018|5020|5038|6304|6759|676[1-3])/,
+ length : [12, 13, 14, 15, 16, 17, 18, 19]
+ },
+ dinersClub: {
+ pattern : /^(30[0-5]|^36)/,
+ length : [14]
+ },
+ laser: {
+ pattern : /^(6304|670[69]|6771)/,
+ length : [16, 17, 18, 19]
+ },
+ visaElectron: {
+ pattern : /^(4026|417500|4508|4844|491(3|7))/,
+ length : [16]
+ }
+ },
+ valid = {},
+ validCard = false,
+ requiredTypes = (typeof cardTypes == 'string')
+ ? cardTypes.split(',')
+ : false,
+ unionPay,
+ validation
+ ;
+
+ if(typeof cardNumber !== 'string' || cardNumber.length === 0) {
+ return;
+ }
+
+ // allow dashes in card
+ cardNumber = cardNumber.replace(/[\-]/g, '');
+
+ // verify card types
+ if(requiredTypes) {
+ $.each(requiredTypes, function(index, type){
+ // verify each card type
+ validation = cards[type];
+ if(validation) {
+ valid = {
+ length : ($.inArray(cardNumber.length, validation.length) !== -1),
+ pattern : (cardNumber.search(validation.pattern) !== -1)
+ };
+ if(valid.length && valid.pattern) {
+ validCard = true;
+ }
+ }
+ });
+
+ if(!validCard) {
+ return false;
+ }
+ }
+
+ // skip luhn for UnionPay
+ unionPay = {
+ number : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1),
+ pattern : (cardNumber.search(cards.unionPay.pattern) !== -1)
+ };
+ if(unionPay.number && unionPay.pattern) {
+ return true;
+ }
+
+ // verify luhn, adapted from
+ var
+ length = cardNumber.length,
+ multiple = 0,
+ producedValue = [
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
+ [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
+ ],
+ sum = 0
+ ;
+ while (length--) {
+ sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)];
+ multiple ^= 1;
+ }
+ return (sum % 10 === 0 && sum > 0);
+ },
+
+ minCount: function(value, minCount) {
+ if(minCount == 0) {
+ return true;
+ }
+ if(minCount == 1) {
+ return (value !== '');
+ }
+ return (value.split(',').length >= minCount);
+ },
+
+ exactCount: function(value, exactCount) {
+ if(exactCount == 0) {
+ return (value === '');
+ }
+ if(exactCount == 1) {
+ return (value !== '' && value.search(',') === -1);
+ }
+ return (value.split(',').length == exactCount);
+ },
+
+ maxCount: function(value, maxCount) {
+ if(maxCount == 0) {
+ return false;
+ }
+ if(maxCount == 1) {
+ return (value.search(',') === -1);
+ }
+ return (value.split(',').length <= maxCount);
+ }
+ }
+
+};
+
+})( jQuery, window, document );
+
+/*!
+ * # Semantic UI 2.7.1 - Accordion
+ * http://github.com/semantic-org/semantic-ui/
+ *
+ *
+ * Released under the MIT license
+ * http://opensource.org/licenses/MIT
+ *
+ */
+
+;(function ($, window, document, undefined) {
+
+'use strict';
+
+$.isFunction = $.isFunction || function(obj) {
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+};
+
+window = (typeof window != 'undefined' && window.Math == Math)
+ ? window
+ : (typeof self != 'undefined' && self.Math == Math)
+ ? self
+ : Function('return this')()
+;
+
+$.fn.accordion = function(parameters) {
+ var
+ $allModules = $(this),
+
+ time = new Date().getTime(),
+ performance = [],
+
+ query = arguments[0],
+ methodInvoked = (typeof query == 'string'),
+ queryArguments = [].slice.call(arguments, 1),
+
+ requestAnimationFrame = window.requestAnimationFrame
+ || window.mozRequestAnimationFrame
+ || window.webkitRequestAnimationFrame
+ || window.msRequestAnimationFrame
+ || function(callback) { setTimeout(callback, 0); },
+
+ returnedValue
+ ;
+ $allModules
+ .each(function() {
+ var
+ settings = ( $.isPlainObject(parameters) )
+ ? $.extend(true, {}, $.fn.accordion.settings, parameters)
+ : $.extend({}, $.fn.accordion.settings),
+
+ className = settings.className,
+ namespace = settings.namespace,
+ selector = settings.selector,
+ error = settings.error,
+
+ eventNamespace = '.' + namespace,
+ moduleNamespace = 'module-' + namespace,
+ moduleSelector = $allModules.selector || '',
+
+ $module = $(this),
+ $title = $module.find(selector.title),
+ $content = $module.find(selector.content),
+
+ element = this,
+ instance = $module.data(moduleNamespace),
+ observer,
+ module
+ ;
+
+ module = {
+
+ initialize: function() {
+ module.debug('Initializing', $module);
+ module.bind.events();
+ if(settings.observeChanges) {
+ module.observeChanges();
+ }
+ module.instantiate();
+ },
+
+ instantiate: function() {
+ instance = module;
+ $module
+ .data(moduleNamespace, module)
+ ;
+ },
+
+ destroy: function() {
+ module.debug('Destroying previous instance', $module);
+ $module
+ .off(eventNamespace)
+ .removeData(moduleNamespace)
+ ;
+ },
+
+ refresh: function() {
+ $title = $module.find(selector.title);
+ $content = $module.find(selector.content);
+ },
+
+ observeChanges: function() {
+ if('MutationObserver' in window) {
+ observer = new MutationObserver(function(mutations) {
+ module.debug('DOM tree modified, updating selector cache');
+ module.refresh();
+ });
+ observer.observe(element, {
+ childList : true,
+ subtree : true
+ });
+ module.debug('Setting up mutation observer', observer);
+ }
+ },
+
+ bind: {
+ events: function() {
+ module.debug('Binding delegated events');
+ $module
+ .on(settings.on + eventNamespace, selector.trigger, module.event.click)
+ ;
+ }
+ },
+
+ event: {
+ click: function() {
+ module.toggle.call(this);
+ }
+ },
+
+ toggle: function(query) {
+ var
+ $activeTitle = (query !== undefined)
+ ? (typeof query === 'number')
+ ? $title.eq(query)
+ : $(query).closest(selector.title)
+ : $(this).closest(selector.title),
+ $activeContent = $activeTitle.next($content),
+ isAnimating = $activeContent.hasClass(className.animating),
+ isActive = $activeContent.hasClass(className.active),
+ isOpen = (isActive && !isAnimating),
+ isOpening = (!isActive && isAnimating)
+ ;
+ module.debug('Toggling visibility of content', $activeTitle);
+ if(isOpen || isOpening) {
+ if(settings.collapsible) {
+ module.close.call($activeTitle);
+ }
+ else {
+ module.debug('Cannot close accordion content collapsing is disabled');
+ }
+ }
+ else {
+ module.open.call($activeTitle);
+ }
+ },
+
+ open: function(query) {
+ var
+ $activeTitle = (query !== undefined)
+ ? (typeof query === 'number')
+ ? $title.eq(query)
+ : $(query).closest(selector.title)
+ : $(this).closest(selector.title),
+ $activeContent = $activeTitle.next($content),
+ isAnimating = $activeContent.hasClass(className.animating),
+ isActive = $activeContent.hasClass(className.active),
+ isOpen = (isActive || isAnimating)
+ ;
+ if(isOpen) {
+ module.debug('Accordion already open, skipping', $activeContent);
+ return;
+ }
+ module.debug('Opening accordion content', $activeTitle);
+ settings.onOpening.call($activeContent);
+ settings.onChanging.call($activeContent);
+ if(settings.exclusive) {
+ module.closeOthers.call($activeTitle);
+ }
+ $activeTitle
+ .addClass(className.active)
+ ;
+ $activeContent
+ .stop(true, true)
+ .addClass(className.animating)
+ ;
+ if(settings.animateChildren) {
+ if($.fn.transition !== undefined && $module.transition('is supported')) {
+ $activeContent
+ .children()
+ .transition({
+ animation : 'fade in',
+ queue : false,
+ useFailSafe : true,
+ debug : settings.debug,
+ verbose : settings.verbose,
+ duration : settings.duration
+ })
+ ;
+ }
+ else {
+ $activeContent
+ .children()
+ .stop(true, true)
+ .animate({
+ opacity: 1
+ }, settings.duration, module.resetOpacity)
+ ;
+ }
+ }
+ $activeContent
+ .slideDown(settings.duration, settings.easing, function() {
+ $activeContent
+ .removeClass(className.animating)
+ .addClass(className.active)
+ ;
+ module.reset.display.call(this);
+ settings.onOpen.call(this);
+ settings.onChange.call(this);
+ })
+ ;
+ },
+
+ close: function(query) {
+ var
+ $activeTitle = (query !== undefined)
+ ? (typeof query === 'number')
+ ? $title.eq(query)
+ : $(query).closest(selector.title)
+ : $(this).closest(selector.title),
+ $activeContent = $activeTitle.next($content),
+ isAnimating = $activeContent.hasClass(className.animating),
+ isActive = $activeContent.hasClass(className.active),
+ isOpening = (!isActive && isAnimating),
+ isClosing = (isActive && isAnimating)
+ ;
+ if((isActive || isOpening) && !isClosing) {
+ module.debug('Closing accordion content', $activeContent);
+ settings.onClosing.call($activeContent);
+ settings.onChanging.call($activeContent);
+ $activeTitle
+ .removeClass(className.active)
+ ;
+ $activeContent
+ .stop(true, true)
+ .addClass(className.animating)
+ ;
+ if(settings.animateChildren) {
+ if($.fn.transition !== undefined && $module.transition('is supported')) {
+ $activeContent
+ .children()
+ .transition({
+ animation : 'fade out',
+ queue : false,
+ useFailSafe : true,
+ debug : settings.debug,
+ verbose : settings.verbose,
+ duration : settings.duration
+ })
+ ;
+ }
+ else {
+ $activeContent
+ .children()
+ .stop(true, true)
+ .animate({
+ opacity: 0
+ }, settings.duration, module.resetOpacity)
+ ;
+ }
+ }
+ $activeContent
+ .slideUp(settings.duration, settings.easing, function() {
+ $activeContent
+ .removeClass(className.animating)
+ .removeClass(className.active)
+ ;
+ module.reset.display.call(this);
+ settings.onClose.call(this);
+ settings.onChange.call(this);
+ })
+ ;
+ }
+ },
+
+ closeOthers: function(index) {
+ var
+ $activeTitle = (index !== undefined)
+ ? $title.eq(index)
+ : $(this).closest(selector.title),
+ $parentTitles = $activeTitle.parents(selector.content).prev(selector.title),
+ $activeAccordion = $activeTitle.closest(selector.accordion),
+ activeSelector = selector.title + '.' + className.active + ':visible',
+ activeContent = selector.content + '.' + className.active + ':visible',
+ $openTitles,
+ $nestedTitles,
+ $openContents
+ ;
+ if(settings.closeNested) {
+ $openTitles = $activeAccordion.find(activeSelector).not($parentTitles);
+ $openContents = $openTitles.next($content);
+ }
+ else {
+ $openTitles = $activeAccordion.find(activeSelector).not($parentTitles);
+ $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles);
+ $openTitles = $openTitles.not($nestedTitles);
+ $openContents = $openTitles.next($content);
+ }
+ if( ($openTitles.length > 0) ) {
+ module.debug('Exclusive enabled, closing other content', $openTitles);
+ $openTitles
+ .removeClass(className.active)
+ ;
+ $openContents
+ .removeClass(className.animating)
+ .stop(true, true)
+ ;
+ if(settings.animateChildren) {
+ if($.fn.transition !== undefined && $module.transition('is supported')) {
+ $openContents
+ .children()
+ .transition({
+ animation : 'fade out',
+ useFailSafe : true,
+ debug : settings.debug,
+ verbose : settings.verbose,
+ duration : settings.duration
+ })
+ ;
+ }
+ else {
+ $openContents
+ .children()
+ .stop(true, true)
+ .animate({
+ opacity: 0
+ }, settings.duration, module.resetOpacity)
+ ;
+ }
+ }
+ $openContents
+ .slideUp(settings.duration , settings.easing, function() {
+ $(this).removeClass(className.active);
+ module.reset.display.call(this);
+ })
+ ;
+ }
+ },
+
+ reset: {
+
+ display: function() {
+ module.verbose('Removing inline display from element', this);
+ $(this).css('display', '');
+ if( $(this).attr('style') === '') {
+ $(this)
+ .attr('style', '')
+ .removeAttr('style')
+ ;
+ }
+ },
+
+ opacity: function() {
+ module.verbose('Removing inline opacity from element', this);
+ $(this).css('opacity', '');
+ if( $(this).attr('style') === '') {
+ $(this)
+ .attr('style', '')
+ .removeAttr('style')
+ ;
+ }
+ },
+
+ },
+
+ setting: function(name, value) {
+ module.debug('Changing setting', name, value);
+ if( $.isPlainObject(name) ) {
+ $.extend(true, settings, name);
+ }
+ else if(value !== undefined) {
+ if($.isPlainObject(settings[name])) {
+ $.extend(true, settings[name], value);
+ }
+ else {
+ settings[name] = value;
+ }
+ }
+ else {
+ return settings[name];
+ }
+ },
+ internal: function(name, value) {
+ module.debug('Changing internal', name, value);
+ if(value !== undefined) {
+ if( $.isPlainObject(name) ) {
+ $.extend(true, module, name);
+ }
+ else {
+ module[name] = value;
+ }
+ }
+ else {
+ return module[name];
+ }
+ },
+ debug: function() {
+ if(!settings.silent && settings.debug) {
+ if(settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.debug.apply(console, arguments);
+ }
+ }
+ },
+ verbose: function() {
+ if(!settings.silent && settings.verbose && settings.debug) {
+ if(settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.verbose.apply(console, arguments);
+ }
+ }
+ },
+ error: function() {
+ if(!settings.silent) {
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
+ module.error.apply(console, arguments);
+ }
+ },
+ performance: {
+ log: function(message) {
+ var
+ currentTime,
+ executionTime,
+ previousTime
+ ;
+ if(settings.performance) {
+ currentTime = new Date().getTime();
+ previousTime = time || currentTime;
+ executionTime = currentTime - previousTime;
+ time = currentTime;
+ performance.push({
+ 'Name' : message[0],
+ 'Arguments' : [].slice.call(message, 1) || '',
+ 'Element' : element,
+ 'Execution Time' : executionTime
+ });
+ }
+ clearTimeout(module.performance.timer);
+ module.performance.timer = setTimeout(module.performance.display, 500);
+ },
+ display: function() {
+ var
+ title = settings.name + ':',
+ totalTime = 0
+ ;
+ time = false;
+ clearTimeout(module.performance.timer);
+ $.each(performance, function(index, data) {
+ totalTime += data['Execution Time'];
+ });
+ title += ' ' + totalTime + 'ms';
+ if(moduleSelector) {
+ title += ' \'' + moduleSelector + '\'';
+ }
+ if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
+ console.groupCollapsed(title);
+ if(console.table) {
+ console.table(performance);
+ }
+ else {
+ $.each(performance, function(index, data) {
+ console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
+ });
+ }
+ console.groupEnd();
+ }
+ performance = [];
+ }
+ },
+ invoke: function(query, passedArguments, context) {
+ var
+ object = instance,
+ maxDepth,
+ found,
+ response
+ ;
+ passedArguments = passedArguments || queryArguments;
+ context = element || context;
+ if(typeof query == 'string' && object !== undefined) {
+ query = query.split(/[\. ]/);
+ maxDepth = query.length - 1;
+ $.each(query, function(depth, value) {
+ var camelCaseValue = (depth != maxDepth)
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
+ : query
+ ;
+ if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
+ object = object[camelCaseValue];
+ }
+ else if( object[camelCaseValue] !== undefined ) {
+ found = object[camelCaseValue];
+ return false;
+ }
+ else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
+ object = object[value];
+ }
+ else if( object[value] !== undefined ) {
+ found = object[value];
+ return false;
+ }
+ else {
+ module.error(error.method, query);
+ return false;
+ }
+ });
+ }
+ if ( $.isFunction( found ) ) {
+ response = found.apply(context, passedArguments);
+ }
+ else if(found !== undefined) {
+ response = found;
+ }
+ if(Array.isArray(returnedValue)) {
+ returnedValue.push(response);
+ }
+ else if(returnedValue !== undefined) {
+ returnedValue = [returnedValue, response];
+ }
+ else if(response !== undefined) {
+ returnedValue = response;
+ }
+ return found;
+ }
+ };
+ if(methodInvoked) {
+ if(instance === undefined) {
+ module.initialize();
+ }
+ module.invoke(query);
+ }
+ else {
+ if(instance !== undefined) {
+ instance.invoke('destroy');
+ }
+ module.initialize();
+ }
+ })
+ ;
+ return (returnedValue !== undefined)
+ ? returnedValue
+ : this
+ ;
+};
+
+$.fn.accordion.settings = {
+
+ name : 'Accordion',
+ namespace : 'accordion',
+
+ silent : false,
+ debug : false,
+ verbose : false,
+ performance : true,
+
+ on : 'click', // event on title that opens accordion
+
+ observeChanges : true, // whether accordion should automatically refresh on DOM insertion
+
+ exclusive : true, // whether a single accordion content panel should be open at once
+ collapsible : true, // whether accordion content can be closed
+ closeNested : false, // whether nested content should be closed when a panel is closed
+ animateChildren : true, // whether children opacity should be animated
+
+ duration : 350, // duration of animation
+ easing : 'easeOutQuad', // easing equation for animation
+
+ onOpening : function(){}, // callback before open animation
+ onClosing : function(){}, // callback before closing animation
+ onChanging : function(){}, // callback before closing or opening animation
+
+ onOpen : function(){}, // callback after open animation
+ onClose : function(){}, // callback after closing animation
+ onChange : function(){}, // callback after closing or opening animation
+
+ error: {
+ method : 'The method you called is not defined'
+ },
+
+ className : {
+ active : 'active',
+ animating : 'animating'
+ },
+
+ selector : {
+ accordion : '.accordion',
+ title : '.title',
+ trigger : '.title',
+ content : '.content'
+ }
+
+};
+
+// Adds easing
+$.extend( $.easing, {
+ easeOutQuad: function (x, t, b, c, d) {
+ return -c *(t/=d)*(t-2) + b;
+ }
+});
+
+})( jQuery, window, document );
+
+
+/*!
+ * # Semantic UI 2.7.1 - Calendar
+ * http://github.com/semantic-org/semantic-ui/
+ *
+ *
+ * Released under the MIT license
+ * http://opensource.org/licenses/MIT
+ *
+ */
+
+;(function ($, window, document, undefined) {
+
+'use strict';
+
+$.isFunction = $.isFunction || function(obj) {
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+};
+
+window = (typeof window != 'undefined' && window.Math == Math)
+ ? window
+ : (typeof self != 'undefined' && self.Math == Math)
+ ? self
+ : Function('return this')()
+;
+
+$.fn.calendar = function(parameters) {
+ var
+ $allModules = $(this),
+
+ moduleSelector = $allModules.selector || '',
+
+ time = new Date().getTime(),
+ performance = [],
+
+ query = arguments[0],
+ methodInvoked = (typeof query == 'string'),
+ queryArguments = [].slice.call(arguments, 1),
+ returnedValue,
+ timeGapTable = {
+ '5': {'row': 4, 'column': 3 },
+ '10': {'row': 3, 'column': 2 },
+ '15': {'row': 2, 'column': 2 },
+ '20': {'row': 3, 'column': 1 },
+ '30': {'row': 2, 'column': 1 }
+ }
+ ;
+
+ $allModules
+ .each(function () {
+ var
+ settings = ( $.isPlainObject(parameters) )
+ ? $.extend(true, {}, $.fn.calendar.settings, parameters)
+ : $.extend({}, $.fn.calendar.settings),
+
+ className = settings.className,
+ namespace = settings.namespace,
+ selector = settings.selector,
+ formatter = settings.formatter,
+ parser = settings.parser,
+ metadata = settings.metadata,
+ timeGap = timeGapTable[settings.minTimeGap],
+ error = settings.error,
+
+ eventNamespace = '.' + namespace,
+ moduleNamespace = 'module-' + namespace,
+
+ $module = $(this),
+ $input = $module.find(selector.input),
+ $container = $module.find(selector.popup),
+ $activator = $module.find(selector.activator),
+
+ element = this,
+ instance = $module.data(moduleNamespace),
+
+ isTouch,
+ isTouchDown = false,
+ focusDateUsedForRange = false,
+ module
+ ;
+
+ module = {
+
+ initialize: function () {
+ module.debug('Initializing calendar for', element, $module);
+
+ isTouch = module.get.isTouch();
+ module.setup.config();
+ module.setup.popup();
+ module.setup.inline();
+ module.setup.input();
+ module.setup.date();
+ module.create.calendar();
+
+ module.bind.events();
+ module.instantiate();
+ },
+
+ instantiate: function () {
+ module.verbose('Storing instance of calendar');
+ instance = module;
+ $module.data(moduleNamespace, instance);
+ },
+
+ destroy: function () {
+ module.verbose('Destroying previous calendar for', element);
+ $module.removeData(moduleNamespace);
+ module.unbind.events();
+ },
+
+ setup: {
+ config: function () {
+ if (module.get.minDate() !== null) {
+ module.set.minDate($module.data(metadata.minDate));
+ }
+ if (module.get.maxDate() !== null) {
+ module.set.maxDate($module.data(metadata.maxDate));
+ }
+ },
+ popup: function () {
+ if (settings.inline) {
+ return;
+ }
+ if (!$activator.length) {
+ $activator = $module.children().first();
+ if (!$activator.length) {
+ return;
+ }
+ }
+ if ($.fn.popup === undefined) {
+ module.error(error.popup);
+ return;
+ }
+ if (!$container.length) {
+ //prepend the popup element to the activator's parent so that it has less chance of messing with
+ //the styling (eg input action button needs to be the last child to have correct border radius)
+ $container = $('').addClass(className.popup).prependTo($activator.parent());
+ }
+ $container.addClass(className.calendar);
+ var onVisible = settings.onVisible;
+ var onHidden = settings.onHidden;
+ if (!$input.length) {
+ //no input, $container has to handle focus/blur
+ $container.attr('tabindex', '0');
+ onVisible = function () {
+ module.focus();
+ return settings.onVisible.apply($container, arguments);
+ };
+ onHidden = function () {
+ module.blur();
+ return settings.onHidden.apply($container, arguments);
+ };
+ }
+ var onShow = function () {
+ //reset the focus date onShow
+ module.set.focusDate(module.get.date());
+ module.set.mode(settings.startMode);
+ return settings.onShow.apply($container, arguments);
+ };
+ var on = settings.on || ($input.length ? 'focus' : 'click');
+ var options = $.extend({}, settings.popupOptions, {
+ popup: $container,
+ on: on,
+ hoverable: on === 'hover',
+ onShow: onShow,
+ onVisible: onVisible,
+ onHide: settings.onHide,
+ onHidden: onHidden
+ });
+ module.popup(options);
+ },
+ inline: function () {
+ if ($activator.length && !settings.inline) {
+ return;
+ }
+ $container = $('').addClass(className.calendar).appendTo($module);
+ if (!$input.length) {
+ $container.attr('tabindex', '0');
+ }
+ },
+ input: function () {
+ if (settings.touchReadonly && $input.length && isTouch) {
+ $input.prop('readonly', true);
+ }
+ },
+ date: function () {
+ if ($input.length) {
+ var val = $input.val();
+ var date = parser.date(val, settings);
+ module.set.date(date, settings.formatInput, false);
+ }
+ }
+ },
+
+ create: {
+ calendar: function () {
+ var i, r, c, p, row, cell, pageGrid;
+
+ var mode = module.get.mode();
+ var today = new Date();
+ var date = module.get.date();
+ var focusDate = module.get.focusDate();
+ var display = focusDate || date || settings.initialDate || today;
+ display = module.helper.dateInRange(display);
+
+ if (!focusDate) {
+ focusDate = display;
+ module.set.focusDate(focusDate, false, false);
+ }
+
+ var isYear = mode === 'year';
+ var isMonth = mode === 'month';
+ var isDay = mode === 'day';
+ var isHour = mode === 'hour';
+ var isMinute = mode === 'minute';
+ var isTimeOnly = settings.type === 'time';
+
+ var multiMonth = Math.max(settings.multiMonth, 1);
+ var monthOffset = !isDay ? 0 : module.get.monthOffset();
+
+ var minute = display.getMinutes();
+ var hour = display.getHours();
+ var day = display.getDate();
+ var startMonth = display.getMonth() + monthOffset;
+ var year = display.getFullYear();
+
+ var columns = isDay ? settings.showWeekNumbers ? 8 : 7 : isHour ? 4 : timeGap['column'];
+ var rows = isDay || isHour ? 6 : timeGap['row'];
+ var pages = isDay ? multiMonth : 1;
+
+ var container = $container;
+ var tooltipPosition = container.hasClass("left") ? "right center" : "left center";
+ container.empty();
+ if (pages > 1) {
+ pageGrid = $('').addClass(className.grid).appendTo(container);
+ }
+
+ for (p = 0; p < pages; p++) {
+ if (pages > 1) {
+ var pageColumn = $('').addClass(className.column).appendTo(pageGrid);
+ container = pageColumn;
+ }
+
+ var month = startMonth + p;
+ var firstMonthDayColumn = (new Date(year, month, 1).getDay() - settings.firstDayOfWeek % 7 + 7) % 7;
+ if (!settings.constantHeight && isDay) {
+ var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
+ rows = Math.ceil(requiredCells / 7);
+ }
+
+ var yearChange = isYear ? 10 : isMonth ? 1 : 0;
+ var monthChange = isDay ? 1 : 0;
+ var dayChange = isHour || isMinute ? 1 : 0;
+ var prevNextDay = isHour || isMinute ? day : 1;
+ var prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour);
+ var nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour);
+
+ var prevLast = isYear ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0) :
+ isMonth ? new Date(year, 0, 0) : isDay ? new Date(year, month, 0) : new Date(year, month, day, -1);
+ var nextFirst = isYear ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1) :
+ isMonth ? new Date(year + 1, 0, 1) : isDay ? new Date(year, month + 1, 1) : new Date(year, month, day + 1);
+
+ var tempMode = mode;
+ if (isDay && settings.showWeekNumbers){
+ tempMode += ' andweek';
+ }
+ var table = $('').addClass(className.table).addClass(tempMode).appendTo(container);
+ var textColumns = columns;
+ //no header for time-only mode
+ if (!isTimeOnly) {
+ var thead = $('').appendTo(table);
+
+ row = $('
').appendTo(thead);
+ cell = $(' | ').attr('colspan', '' + columns).appendTo(row);
+
+ var headerDate = isYear || isMonth ? new Date(year, 0, 1) :
+ isDay ? new Date(year, month, 1) : new Date(year, month, day, hour, minute);
+ var headerText = $('').addClass(className.link).appendTo(cell);
+ headerText.text(formatter.header(headerDate, mode, settings));
+ var newMode = isMonth ? (settings.disableYear ? 'day' : 'year') :
+ isDay ? (settings.disableMonth ? 'year' : 'month') : 'day';
+ headerText.data(metadata.mode, newMode);
+
+ if (p === 0) {
+ var prev = $('').addClass(className.prev).appendTo(cell);
+ prev.data(metadata.focusDate, prevDate);
+ prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
+ $('').addClass(className.prevIcon).appendTo(prev);
+ }
+
+ if (p === pages - 1) {
+ var next = $('').addClass(className.next).appendTo(cell);
+ next.data(metadata.focusDate, nextDate);
+ next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
+ $('').addClass(className.nextIcon).appendTo(next);
+ }
+ if (isDay) {
+ row = $('
').appendTo(thead);
+ if(settings.showWeekNumbers) {
+ cell = $(' | ').appendTo(row);
+ cell.text(settings.text.weekNo);
+ cell.addClass(className.disabledCell);
+ textColumns--;
+ }
+ for (i = 0; i < textColumns; i++) {
+ cell = $(' | ').appendTo(row);
+ cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
+ }
+ }
+ }
+
+ var tbody = $('').appendTo(table);
+ i = isYear ? Math.ceil(year / 10) * 10 - 9 : isDay ? 1 - firstMonthDayColumn : 0;
+ for (r = 0; r < rows; r++) {
+ row = $('
').appendTo(tbody);
+ if(isDay && settings.showWeekNumbers){
+ cell = $(' | ').appendTo(row);
+ cell.text(module.get.weekOfYear(year,month,i+1-settings.firstDayOfWeek));
+ cell.addClass(className.disabledCell);
+ }
+ for (c = 0; c < textColumns; c++, i++) {
+ var cellDate = isYear ? new Date(i, month, 1, hour, minute) :
+ isMonth ? new Date(year, i, 1, hour, minute) : isDay ? new Date(year, month, i, hour, minute) :
+ isHour ? new Date(year, month, day, i) : new Date(year, month, day, hour, i * settings.minTimeGap);
+ var cellText = isYear ? i :
+ isMonth ? settings.text.monthsShort[i] : isDay ? cellDate.getDate() :
+ formatter.time(cellDate, settings, true);
+ cell = $(' | ').addClass(className.cell).appendTo(row);
+ cell.text(cellText);
+ cell.data(metadata.date, cellDate);
+ var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
+ var disabled = adjacent || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode);
+ if (disabled) {
+ var disabledReason = module.helper.disabledReason(cellDate, mode);
+ if (disabledReason !== null) {
+ cell.attr("data-tooltip", disabledReason[metadata.message]);
+ cell.attr("data-position", tooltipPosition);
+ }
+ }
+ var active = module.helper.dateEqual(cellDate, date, mode);
+ var isToday = module.helper.dateEqual(cellDate, today, mode);
+ cell.toggleClass(className.adjacentCell, adjacent);
+ cell.toggleClass(className.disabledCell, disabled);
+ cell.toggleClass(className.activeCell, active && !adjacent);
+ if (!isHour && !isMinute) {
+ cell.toggleClass(className.todayCell, !adjacent && isToday);
+ }
+
+ // Allow for external modifications of each cell
+ var cellOptions = {
+ mode: mode,
+ adjacent: adjacent,
+ disabled: disabled,
+ active: active,
+ today: isToday
+ };
+ formatter.cell(cell, cellDate, cellOptions);
+
+ if (module.helper.dateEqual(cellDate, focusDate, mode)) {
+ //ensure that the focus date is exactly equal to the cell date
+ //so that, if selected, the correct value is set
+ module.set.focusDate(cellDate, false, false);
+ }
+ }
+ }
+
+ if (settings.today) {
+ var todayRow = $('
').appendTo(tbody);
+ var todayButton = $(' | ').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
+ todayButton.text(formatter.today(settings));
+ todayButton.data(metadata.date, today);
+ }
+
+ module.update.focus(false, table);
+ }
+ }
+ },
+
+ update: {
+ focus: function (updateRange, container) {
+ container = container || $container;
+ var mode = module.get.mode();
+ var date = module.get.date();
+ var focusDate = module.get.focusDate();
+ var startDate = module.get.startDate();
+ var endDate = module.get.endDate();
+ var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
+
+ container.find('td').each(function () {
+ var cell = $(this);
+ var cellDate = cell.data(metadata.date);
+ if (!cellDate) {
+ return;
+ }
+ var disabled = cell.hasClass(className.disabledCell);
+ var active = cell.hasClass(className.activeCell);
+ var adjacent = cell.hasClass(className.adjacentCell);
+ var focused = module.helper.dateEqual(cellDate, focusDate, mode);
+ var inRange = !rangeDate ? false :
+ ((!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate)) ||
+ (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate)));
+ cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && !adjacent && !disabled);
+ cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
+ });
+ }
+ },
+
+ refresh: function () {
+ module.create.calendar();
+ },
+
+ bind: {
+ events: function () {
+ module.debug('Binding events');
+ $container.on('mousedown' + eventNamespace, module.event.mousedown);
+ $container.on('touchstart' + eventNamespace, module.event.mousedown);
+ $container.on('mouseup' + eventNamespace, module.event.mouseup);
+ $container.on('touchend' + eventNamespace, module.event.mouseup);
+ $container.on('mouseover' + eventNamespace, module.event.mouseover);
+ if ($input.length) {
+ $input.on('input' + eventNamespace, module.event.inputChange);
+ $input.on('focus' + eventNamespace, module.event.inputFocus);
+ $input.on('blur' + eventNamespace, module.event.inputBlur);
+ $input.on('click' + eventNamespace, module.event.inputClick);
+ $input.on('keydown' + eventNamespace, module.event.keydown);
+ } else {
+ $container.on('keydown' + eventNamespace, module.event.keydown);
+ }
+ }
+ },
+
+ unbind: {
+ events: function () {
+ module.debug('Unbinding events');
+ $container.off(eventNamespace);
+ if ($input.length) {
+ $input.off(eventNamespace);
+ }
+ }
+ },
+
+ event: {
+ mouseover: function (event) {
+ var target = $(event.target);
+ var date = target.data(metadata.date);
+ var mousedown = event.buttons === 1;
+ if (date) {
+ module.set.focusDate(date, false, true, mousedown);
+ }
+ },
+ mousedown: function (event) {
+ if ($input.length) {
+ //prevent the mousedown on the calendar causing the input to lose focus
+ event.preventDefault();
+ }
+ isTouchDown = event.type.indexOf('touch') >= 0;
+ var target = $(event.target);
+ var date = target.data(metadata.date);
+ if (date) {
+ module.set.focusDate(date, false, true, true);
+ }
+ },
+ mouseup: function (event) {
+ //ensure input has focus so that it receives keydown events for calendar navigation
+ module.focus();
+ event.preventDefault();
+ event.stopPropagation();
+ isTouchDown = false;
+ var target = $(event.target);
+ if (target.hasClass("disabled")) {
+ return;
+ }
+ var parent = target.parent();
+ if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
+ //clicked on a child element, switch to parent (used when clicking directly on prev/next icon element)
+ target = parent;
+ }
+ var date = target.data(metadata.date);
+ var focusDate = target.data(metadata.focusDate);
+ var mode = target.data(metadata.mode);
+ if (date) {
+ var forceSet = target.hasClass(className.today);
+ module.selectDate(date, forceSet);
+ }
+ else if (focusDate) {
+ module.set.focusDate(focusDate);
+ }
+ else if (mode) {
+ module.set.mode(mode);
+ }
+ },
+ keydown: function (event) {
+ if (event.keyCode === 27 || event.keyCode === 9) {
+ //esc || tab
+ module.popup('hide');
+ }
+
+ if (module.popup('is visible')) {
+ if (event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40) {
+ //arrow keys
+ var mode = module.get.mode();
+ var bigIncrement = mode === 'day' ? 7 : mode === 'hour' ? 4 : mode === 'minute' ? timeGap['column'] : 3;
+ var increment = event.keyCode === 37 ? -1 : event.keyCode === 38 ? -bigIncrement : event.keyCode == 39 ? 1 : bigIncrement;
+ increment *= mode === 'minute' ? settings.minTimeGap : 1;
+ var focusDate = module.get.focusDate() || module.get.date() || new Date();
+ var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
+ var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
+ var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
+ var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
+ var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
+ var newFocusDate = new Date(year, month, day, hour, minute);
+ if (settings.type === 'time') {
+ newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
+ }
+ if (module.helper.isDateInRange(newFocusDate, mode)) {
+ module.set.focusDate(newFocusDate);
+ }
+ } else if (event.keyCode === 13) {
+ //enter
+ var mode = module.get.mode();
+ var date = module.get.focusDate();
+ if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode)) {
+ module.selectDate(date);
+ }
+ //disable form submission:
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if (event.keyCode === 38 || event.keyCode === 40) {
+ //arrow-up || arrow-down
+ event.preventDefault(); //don't scroll
+ module.popup('show');
+ }
+ },
+ inputChange: function () {
+ var val = $input.val();
+ var date = parser.date(val, settings);
+ module.set.date(date, false);
+ },
+ inputFocus: function () {
+ $container.addClass(className.active);
+ },
+ inputBlur: function () {
+ $container.removeClass(className.active);
+ if (settings.formatInput) {
+ var date = module.get.date();
+ var text = formatter.datetime(date, settings);
+ $input.val(text);
+ }
+ },
+ inputClick: function () {
+ module.popup('show');
+ }
+ },
+
+ get: {
+ weekOfYear: function(weekYear,weekMonth,weekDay) {
+ // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
+ var ms1d = 864e5, // milliseconds in a day
+ ms7d = 7 * ms1d; // milliseconds in a week
+
+ return function() { // return a closure so constants get calculated only once
+ var DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an Absolute Day Number
+ AWN = Math.floor(DC3 / 7), // an Absolute Week Number
+ Wyr = new Date(AWN * ms7d).getUTCFullYear();
+
+ return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
+ }();
+ },
+ date: function () {
+ return $module.data(metadata.date) || null;
+ },
+ focusDate: function () {
+ return $module.data(metadata.focusDate) || null;
+ },
+ startDate: function () {
+ var startModule = module.get.calendarModule(settings.startCalendar);
+ return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
+ },
+ endDate: function () {
+ var endModule = module.get.calendarModule(settings.endCalendar);
+ return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
+ },
+ minDate: function() {
+ return $module.data(metadata.minDate) || null;
+ },
+ maxDate: function() {
+ return $module.data(metadata.maxDate) || null;
+ },
+ monthOffset: function () {
+ return $module.data(metadata.monthOffset) || 0;
+ },
+ mode: function () {
+ //only returns valid modes for the current settings
+ var mode = $module.data(metadata.mode) || settings.startMode;
+ var validModes = module.get.validModes();
+ if ($.inArray(mode, validModes) >= 0) {
+ return mode;
+ }
+ return settings.type === 'time' ? 'hour' :
+ settings.type === 'month' ? 'month' :
+ settings.type === 'year' ? 'year' : 'day';
+ },
+ validModes: function () {
+ var validModes = [];
+ if (settings.type !== 'time') {
+ if (!settings.disableYear || settings.type === 'year') {
+ validModes.push('year');
+ }
+ if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
+ validModes.push('month');
+ }
+ if (settings.type.indexOf('date') >= 0) {
+ validModes.push('day');
+ }
+ }
+ if (settings.type.indexOf('time') >= 0) {
+ validModes.push('hour');
+ if (!settings.disableMinute) {
+ validModes.push('minute');
+ }
+ }
+ return validModes;
+ },
+ isTouch: function () {
+ try {
+ document.createEvent('TouchEvent');
+ return true;
+ }
+ catch (e) {
+ return false;
+ }
+ },
+ calendarModule: function (selector) {
+ if (!selector) {
+ return null;
+ }
+ if (!(selector instanceof $)) {
+ selector = $module.parent().children(selector).first();
+ }
+ //assume range related calendars are using the same namespace
+ return selector.data(moduleNamespace);
+ }
+ },
+
+ set: {
+ date: function (date, updateInput, fireChange) {
+ updateInput = updateInput !== false;
+ fireChange = fireChange !== false;
+ date = module.helper.sanitiseDate(date);
+ date = module.helper.dateInRange(date);
+
+ var mode = module.get.mode();
+ var text = formatter.datetime(date, settings);
+ if (fireChange && settings.onChange.call(element, date, text, mode) === false) {
+ return false;
+ }
+
+ module.set.focusDate(date);
+
+ if (settings.isDisabled(date, mode)) {
+ return false;
+ }
+
+ var endDate = module.get.endDate();
+ if (!!endDate && !!date && date > endDate) {
+ //selected date is greater than end date in range, so clear end date
+ module.set.endDate(undefined);
+ }
+ module.set.dataKeyValue(metadata.date, date);
+
+ if (updateInput && $input.length) {
+ $input.val(text);
+ }
+ },
+ startDate: function (date, refreshCalendar) {
+ date = module.helper.sanitiseDate(date);
+ var startModule = module.get.calendarModule(settings.startCalendar);
+ if (startModule) {
+ startModule.set.date(date);
+ }
+ module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
+ },
+ endDate: function (date, refreshCalendar) {
+ date = module.helper.sanitiseDate(date);
+ var endModule = module.get.calendarModule(settings.endCalendar);
+ if (endModule) {
+ endModule.set.date(date);
+ }
+ module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
+ },
+ focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
+ date = module.helper.sanitiseDate(date);
+ date = module.helper.dateInRange(date);
+ var isDay = module.get.mode() === 'day';
+ var oldFocusDate = module.get.focusDate();
+ if (isDay && date && oldFocusDate) {
+ var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
+ var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
+ if (monthDelta) {
+ var monthOffset = module.get.monthOffset() - monthDelta;
+ module.set.monthOffset(monthOffset, false);
+ }
+ }
+ var changed = module.set.dataKeyValue(metadata.focusDate, date, refreshCalendar);
+ updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
+ focusDateUsedForRange = updateRange;
+ if (updateFocus) {
+ module.update.focus(updateRange);
+ }
+ },
+ minDate: function (date) {
+ date = module.helper.sanitiseDate(date);
+ if (settings.maxDate !== null && settings.maxDate <= date) {
+ module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate);
+ } else {
+ module.setting('minDate', date);
+ module.set.dataKeyValue(metadata.minDate, date);
+ }
+ },
+ maxDate: function (date) {
+ date = module.helper.sanitiseDate(date);
+ if (settings.minDate !== null && settings.minDate >= date) {
+ module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate);
+ } else {
+ module.setting('maxDate', date);
+ module.set.dataKeyValue(metadata.maxDate, date);
+ }
+ },
+ monthOffset: function (monthOffset, refreshCalendar) {
+ var multiMonth = Math.max(settings.multiMonth, 1);
+ monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
+ module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
+ },
+ mode: function (mode, refreshCalendar) {
+ module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
+ },
+ dataKeyValue: function (key, value, refreshCalendar) {
+ var oldValue = $module.data(key);
+ var equal = oldValue === value || (oldValue <= value && oldValue >= value); //equality test for dates and string objects
+ if (value) {
+ $module.data(key, value);
+ } else {
+ $module.removeData(key);
+ }
+ refreshCalendar = refreshCalendar !== false && !equal;
+ if (refreshCalendar) {
+ module.refresh();
+ }
+ return !equal;
+ }
+ },
+
+ selectDate: function (date, forceSet) {
+ module.verbose('New date selection', date)
+ var mode = module.get.mode();
+ var complete = forceSet || mode === 'minute' ||
+ (settings.disableMinute && mode === 'hour') ||
+ (settings.type === 'date' && mode === 'day') ||
+ (settings.type === 'month' && mode === 'month') ||
+ (settings.type === 'year' && mode === 'year');
+ if (complete) {
+ var canceled = module.set.date(date) === false;
+ if (!canceled && settings.closable) {
+ module.popup('hide');
+ //if this is a range calendar, show the end date calendar popup and focus the input
+ var endModule = module.get.calendarModule(settings.endCalendar);
+ if (endModule) {
+ endModule.popup('show');
+ endModule.focus();
+ }
+ }
+ } else {
+ var newMode = mode === 'year' ? (!settings.disableMonth ? 'month' : 'day') :
+ mode === 'month' ? 'day' : mode === 'day' ? 'hour' : 'minute';
+ module.set.mode(newMode);
+ if (mode === 'hour' || (mode === 'day' && module.get.date())) {
+ //the user has chosen enough to consider a valid date/time has been chosen
+ module.set.date(date);
+ } else {
+ module.set.focusDate(date);
+ }
+ }
+ },
+
+ changeDate: function (date) {
+ module.set.date(date);
+ },
+
+ clear: function () {
+ module.set.date(undefined);
+ },
+
+ popup: function () {
+ return $activator.popup.apply($activator, arguments);
+ },
+
+ focus: function () {
+ if ($input.length) {
+ $input.focus();
+ } else {
+ $container.focus();
+ }
+ },
+ blur: function () {
+ if ($input.length) {
+ $input.blur();
+ } else {
+ $container.blur();
+ }
+ },
+
+ helper: {
+ isDisabled: function(date, mode) {
+ return mode === 'day' && ((settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function(d){
+ if (d instanceof Date) {
+ return module.helper.dateEqual(date, d, mode);
+ }
+ if (d !== null && typeof d === 'object') {
+ return module.helper.dateEqual(date, d[metadata.date], mode);
+ }
+ }));
+ },
+ disabledReason: function(date, mode) {
+ if (mode === 'day') {
+ for (var i = 0; i < settings.disabledDates.length; i++) {
+ var d = settings.disabledDates[i];
+ if (d !== null && typeof d === 'object' && module.helper.dateEqual(date, d[metadata.date], mode)) {
+ var reason = {};
+ reason[metadata.message] = d[metadata.message];
+ return reason;
+ }
+ }
+ }
+ return null;
+ },
+ sanitiseDate: function (date) {
+ if (!date) {
+ return undefined;
+ }
+ if (!(date instanceof Date)) {
+ date = parser.date('' + date, settings);
+ }
+ if (isNaN(date.getTime())) {
+ return undefined;
+ }
+ return date;
+ },
+ dateDiff: function (date1, date2, mode) {
+ mode = mode || 'day';
+ var isTimeOnly = settings.type === 'time';
+ var isYear = mode === 'year';
+ var isYearOrMonth = isYear || mode === 'month';
+ var isMinute = mode === 'minute';
+ var isHourOrMinute = isMinute || mode === 'hour';
+ //only care about a minute accuracy of settings.minTimeGap
+ date1 = new Date(
+ isTimeOnly ? 2000 : date1.getFullYear(),
+ isTimeOnly ? 0 : isYear ? 0 : date1.getMonth(),
+ isTimeOnly ? 1 : isYearOrMonth ? 1 : date1.getDate(),
+ !isHourOrMinute ? 0 : date1.getHours(),
+ !isMinute ? 0 : settings.minTimeGap * Math.floor(date1.getMinutes() / settings.minTimeGap));
+ date2 = new Date(
+ isTimeOnly ? 2000 : date2.getFullYear(),
+ isTimeOnly ? 0 : isYear ? 0 : date2.getMonth(),
+ isTimeOnly ? 1 : isYearOrMonth ? 1 : date2.getDate(),
+ !isHourOrMinute ? 0 : date2.getHours(),
+ !isMinute ? 0 : settings.minTimeGap * Math.floor(date2.getMinutes() / settings.minTimeGap));
+ return date2.getTime() - date1.getTime();
+ },
+ dateEqual: function (date1, date2, mode) {
+ return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
+ },
+ isDateInRange: function (date, mode, minDate, maxDate) {
+ if (!minDate && !maxDate) {
+ var startDate = module.get.startDate();
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
+ maxDate = settings.maxDate;
+ }
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
+ return !(!date ||
+ (minDate && module.helper.dateDiff(date, minDate, mode) > 0) ||
+ (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
+ },
+ dateInRange: function (date, minDate, maxDate) {
+ if (!minDate && !maxDate) {
+ var startDate = module.get.startDate();
+ minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
+ maxDate = settings.maxDate;
+ }
+ minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
+ var isTimeOnly = settings.type === 'time';
+ return !date ? date :
+ (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0) ?
+ (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) :
+ (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0) ?
+ (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate) :
+ date;
+ },
+ mergeDateTime: function (date, time) {
+ return (!date || !time) ? time :
+ new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
+ }
+ },
+
+ setting: function (name, value) {
+ module.debug('Changing setting', name, value);
+ if ($.isPlainObject(name)) {
+ $.extend(true, settings, name);
+ }
+ else if (value !== undefined) {
+ if ($.isPlainObject(settings[name])) {
+ $.extend(true, settings[name], value);
+ }
+ else {
+ settings[name] = value;
+ }
+ }
+ else {
+ return settings[name];
+ }
+ },
+ internal: function (name, value) {
+ if( $.isPlainObject(name) ) {
+ $.extend(true, module, name);
+ }
+ else if(value !== undefined) {
+ module[name] = value;
+ }
+ else {
+ return module[name];
+ }
+ },
+ debug: function () {
+ if (!settings.silent && settings.debug) {
+ if (settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.debug.apply(console, arguments);
+ }
+ }
+ },
+ verbose: function () {
+ if (!settings.silent && settings.verbose && settings.debug) {
+ if (settings.performance) {
+ module.performance.log(arguments);
+ }
+ else {
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
+ module.verbose.apply(console, arguments);
+ }
+ }
+ },
+ error: function () {
+ if (!settings.silent) {
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
+ module.error.apply(console, arguments);
+ }
+ },
+ performance: {
+ log: function (message) {
+ var
+ currentTime,
+ executionTime,
+ previousTime
+ ;
+ if (settings.performance) {
+ currentTime = new Date().getTime();
+ previousTime = time || currentTime;
+ executionTime = currentTime - previousTime;
+ time = currentTime;
+ performance.push({
+ 'Name': message[0],
+ 'Arguments': [].slice.call(message, 1) || '',
+ 'Element': element,
+ 'Execution Time': executionTime
+ });
+ }
+ clearTimeout(module.performance.timer);
+ module.performance.timer = setTimeout(module.performance.display, 500);
+ },
+ display: function () {
+ var
+ title = settings.name + ':',
+ totalTime = 0
+ ;
+ time = false;
+ clearTimeout(module.performance.timer);
+ $.each(performance, function (index, data) {
+ totalTime += data['Execution Time'];
+ });
+ title += ' ' + totalTime + 'ms';
+ if (moduleSelector) {
+ title += ' \'' + moduleSelector + '\'';
+ }
+ if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) {
+ console.groupCollapsed(title);
+ if (console.table) {
+ console.table(performance);
+ }
+ else {
+ $.each(performance, function (index, data) {
+ console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms');
+ });
+ }
+ console.groupEnd();
+ }
+ performance = [];
+ }
+ },
+ invoke: function (query, passedArguments, context) {
+ var
+ object = instance,
+ maxDepth,
+ found,
+ response
+ ;
+ passedArguments = passedArguments || queryArguments;
+ context = element || context;
+ if (typeof query == 'string' && object !== undefined) {
+ query = query.split(/[\. ]/);
+ maxDepth = query.length - 1;
+ $.each(query, function (depth, value) {
+ var camelCaseValue = (depth != maxDepth)
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
+ : query
+ ;
+ if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) {
+ object = object[camelCaseValue];
+ }
+ else if (object[camelCaseValue] !== undefined) {
+ found = object[camelCaseValue];
+ return false;
+ }
+ else if ($.isPlainObject(object[value]) && (depth != maxDepth)) {
+ object = object[value];
+ }
+ else if (object[value] !== undefined) {
+ found = object[value];
+ return false;
+ }
+ else {
+ module.error(error.method, query);
+ return false;
+ }
+ });
+ }
+ if ($.isFunction(found)) {
+ response = found.apply(context, passedArguments);
+ }
+ else if (found !== undefined) {
+ response = found;
+ }
+ if (Array.isArray(returnedValue)) {
+ returnedValue.push(response);
+ }
+ else if (returnedValue !== undefined) {
+ returnedValue = [returnedValue, response];
+ }
+ else if (response !== undefined) {
+ returnedValue = response;
+ }
+ return found;
+ }
+ };
+
+ if (methodInvoked) {
+ if (instance === undefined) {
+ module.initialize();
+ }
+ module.invoke(query);
+ }
+ else {
+ if (instance !== undefined) {
+ instance.invoke('destroy');
+ }
+ module.initialize();
+ }
+ })
+ ;
+ return (returnedValue !== undefined)
+ ? returnedValue
+ : this
+ ;
+};
+
+$.fn.calendar.settings = {
+
+ name : 'Calendar',
+ namespace : 'calendar',
+
+ silent: false,
+ debug: false,
+ verbose: false,
+ performance: false,
+
+ type : 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
+ firstDayOfWeek : 0, // day for first day column (0 = Sunday)
+ constantHeight : true, // add rows to shorter months to keep day calendar height consistent (6 rows)
+ today : false, // show a 'today/now' button at the bottom of the calendar
+ closable : true, // close the popup after selecting a date/time
+ monthFirst : true, // month before day when parsing/converting date from/to text
+ touchReadonly : true, // set input to readonly on touch devices
+ inline : false, // create the calendar inline instead of inside a popup
+ on : null, // when to show the popup (defaults to 'focus' for input, 'click' for others)
+ initialDate : null, // date to display initially when no date is selected (null = now)
+ startMode : false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
+ minDate : null, // minimum date/time that can be selected, dates/times before are disabled
+ maxDate : null, // maximum date/time that can be selected, dates/times after are disabled
+ ampm : true, // show am/pm in time mode
+ disableYear : false, // disable year selection mode
+ disableMonth : false, // disable month selection mode
+ disableMinute : false, // disable minute selection mode
+ formatInput : true, // format the input text upon input blur and module creation
+ startCalendar : null, // jquery object or selector for another calendar that represents the start date of a date range
+ endCalendar : null, // jquery object or selector for another calendar that represents the end date of a date range
+ multiMonth : 1, // show multiple months when in 'day' mode
+ minTimeGap : 5,
+ showWeekNumbers : null, // show Number of Week at the very first column of a dayView
+ disabledDates : [], // specific day(s) which won't be selectable and contain additional information.
+ disabledDaysOfWeek : [], // day(s) which won't be selectable(s) (0 = Sunday)
+ // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
+ popupOptions: {
+ position: 'bottom left',
+ lastResort: 'bottom left',
+ prefer: 'opposite',
+ hideOnScroll: false
+ },
+
+ text: {
+ days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ today: 'Today',
+ now: 'Now',
+ am: 'AM',
+ pm: 'PM',
+ weekNo: 'Week'
+ },
+
+ formatter: {
+ header: function (date, mode, settings) {
+ return mode === 'year' ? settings.formatter.yearHeader(date, settings) :
+ mode === 'month' ? settings.formatter.monthHeader(date, settings) :
+ mode === 'day' ? settings.formatter.dayHeader(date, settings) :
+ mode === 'hour' ? settings.formatter.hourHeader(date, settings) :
+ settings.formatter.minuteHeader(date, settings);
+ },
+ yearHeader: function (date, settings) {
+ var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
+ return (decadeYear - 9) + ' - ' + (decadeYear + 2);
+ },
+ monthHeader: function (date, settings) {
+ return date.getFullYear();
+ },
+ dayHeader: function (date, settings) {
+ var month = settings.text.months[date.getMonth()];
+ var year = date.getFullYear();
+ return month + ' ' + year;
+ },
+ hourHeader: function (date, settings) {
+ return settings.formatter.date(date, settings);
+ },
+ minuteHeader: function (date, settings) {
+ return settings.formatter.date(date, settings);
+ },
+ dayColumnHeader: function (day, settings) {
+ return settings.text.days[day];
+ },
+ datetime: function (date, settings) {
+ if (!date) {
+ return '';
+ }
+ var day = settings.type === 'time' ? '' : settings.formatter.date(date, settings);
+ var time = settings.type.indexOf('time') < 0 ? '' : settings.formatter.time(date, settings, false);
+ var separator = settings.type === 'datetime' ? ' ' : '';
+ return day + separator + time;
+ },
+ date: function (date, settings) {
+ if (!date) {
+ return '';
+ }
+ var day = date.getDate();
+ var month = settings.text.months[date.getMonth()];
+ var year = date.getFullYear();
+ return settings.type === 'year' ? year :
+ settings.type === 'month' ? month + ' ' + year :
+ (settings.monthFirst ? month + ' ' + day : day + ' ' + month) + ', ' + year;
+ },
+ time: function (date, settings, forCalendar) {
+ if (!date) {
+ return '';
+ }
+ var hour = date.getHours();
+ var minute = date.getMinutes();
+ var ampm = '';
+ if (settings.ampm) {
+ ampm = ' ' + (hour < 12 ? settings.text.am : settings.text.pm);
+ hour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
+ }
+ return hour + ':' + (minute < 10 ? '0' : '') + minute + ampm;
+ },
+ today: function (settings) {
+ return settings.type === 'date' ? settings.text.today : settings.text.now;
+ },
+ cell: function (cell, date, cellOptions) {
+ }
+ },
+
+ parser: {
+ date: function (text, settings) {
+ if (!text) {
+ return null;
+ }
+ text = ('' + text).trim().toLowerCase();
+ if (text.length === 0) {
+ return null;
+ }
+
+ var i, j, k;
+ var minute = -1, hour = -1, day = -1, month = -1, year = -1;
+ var isAm = undefined;
+
+ var isTimeOnly = settings.type === 'time';
+ var isDateOnly = settings.type.indexOf('time') < 0;
+
+ var words = text.split(settings.regExp.dateWords);
+ var numbers = text.split(settings.regExp.dateNumbers);
+
+ if (!isDateOnly) {
+ //am/pm
+ isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0 ? true :
+ $.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined;
+
+ //time with ':'
+ for (i = 0; i < numbers.length; i++) {
+ var number = numbers[i];
+ if (number.indexOf(':') >= 0) {
+ if (hour < 0 || minute < 0) {
+ var parts = number.split(':');
+ for (k = 0; k < Math.min(2, parts.length); k++) {
+ j = parseInt(parts[k]);
+ if (isNaN(j)) {
+ j = 0;
+ }
+ if (k === 0) {
+ hour = j % 24;
+ } else {
+ minute = j % 60;
+ }
+ }
+ }
+ numbers.splice(i, 1);
+ }
+ }
+ }
+
+ if (!isTimeOnly) {
+ //textual month
+ for (i = 0; i < words.length; i++) {
+ var word = words[i];
+ if (word.length <= 0) {
+ continue;
+ }
+ word = word.substring(0, Math.min(word.length, 3));
+ for (j = 0; j < settings.text.months.length; j++) {
+ var monthString = settings.text.months[j];
+ monthString = monthString.substring(0, Math.min(word.length, Math.min(monthString.length, 3))).toLowerCase();
+ if (monthString === word) {
+ month = j + 1;
+ break;
+ }
+ }
+ if (month >= 0) {
+ break;
+ }
+ }
+
+ //year > 59
+ for (i = 0; i < numbers.length; i++) {
+ j = parseInt(numbers[i]);
+ if (isNaN(j)) {
+ continue;
+ }
+ if (j > 59) {
+ year = j;
+ numbers.splice(i, 1);
+ break;
+ }
+ }
+
+ //numeric month
+ if (month < 0) {
+ for (i = 0; i < numbers.length; i++) {
+ k = i > 1 || settings.monthFirst ? i : i === 1 ? 0 : 1;
+ j = parseInt(numbers[k]);
+ if (isNaN(j)) {
+ continue;
+ }
+ if (1 <= j && j <= 12) {
+ month = j;
+ numbers.splice(k, 1);
+ break;
+ }
+ }
+ }
+
+ //day
+ for (i = 0; i < numbers.length; i++) {
+ j = parseInt(numbers[i]);
+ if (isNaN(j)) {
+ continue;
+ }
+ if (1 <= j && j <= 31) {
+ day = j;
+ numbers.splice(i, 1);
+ break;
+ }
+ }
+
+ //year <= 59
+ if (year < 0) {
+ for (i = numbers.length - 1; i >= 0; i--) {
+ j = parseInt(numbers[i]);
+ if (isNaN(j)) {
+ continue;
+ }
+ if (j < 99) {
+ j += 2000;
+ }
+ year = j;
+ numbers.splice(i, 1);
+ break;
+ }
+ }
+ }
+
+ if (!isDateOnly) {
+ //hour
+ if (hour < 0) {
+ for (i = 0; i < numbers.length; i++) {
+ j = parseInt(numbers[i]);
+ if (isNaN(j)) {
+ continue;
+ }
+ if (0 <= j && j <= 23) {
+ hour = j;
+ numbers.splice(i, 1);
+ break;
+ }
+ }
+ }
+
+ //minute
+ if (minute < 0) {
+ for (i = 0; i < numbers.length; i++) {
+ j = parseInt(numbers[i]);
+ if (isNaN(j)) {
+ continue;
+ }
+ if (0 <= j && j <= 59) {
+ minute = j;
+ numbers.splice(i, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
+ return null;
+ }
+
+ if (minute < 0) {
+ minute = 0;
+ }
+ if (hour < 0) {
+ hour = 0;
+ }
+ if (day < 0) {
+ day = 1;
+ }
+ if (month < 0) {
+ month = 1;
+ }
+ if (year < 0) {
+ year = new Date().getFullYear();
+ }
+
+ if (isAm !== undefined) {
+ if (isAm) {
+ if (hour === 12) {
+ hour = 0;
+ }
+ } else if (hour < 12) {
+ hour += 12;
+ }
+ }
+
+ var date = new Date(year, month - 1, day, hour, minute);
+ if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
+ //month or year don't match up, switch to last day of the month
+ date = new Date(year, month, 0, hour, minute);
+ }
+ return isNaN(date.getTime()) ? null : date;
+ }
+ },
+
+ // callback when date changes, return false to cancel the change
+ onChange: function (date, text, mode) {
+ return true;
+ },
+
+ // callback before show animation, return false to prevent show
+ onShow: function () {
+ },
+
+ // callback after show animation
+ onVisible: function () {
+ },
+
+ // callback before hide animation, return false to prevent hide
+ onHide: function () {
+ },
+
+ // callback after hide animation
+ onHidden: function () {
+ },
+
+ // is the given date disabled?
+ isDisabled: function (date, mode) {
+ return false;
+ },
+
+ selector: {
+ popup: '.ui.popup',
+ input: 'input',
+ activator: 'input'
+ },
+
+ regExp: {
+ dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
+ dateNumbers: /[^\d:]+/g
+ },
+
+ error: {
+ popup: 'UI Popup, a required component is not included in this page',
+ method: 'The method you called is not defined.'
+ },
+
+ className: {
+ calendar: 'calendar',
+ active: 'active',
+ popup: 'ui popup',
+ grid: 'ui equal width grid',
+ column: 'column',
+ table: 'ui celled center aligned unstackable table',
+ prev: 'prev link',
+ next: 'next link',
+ prevIcon: 'chevron left icon',
+ nextIcon: 'chevron right icon',
+ link: 'link',
+ cell: 'link',
+ disabledCell: 'disabled',
+ adjacentCell: 'adjacent',
+ activeCell: 'active',
+ rangeCell: 'range',
+ focusCell: 'focus',
+ todayCell: 'today',
+ today: 'today link'
+ },
+
+ metadata: {
+ date: 'date',
+ focusDate: 'focusDate',
+ startDate: 'startDate',
+ endDate: 'endDate',
+ minDate: 'minDate',
+ maxDate: 'maxDate',
+ mode: 'mode',
+ monthOffset: 'monthOffset',
+ message: 'message'
+ }
+};
+
+})(jQuery, window, document);
+
+/*!
+ * # Semantic UI 2.7.1 - Checkbox
+ * http://github.com/semantic-org/semantic-ui/
+ *
+ *
+ * Released under the MIT license
+ * http://opensource.org/licenses/MIT
+ *
+ */
+
+;(function ($, window, document, undefined) {
+
+'use strict';
+
+$.isFunction = $.isFunction || function(obj) {
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+};
+
+window = (typeof window != 'undefined' && window.Math == Math)
+ ? window
+ : (typeof self != 'undefined' && self.Math == Math)
+ ? self
+ : Function('return this')()
+;
+
+$.fn.checkbox = function(parameters) {
+ var
+ $allModules = $(this),
+ moduleSelector = $allModules.selector || '',
+
+ time = new Date().getTime(),
+ performance = [],
+
+ query = arguments[0],
+ methodInvoked = (typeof query == 'string'),
+ queryArguments = [].slice.call(arguments, 1),
+ returnedValue
+ ;
+
+ $allModules
+ .each(function() {
+ var
+ settings = $.extend(true, {}, $.fn.checkbox.settings, parameters),
+
+ className = settings.className,
+ namespace = settings.namespace,
+ selector = settings.selector,
+ error = settings.error,
+
+ eventNamespace = '.' + namespace,
+ moduleNamespace = 'module-' + namespace,
+
+ $module = $(this),
+ $label = $(this).children(selector.label),
+ $input = $(this).children(selector.input),
+ input = $input[0],
+
+ initialLoad = false,
+ shortcutPressed = false,
+ instance = $module.data(moduleNamespace),
+
+ observer,
+ element = this,
+ module
+ ;
+
+ module = {
+
+ initialize: function() {
+ module.verbose('Initializing checkbox', settings);
+
+ module.create.label();
+ module.bind.events();
+
+ module.set.tabbable();
+ module.hide.input();
+
+ module.observeChanges();
+ module.instantiate();
+ module.setup();
+ },
+
+ instantiate: function() {
+ module.verbose('Storing instance of module', module);
+ instance = module;
+ $module
+ .data(moduleNamespace, module)
+ ;
+ },
+
+ destroy: function() {
+ module.verbose('Destroying module');
+ module.unbind.events();
+ module.show.input();
+ $module.removeData(moduleNamespace);
+ },
+
+ fix: {
+ reference: function() {
+ if( $module.is(selector.input) ) {
+ module.debug('Behavior called on adjusting invoked element');
+ $module = $module.closest(selector.checkbox);
+ module.refresh();
+ }
+ }
+ },
+
+ setup: function() {
+ module.set.initialLoad();
+ if( module.is.indeterminate() ) {
+ module.debug('Initial value is indeterminate');
+ module.indeterminate();
+ }
+ else if( module.is.checked() ) {
+ module.debug('Initial value is checked');
+ module.check();
+ }
+ else {
+ module.debug('Initial value is unchecked');
+ module.uncheck();
+ }
+ module.remove.initialLoad();
+ },
+
+ refresh: function() {
+ $label = $module.children(selector.label);
+ $input = $module.children(selector.input);
+ input = $input[0];
+ },
+
+ hide: {
+ input: function() {
+ module.verbose('Modifying z-index to be unselectable');
+ $input.addClass(className.hidden);
+ }
+ },
+ show: {
+ input: function() {
+ module.verbose('Modifying z-index to be selectable');
+ $input.removeClass(className.hidden);
+ }
+ },
+
+ observeChanges: function() {
+ if('MutationObserver' in window) {
+ observer = new MutationObserver(function(mutations) {
+ module.debug('DOM tree modified, updating selector cache');
+ module.refresh();
+ });
+ observer.observe(element, {
+ childList : true,
+ subtree : true
+ });
+ module.debug('Setting up mutation observer', observer);
+ }
+ },
+
+ attachEvents: function(selector, event) {
+ var
+ $element = $(selector)
+ ;
+ event = $.isFunction(module[event])
+ ? module[event]
+ : module.toggle
+ ;
+ if($element.length > 0) {
+ module.debug('Attaching checkbox events to element', selector, event);
+ $element
+ .on('click' + eventNamespace, event)
+ ;
+ }
+ else {
+ module.error(error.notFound);
+ }
+ },
+
+ event: {
+ change: function(event) {
+ if( !module.should.ignoreCallbacks() ) {
+ settings.onChange.call(input);
+ }
+ },
+ click: function(event) {
+ var
+ $target = $(event.target)
+ ;
+ if( $target.is(selector.input) ) {
+ module.verbose('Using default check action on initialized checkbox');
+ return;
+ }
+ if( $target.is(selector.link) ) {
+ module.debug('Clicking link inside checkbox, skipping toggle');
+ return;
+ }
+ module.toggle();
+ $input.focus();
+ event.preventDefault();
+ },
+ keydown: function(event) {
+ var
+ key = event.which,
+ keyCode = {
+ enter : 13,
+ space : 32,
+ escape : 27,
+ left : 37,
+ up : 38,
+ right : 39,
+ down : 40
+ }
+ ;
+
+ var r = module.get.radios(),
+ rIndex = r.index($module),
+ rLen = r.length,
+ checkIndex = false;
+
+ if(key == keyCode.left || key == keyCode.up) {
+ checkIndex = (rIndex === 0 ? rLen : rIndex) - 1;
+ } else if(key == keyCode.right || key == keyCode.down) {
+ checkIndex = rIndex === rLen-1 ? 0 : rIndex+1;
+ }
+
+ if (!module.should.ignoreCallbacks() && checkIndex !== false) {
+ if(!settings.beforeUnchecked.apply(input)) {
+ module.verbose('Option not allowed to be unchecked, cancelling key navigation');
+ return false;
+ }
+ if (!settings.beforeChecked.apply($(r[checkIndex]).children(selector.input)[0])) {
+ module.verbose('Next option should not allow check, cancelling key navigation');
+ return false;
+ }
+ }
+
+ if(key == keyCode.escape) {
+ module.verbose('Escape key pressed blurring field');
+ $input.blur();
+ shortcutPressed = true;
+ }
+ else if(!event.ctrlKey && ( key == keyCode.space || key == keyCode.enter) ) {
+ module.verbose('Enter/space key pressed, toggling checkbox');
+ module.toggle();
+ shortcutPressed = true;
+ }
+ else {
+ shortcutPressed = false;
+ }
+ },
+ keyup: function(event) {
+ if(shortcutPressed) {
+ event.preventDefault();
+ }
+ }
+ },
+
+ check: function() {
+ if( !module.should.allowCheck() ) {
+ return;
+ }
+ module.debug('Checking checkbox', $input);
+ module.set.checked();
+ if( !module.should.ignoreCallbacks() ) {
+ settings.onChecked.call(input);
+ settings.onChange.call(input);
+ }
+ },
+
+ uncheck: function() {
+ if( !module.should.allowUncheck() ) {
+ return;
+ }
+ module.debug('Unchecking checkbox');
+ module.set.unchecked();
+ if( !module.should.ignoreCallbacks() ) {
+ settings.onUnchecked.call(input);
+ settings.onChange.call(input);
+ }
+ },
+
+ indeterminate: function() {
+ if( module.should.allowIndeterminate() ) {
+ module.debug('Checkbox is already indeterminate');
+ return;
+ }
+ module.debug('Making checkbox indeterminate');
+ module.set.indeterminate();
+ if( !module.should.ignoreCallbacks() ) {
+ settings.onIndeterminate.call(input);
+ settings.onChange.call(input);
+ }
+ },
+
+ determinate: function() {
+ if( module.should.allowDeterminate() ) {
+ module.debug('Checkbox is already determinate');
+ return;
+ }
+ module.debug('Making checkbox determinate');
+ module.set.determinate();
+ if( !module.should.ignoreCallbacks() ) {
+ settings.onDeterminate.call(input);
+ settings.onChange.call(input);
+ }
+ },
+
+ enable: function() {
+ if( module.is.enabled() ) {
+ module.debug('Checkbox is already enabled');
+ return;
+ }
+ module.debug('Enabling checkbox');
+ module.set.enabled();
+ settings.onEnable.call(input);
+ // preserve legacy callbacks
+ settings.onEnabled.call(input);
+ },
+
+ disable: function() {
+ if( module.is.disabled() ) {
+ module.debug('Checkbox is already disabled');
+ return;
+ }
+ module.debug('Disabling checkbox');
+ module.set.disabled();
+ settings.onDisable.call(input);
+ // preserve legacy callbacks
+ settings.onDisabled.call(input);
+ },
+
+ get: {
+ radios: function() {
+ var
+ name = module.get.name()
+ ;
+ return $('input[name="' + name + '"]').closest(selector.checkbox);
+ },
+ otherRadios: function() {
+ return module.get.radios().not($module);
+ },
+ name: function() {
+ return $input.attr('name');
+ }
+ },
+
+ is: {
+ initialLoad: function() {
+ return initialLoad;
+ },
+ radio: function() {
+ return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
+ },
+ indeterminate: function() {
+ return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
+ },
+ checked: function() {
+ return $input.prop('checked') !== undefined && $input.prop('checked');
+ },
+ disabled: function() {
+ return $input.prop('disabled') !== undefined && $input.prop('disabled');
+ },
+ enabled: function() {
+ return !module.is.disabled();
+ },
+ determinate: function() {
+ return !module.is.indeterminate();
+ },
+ unchecked: function() {
+ return !module.is.checked();
+ }
+ },
+
+ should: {
+ allowCheck: function() {
+ if(module.is.determinate() && module.is.checked() && !module.is.initialLoad() ) {
+ module.debug('Should not allow check, checkbox is already checked');
+ return false;
+ }
+ if(!module.should.ignoreCallbacks() && settings.beforeChecked.apply(input) === false) {
+ module.debug('Should not allow check, beforeChecked cancelled');
+ return false;
+ }
+ return true;
+ },
+ allowUncheck: function() {
+ if(module.is.determinate() && module.is.unchecked() && !module.is.initialLoad() ) {
+ module.debug('Should not allow uncheck, checkbox is already unchecked');
+ return false;
+ }
+ if(!module.should.ignoreCallbacks() && settings.beforeUnchecked.apply(input) === false) {
+ module.debug('Should not allow uncheck, beforeUnchecked cancelled');
+ return false;
+ }
+ return true;
+ },
+ allowIndeterminate: function() {
+ if(module.is.indeterminate() && !module.is.initialLoad() ) {
+ module.debug('Should not allow indeterminate, checkbox is already indeterminate');
+ return false;
+ }
+ if(!module.should.ignoreCallbacks() && settings.beforeIndeterminate.apply(input) === false) {
+ module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
+ return false;
+ }
+ return true;
+ },
+ allowDeterminate: function() {
+ if(module.is.determinate() && !module.is.initialLoad() ) {
+ module.debug('Should not allow determinate, checkbox is already determinate');
+ return false;
+ }
+ if(!module.should.ignoreCallbacks() && settings.beforeDeterminate.apply(input) === false) {
+ module.debug('Should not allow determinate, beforeDeterminate cancelled');
+ return false;
+ }
+ return true;
+ },
+ ignoreCallbacks: function() {
+ return (initialLoad && !settings.fireOnInit);
+ }
+ },
+
+ can: {
+ change: function() {
+ return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
+ },
+ uncheck: function() {
+ return (typeof settings.uncheckable === 'boolean')
+ ? settings.uncheckable
+ : !module.is.radio()
+ ;
+ }
+ },
+
+ set: {
+ initialLoad: function() {
+ initialLoad = true;
+ },
+ checked: function() {
+ module.verbose('Setting class to checked');
+ $module
+ .removeClass(className.indeterminate)
+ .addClass(className.checked)
+ ;
+ if( module.is.radio() ) {
+ module.uncheckOthers();
+ }
+ if(!module.is.indeterminate() && module.is.checked()) {
+ module.debug('Input is already checked, skipping input property change');
+ return;
+ }
+ module.verbose('Setting state to checked', input);
+ $input
+ .prop('indeterminate', false)
+ .prop('checked', true)
+ ;
+ module.trigger.change();
+ },
+ unchecked: function() {
+ module.verbose('Removing checked class');
+ $module
+ .removeClass(className.indeterminate)
+ .removeClass(className.checked)
+ ;
+ if(!module.is.indeterminate() && module.is.unchecked() ) {
+ module.debug('Input is already unchecked');
+ return;
+ }
+ module.debug('Setting state to unchecked');
+ $input
+ .prop('indeterminate', false)
+ .prop('checked', false)
+ ;
+ module.trigger.change();
+ },
+ indeterminate: function() {
+ module.verbose('Setting class to indeterminate');
+ $module
+ .addClass(className.indeterminate)
+ ;
+ if( module.is.indeterminate() ) {
+ module.debug('Input is already indeterminate, skipping input property change');
+ return;
+ }
+ module.debug('Setting state to indeterminate');
+ $input
+ .prop('indeterminate', true)
+ ;
+ module.trigger.change();
+ },
+ determinate: function() {
+ module.verbose('Removing indeterminate class');
+ $module
+ .removeClass(className.indeterminate)
+ ;
+ if( module.is.determinate() ) {
+ module.debug('Input is already determinate, skipping input property change');
+ return;
+ }
+ module.debug('Setting state to determinate');
+ $input
+ .prop('indeterminate', false)
+ ;
+ },
+ disabled: function() {
+ module.verbose('Setting class to disabled');
+ $module
+ .addClass(className.disabled)
+ ;
+ if( module.is.disabled() ) {
+ module.debug('Input is already disabled, skipping input property change');
+ return;
+ }
+ module.debug('Setting state to disabled');
+ $input
+ .prop('disabled', 'disabled')
+ ;
+ module.trigger.change();
+ },
+ enabled: function() {
+ module.verbose('Removing disabled class');
+ $module.removeClass(className.disabled);
+ if( module.is.enabled() ) {
+ module.debug('Input is already enabled, skipping input property change');
+ return;
+ }
+ module.debug('Setting state to enabled');
+ $input
+ .prop('disabled', false)
+ ;
+ module.trigger.change();
+ },
+ tabbable: function() {
+ module.verbose('Adding tabindex to checkbox');
+ if( $input.attr('tabindex') === undefined) {
+ $input.attr('tabindex', 0);
+ }
+ }
+ },
+
+ remove: {
+ initialLoad: function() {
+ initialLoad = false;
+ }
+ },
+
+ trigger: {
+ change: function() {
+ var
+ events = document.createEvent('HTMLEvents'),
+ inputElement = $input[0]
+ ;
+ if(inputElement) {
+ module.verbose('Triggering native change event');
+ events.initEvent('change', true, false);
+ inputElement.dispatchEvent(events);
+ }
+ }
+ },
+
+
+ create: {
+ label: function() {
+ if($input.prevAll(selector.label).length > 0) {
+ $input.prev(selector.label).detach().insertAfter($input);
+ module.debug('Moving existing label', $label);
+ }
+ else if( !module.has.label() ) {
+ $label = $('