/* Minification failed. Returning unminified contents.
(984,3-11): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: goToPage
 */
/**
 * jquery.mask.js
 * @version: v1.13.4
 * @author: Igor Escobar
 *
 * Created by Igor Escobar on 2012-03-10. Please report any bug at http://blog.igorescobar.com
 *
 * Copyright (c) 2012 Igor Escobar http://blog.igorescobar.com
 *
 * The MIT License (http://www.opensource.org/licenses/mit-license.php)
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/* jshint laxbreak: true */
/* global define, jQuery, Zepto */

'use strict';

// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
(function (factory) {

	if (typeof define === 'function' && define.amd) {
		define(['jquery'], factory);
	} else if (typeof exports === 'object') {
		module.exports = factory(require('jquery'));
	} else {
		factory(jQuery || Zepto);
	}

}(function ($) {

	var Mask = function (el, mask, options) {
		el = $(el);

		var jMask = this, oldValue = el.val(), regexMask;

		mask = typeof mask === 'function' ? mask(el.val(), undefined, el, options) : mask;

		var p = {
			invalid: [],
			getCaret: function () {
				try {
					var sel,
							pos = 0,
							ctrl = el.get(0),
							dSel = document.selection,
							cSelStart = ctrl.selectionStart;

					// IE Support
					if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
						sel = dSel.createRange();
						sel.moveStart('character', el.is('input') ? -el.val().length : -el.text().length);
						pos = sel.text.length;
					}
						// Firefox support
					else if (cSelStart || cSelStart === '0') {
						pos = cSelStart;
					}

					return pos;
				} catch (e) { }
			},
			setCaret: function (pos) {
				try {
					if (el.is(':focus')) {
						var range, ctrl = el.get(0);

						if (ctrl.setSelectionRange) {
							ctrl.setSelectionRange(pos, pos);
						} else if (ctrl.createTextRange) {
							range = ctrl.createTextRange();
							range.collapse(true);
							range.moveEnd('character', pos);
							range.moveStart('character', pos);
							range.select();
						}
					}
				} catch (e) { }
			},
			events: function () {
				el
				.on('input.mask keyup.mask', p.behaviour)
				.on('paste.mask drop.mask', function () {
					setTimeout(function () {
						el.keydown().keyup();
					}, 100);
				})
				.on('change.mask', function () {
					el.data('changed', true);
				})
				.on('blur.mask', function () {
					if (oldValue !== el.val() && !el.data('changed')) {
						el.triggerHandler('change');
					}
					el.data('changed', false);
				})
				// it's very important that this callback remains in this position
				// otherwhise oldValue it's going to work buggy
				.on('blur.mask', function () {
					oldValue = el.val();
				})
				// select all text on focus
				.on('focus.mask', function (e) {
					if (options.selectOnFocus === true) {
						$(e.target).select();
					}
				})
				// clear the value if it not complete the mask
				.on('focusout.mask', function () {
					if (options.clearIfNotMatch && !regexMask.test(p.val())) {
						p.val('');
					}
				});
			},
			getRegexMask: function () {
				var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;

				for (var i = 0; i < mask.length; i++) {
					translation = jMask.translation[mask.charAt(i)];

					if (translation) {

						pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, '');
						optional = translation.optional;
						recursive = translation.recursive;

						if (recursive) {
							maskChunks.push(mask.charAt(i));
							oRecursive = { digit: mask.charAt(i), pattern: pattern };
						} else {
							maskChunks.push(!optional && !recursive ? pattern : (pattern + '?'));
						}

					} else {
						maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
					}
				}

				r = maskChunks.join('');

				if (oRecursive) {
					r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?')
							 .replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern);
				}

				return new RegExp(r);
			},
			destroyEvents: function () {
				el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
			},
			val: function (v) {
				var isInput = el.is('input'),
						method = isInput ? 'val' : 'text',
						r;

				if (arguments.length > 0) {
					if (el[method]() !== v) {
						el[method](v);
					}
					r = el;
				} else {
					r = el[method]();
				}

				return r;
			},
			getMCharsBeforeCount: function (index, onCleanVal) {
				for (var count = 0, i = 0, maskL = mask.length; i < maskL && i < index; i++) {
					if (!jMask.translation[mask.charAt(i)]) {
						index = onCleanVal ? index + 1 : index;
						count++;
					}
				}
				return count;
			},
			caretPos: function (originalCaretPos, oldLength, newLength, maskDif) {
				var translation = jMask.translation[mask.charAt(Math.min(originalCaretPos - 1, mask.length - 1))];

				return !translation ? p.caretPos(originalCaretPos + 1, oldLength, newLength, maskDif)
														: Math.min(originalCaretPos + newLength - oldLength - maskDif, newLength);
			},
			behaviour: function (e) {
				e = e || window.event;
				p.invalid = [];
				var keyCode = e.keyCode || e.which;
				if ($.inArray(keyCode, jMask.byPassKeys) === -1) {

					var caretPos = p.getCaret(),
							currVal = p.val(),
							currValL = currVal.length,
							changeCaret = caretPos < currValL,
							newVal = p.getMasked(),
							newValL = newVal.length,
							maskDif = p.getMCharsBeforeCount(newValL - 1) - p.getMCharsBeforeCount(currValL - 1);

					p.val(newVal);

					// change caret but avoid CTRL+A
					if (changeCaret && !(keyCode === 65 && e.ctrlKey)) {
						// Avoid adjusting caret on backspace or delete
						if (!(keyCode === 8 || keyCode === 46)) {
							caretPos = p.caretPos(caretPos, currValL, newValL, maskDif);
						}
						p.setCaret(caretPos);
					}

					return p.callbacks(e);
				}
			},
			getMasked: function (skipMaskChars) {
				var buf = [],
						value = p.val(),
						m = 0, maskLen = mask.length,
						v = 0, valLen = value.length,
						offset = 1, addMethod = 'push',
						resetPos = -1,
						lastMaskChar,
						check;

				if (options.reverse) {
					addMethod = 'unshift';
					offset = -1;
					lastMaskChar = 0;
					m = maskLen - 1;
					v = valLen - 1;
					check = function () {
						return m > -1 && v > -1;
					};
				} else {
					lastMaskChar = maskLen - 1;
					check = function () {
						return m < maskLen && v < valLen;
					};
				}

				while (check()) {
					var maskDigit = mask.charAt(m),
							valDigit = value.charAt(v),
							translation = jMask.translation[maskDigit];

					if (translation) {
						if (valDigit.match(translation.pattern)) {
							buf[addMethod](valDigit);
							if (translation.recursive) {
								if (resetPos === -1) {
									resetPos = m;
								} else if (m === lastMaskChar) {
									m = resetPos - offset;
								}

								if (lastMaskChar === resetPos) {
									m -= offset;
								}
							}
							m += offset;
						} else if (translation.optional) {
							m += offset;
							v -= offset;
						} else if (translation.fallback) {
							buf[addMethod](translation.fallback);
							m += offset;
							v -= offset;
						} else {
							p.invalid.push({ p: v, v: valDigit, e: translation.pattern });
						}
						v += offset;
					} else {
						if (!skipMaskChars) {
							buf[addMethod](maskDigit);
						}

						if (valDigit === maskDigit) {
							v += offset;
						}

						m += offset;
					}
				}

				var lastMaskCharDigit = mask.charAt(lastMaskChar);
				if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
					buf.push(lastMaskCharDigit);
				}

				return buf.join('');
			},
			callbacks: function (e) {
				var val = p.val(),
						changed = val !== oldValue,
						defaultArgs = [val, e, el, options],
						callback = function (name, criteria, args) {
							if (typeof options[name] === 'function' && criteria) {
								options[name].apply(this, args);
							}
						};

				callback('onChange', changed === true, defaultArgs);
				callback('onKeyPress', changed === true, defaultArgs);
				callback('onComplete', val.length === mask.length, defaultArgs);
				callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
			}
		};


		// public methods
		jMask.mask = mask;
		jMask.options = options;
		jMask.remove = function () {
			var caret = p.getCaret();
			p.destroyEvents();
			p.val(jMask.getCleanVal());
			p.setCaret(caret - p.getMCharsBeforeCount(caret));
			return el;
		};

		// get value without mask
		jMask.getCleanVal = function () {
			return p.getMasked(true);
		};

		jMask.init = function (onlyMask) {
			onlyMask = onlyMask || false;
			options = options || {};

			jMask.byPassKeys = $.jMaskGlobals.byPassKeys;
			jMask.translation = $.jMaskGlobals.translation;

			jMask.translation = $.extend({}, jMask.translation, options.translation);
			jMask = $.extend(true, {}, jMask, options);

			regexMask = p.getRegexMask();

			if (onlyMask === false) {

				if (options.placeholder) {
					el.attr('placeholder', options.placeholder);
				}

				// this is necessary, otherwise if the user submit the form
				// and then press the "back" button, the autocomplete will erase
				// the data. Works fine on IE9+, FF, Opera, Safari.
				if ($('input').length && 'oninput' in $('input')[0] === false && el.attr('autocomplete') === 'on') {
					el.attr('autocomplete', 'off');
				}

				p.destroyEvents();
				p.events();

				var caret = p.getCaret();
				p.val(p.getMasked());
				p.setCaret(caret + p.getMCharsBeforeCount(caret, true));

			} else {
				p.events();
				p.val(p.getMasked());
			}
		};

		jMask.init(!el.is('input'));
	};

	$.maskWatchers = {};
	var HTMLAttributes = function () {
		var input = $(this),
				options = {},
				prefix = 'data-mask-',
				mask = input.attr('data-mask');

		if (input.attr(prefix + 'reverse')) {
			options.reverse = true;
		}

		if (input.attr(prefix + 'clearifnotmatch')) {
			options.clearIfNotMatch = true;
		}

		if (input.attr(prefix + 'selectonfocus') === 'true') {
			options.selectOnFocus = true;
		}

		if (notSameMaskObject(input, mask, options)) {
			return input.data('mask', new Mask(this, mask, options));
		}
	},
			notSameMaskObject = function (field, mask, options) {
				options = options || {};
				var maskObject = $(field).data('mask'),
						stringify = JSON.stringify,
						value = $(field).val() || $(field).text();
				try {
					if (typeof mask === 'function') {
						mask = mask(value);
					}
					return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
				} catch (e) { }
			};


	$.fn.mask = function (mask, options) {
		options = options || {};
		var selector = this.selector,
				globals = $.jMaskGlobals,
				interval = $.jMaskGlobals.watchInterval,
				maskFunction = function () {
					if (notSameMaskObject(this, mask, options)) {
						return $(this).data('mask', new Mask(this, mask, options));
					}
				};

		$(this).each(maskFunction);

		if (selector && selector !== '' && globals.watchInputs) {
			clearInterval($.maskWatchers[selector]);
			$.maskWatchers[selector] = setInterval(function () {
				$(document).find(selector).each(maskFunction);
			}, interval);
		}
		return this;
	};

	$.fn.unmask = function () {
		clearInterval($.maskWatchers[this.selector]);
		delete $.maskWatchers[this.selector];
		return this.each(function () {
			var dataMask = $(this).data('mask');
			if (dataMask) {
				dataMask.remove().removeData('mask');
			}
		});
	};

	$.fn.cleanVal = function () {
		return this.data('mask').getCleanVal();
	};

	$.applyDataMask = function (selector) {
		selector = selector || $.jMaskGlobals.maskElements;
		var $selector = (selector instanceof $) ? selector : $(selector);
		$selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes);
	};

	var globals = {
		maskElements: 'input,td,span,div',
		dataMaskAttr: '*[data-mask]',
		dataMask: true,
		watchInterval: 300,
		watchInputs: true,
		watchDataMask: false,
		byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
		translation: {
			'0': { pattern: /\d/ },
			'9': { pattern: /\d/, optional: true },
			'#': { pattern: /\d/, recursive: true },
			'A': { pattern: /[a-zA-Z0-9]/ },
			'S': { pattern: /[a-zA-Z]/ }
		}
	};

	$.jMaskGlobals = $.jMaskGlobals || {};
	globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);

	// looking for inputs with data-mask attribute
	if (globals.dataMask) { $.applyDataMask(); }

	setInterval(function () {
		if ($.jMaskGlobals.watchDataMask) { $.applyDataMask(); }
	}, globals.watchInterval);
}));
;
/*
 *
 * Copyright (c) 2006-2014 Sam Collett (http://www.texotela.co.uk)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Version 1.4.1
 * Demo: http://www.texotela.co.uk/code/jquery/numeric/
 *
 */
(function ($) {
	/*
	 * Allows only valid characters to be entered into input boxes.
	 * Note: fixes value when pasting via Ctrl+V, but not when using the mouse to paste
		*      side-effect: Ctrl+A does not work, though you can still use the mouse to select (or double-click to select all)
	 *
	 * @name     numeric
	 * @param    config      { decimal : "." , negative : true }
	 * @param    callback     A function that runs if the number is not valid (fires onblur)
	 * @author   Sam Collett (http://www.texotela.co.uk)
	 * @example  $(".numeric").numeric();
	 * @example  $(".numeric").numeric(","); // use , as separator
	 * @example  $(".numeric").numeric({ decimal : "," }); // use , as separator
	 * @example  $(".numeric").numeric({ negative : false }); // do not allow negative values
	 * @example  $(".numeric").numeric({ decimalPlaces : 2 }); // only allow 2 decimal places
	 * @example  $(".numeric").numeric(null, callback); // use default values, pass on the 'callback' function
	 *
	 */
	$.fn.numeric = function (config, callback) {
		if (typeof config === 'boolean') {
			config = { decimal: config, negative: true, decimalPlaces: -1 };
		}
		config = config || {};
		// if config.negative undefined, set to true (default is to allow negative numbers)
		if (typeof config.negative == "undefined") { config.negative = true; }
		// set decimal point
		var decimal = (config.decimal === false) ? "" : config.decimal || ".";
		// allow negatives
		var negative = (config.negative === true) ? true : false;
		// set decimal places
		var decimalPlaces = (typeof config.decimalPlaces == "undefined") ? -1 : config.decimalPlaces;
		// callback function
		callback = (typeof (callback) == "function" ? callback : function () { });
		// set data and methods
		return this.data("numeric.decimal", decimal).data("numeric.negative", negative).data("numeric.callback", callback).data("numeric.decimalPlaces", decimalPlaces).keypress($.fn.numeric.keypress).keyup($.fn.numeric.keyup).blur($.fn.numeric.blur);
	};

	$.fn.numeric.keypress = function (e) {
		// get decimal character and determine if negatives are allowed
		var decimal = $.data(this, "numeric.decimal");
		var negative = $.data(this, "numeric.negative");
		var decimalPlaces = $.data(this, "numeric.decimalPlaces");
		// get the key that was pressed
		var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
		// allow enter/return key (only when in an input box)
		if (key == 13 && this.nodeName.toLowerCase() == "input") {
			return true;
		}
		else if (key == 13) {
			return false;
		}
		var allow = false;
		// allow Ctrl+A
		if ((e.ctrlKey && key == 97 /* firefox */) || (e.ctrlKey && key == 65) /* opera */) { return true; }
		// allow Ctrl+X (cut)
		if ((e.ctrlKey && key == 120 /* firefox */) || (e.ctrlKey && key == 88) /* opera */) { return true; }
		// allow Ctrl+C (copy)
		if ((e.ctrlKey && key == 99 /* firefox */) || (e.ctrlKey && key == 67) /* opera */) { return true; }
		// allow Ctrl+Z (undo)
		if ((e.ctrlKey && key == 122 /* firefox */) || (e.ctrlKey && key == 90) /* opera */) { return true; }
		// allow or deny Ctrl+V (paste), Shift+Ins
		if ((e.ctrlKey && key == 118 /* firefox */) || (e.ctrlKey && key == 86) /* opera */ ||
			(e.shiftKey && key == 45)) { return true; }
		// if a number was not pressed
		if (key < 48 || key > 57) {
			var value = $(this).val();
			/* '-' only allowed at start and if negative numbers allowed */
			if ($.inArray('-', value.split('')) !== 0 && negative && key == 45 && (value.length === 0 || parseInt($.fn.getSelectionStart(this), 10) === 0)) { return true; }
			/* only one decimal separator allowed */
			if (decimal && key == decimal.charCodeAt(0) && $.inArray(decimal, value.split('')) != -1) {
				allow = false;
			}
			// check for other keys that have special purposes
			if (
				 key != 8 /* backspace */ &&
				 key != 9 /* tab */ &&
				 key != 13 /* enter */ &&
				 key != 35 /* end */ &&
				 key != 36 /* home */ &&
				 key != 37 /* left */ &&
				 key != 39 /* right */ &&
				 key != 46 /* del */
			) {
				allow = false;
			}
			else {
				// for detecting special keys (listed above)
				// IE does not support 'charCode' and ignores them in keypress anyway
				if (typeof e.charCode != "undefined") {
					// special keys have 'keyCode' and 'which' the same (e.g. backspace)
					if (e.keyCode == e.which && e.which !== 0) {
						allow = true;
						// . and delete share the same code, don't allow . (will be set to true later if it is the decimal point)
						if (e.which == 46) { allow = false; }
					}
						// or keyCode != 0 and 'charCode'/'which' = 0
					else if (e.keyCode !== 0 && e.charCode === 0 && e.which === 0) {
						allow = true;
					}
				}
			}
			// if key pressed is the decimal and it is not already in the field
			if (decimal && key == decimal.charCodeAt(0)) {
				if ($.inArray(decimal, value.split('')) == -1) {
					allow = true;
				}
				else {
					allow = false;
				}
			}
		}
		else {
			allow = true;
			// remove extra decimal places
			if (decimal && decimalPlaces > 0) {
				var dot = $.inArray(decimal, $(this).val().split(''));
				if (dot >= 0 && $(this).val().length > dot + decimalPlaces) {
					allow = false;
				}
			}

		}
		return allow;
	};

	$.fn.numeric.keyup = function (e) {
		var val = $(this).val();
		if (val && val.length > 0) {
			// get carat (cursor) position
			var carat = $.fn.getSelectionStart(this);
			var selectionEnd = $.fn.getSelectionEnd(this);
			// get decimal character and determine if negatives are allowed
			var decimal = $.data(this, "numeric.decimal");
			var negative = $.data(this, "numeric.negative");
			var decimalPlaces = $.data(this, "numeric.decimalPlaces");

			// prepend a 0 if necessary
			if (decimal !== "" && decimal !== null) {
				// find decimal point
				var dot = $.inArray(decimal, val.split(''));
				// if dot at start, add 0 before
				if (dot === 0) {
					this.value = "0" + val;
					carat++;
					selectionEnd++;
				}
				// if dot at position 1, check if there is a - symbol before it
				if (dot == 1 && val.charAt(0) == "-") {
					this.value = "-0" + val.substring(1);
					carat++;
					selectionEnd++;
				}
				val = this.value;
			}

			// if pasted in, only allow the following characters
			var validChars = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, '-', decimal];
			// get length of the value (to loop through)
			var length = val.length;
			// loop backwards (to prevent going out of bounds)
			for (var i = length - 1; i >= 0; i--) {
				var ch = val.charAt(i);
				// remove '-' if it is in the wrong place
				if (i !== 0 && ch == "-") {
					val = val.substring(0, i) + val.substring(i + 1);
				}
					// remove character if it is at the start, a '-' and negatives aren't allowed
				else if (i === 0 && !negative && ch == "-") {
					val = val.substring(1);
				}
				var validChar = false;
				// loop through validChars
				for (var j = 0; j < validChars.length; j++) {
					// if it is valid, break out the loop
					if (ch == validChars[j]) {
						validChar = true;
						break;
					}
				}
				// if not a valid character, or a space, remove
				if (!validChar || ch == " ") {
					val = val.substring(0, i) + val.substring(i + 1);
				}
			}
			// remove extra decimal characters
			var firstDecimal = $.inArray(decimal, val.split(''));
			if (firstDecimal > 0) {
				for (var k = length - 1; k > firstDecimal; k--) {
					var chch = val.charAt(k);
					// remove decimal character
					if (chch == decimal) {
						val = val.substring(0, k) + val.substring(k + 1);
					}
				}
			}

			// remove extra decimal places
			if (decimal && decimalPlaces > 0) {
				var dot = $.inArray(decimal, val.split(''));
				if (dot >= 0) {
					val = val.substring(0, dot + decimalPlaces + 1);
					selectionEnd = Math.min(val.length, selectionEnd);
				}
			}
			// set the value and prevent the cursor moving to the end
			this.value = val;
			$.fn.setSelection(this, [carat, selectionEnd]);
		}
	};

	$.fn.numeric.blur = function () {
		var decimal = $.data(this, "numeric.decimal");
		var callback = $.data(this, "numeric.callback");
		var negative = $.data(this, "numeric.negative");
		var val = this.value;
		if (val !== "") {
			var re = new RegExp(negative ? "-?" : "" + "^\\d+$|^\\d*" + decimal + "\\d+$");
			if (!re.exec(val)) {
				callback.apply(this);
			}
		}
	};

	$.fn.removeNumeric = function () {
		return this.data("numeric.decimal", null).data("numeric.negative", null).data("numeric.callback", null).data("numeric.decimalPlaces", null).unbind("keypress", $.fn.numeric.keypress).unbind("keyup", $.fn.numeric.keyup).unbind("blur", $.fn.numeric.blur);
	};

	// Based on code from http://javascript.nwbox.com/cursor_position/ (Diego Perini <dperini@nwbox.com>)
	$.fn.getSelectionStart = function (o) {
		if (o.type === "number") {
			return undefined;
		}
		else if (o.createTextRange && document.selection) {
			var r = document.selection.createRange().duplicate();
			r.moveEnd('character', o.value.length);
			if (r.text == '') return o.value.length;

			return Math.max(0, o.value.lastIndexOf(r.text));
		} else {
			try { return o.selectionStart; }
			catch (e) { return 0; }
		}
	};

	// Based on code from http://javascript.nwbox.com/cursor_position/ (Diego Perini <dperini@nwbox.com>)
	$.fn.getSelectionEnd = function (o) {
		if (o.type === "number") {
			return undefined;
		}
		else if (o.createTextRange && document.selection) {
			var r = document.selection.createRange().duplicate()
			r.moveStart('character', -o.value.length)
			return r.text.length
		} else return o.selectionEnd
	}

	// set the selection, o is the object (input), p is the position ([start, end] or just start)
	$.fn.setSelection = function (o, p) {
		// if p is number, start and end are the same
		if (typeof p == "number") { p = [p, p]; }
		// only set if p is an array of length 2
		if (p && p.constructor == Array && p.length == 2) {
			if (o.type === "number") {
				o.focus();
			}
			else if (o.createTextRange) {
				var r = o.createTextRange();
				r.collapse(true);
				r.moveStart('character', p[0]);
				r.moveEnd('character', p[1] - p[0]);
				r.select();
			}
			else {
				o.focus();
				try {
					if (o.setSelectionRange) {
						o.setSelectionRange(p[0], p[1]);
					}
				} catch (e) {
				}
			}
		}
	};

})(jQuery);

;
//UIUtil jhoffman


if (!jQuery) { throw new Error("mask requires jQuery") }


$(document).ready(function () {
	//find any input objects with class  x, and attach relevant mask to it.
	$('.phone').mask('(999) 999-9999');
	$('.zip').mask('99999-9999');
	$('.date').mask('00/00/0000').datepicker();
	$('.integer').mask('99999999');
	$('.numeric').numeric({ decimal: ".", negative: true });

	$('.measurement').numeric({ decimal: ".", negative: false, scale: 3, decimalPlaces: 3 });
    $('.currency').numeric({ decimal: ".", negative: false, decimalPlaces: 2 });
	//$('.integer').numeric({ negative: false, scale: 0, decimalPlaces: 0 });

	$('[data-toggle="tooltip"]').tooltip();
});

String.prototype.insert = function (index, string) {
	if (index > 0)
		return this.substring(0, index) + string + this.substring(index, this.length);
	else
		return string + this;
};


var UIUtil = {} //one method of creating a namespace

UIUtil.isAlpha = function (str) {
	//letters only
	var regEx = /^[a-zA-Z]+$/;
	return str.match(regEx);
}

UIUtil.isAlphaNumeric = function (str) {
	//letters and numbers
	var regEx = /^[a-zA-Z0-9]+$/;
	return str.match(regEx);
}
UIUtil.isNumeric = function (str) {
	var regEx = /^[0-9]+$/;
	return str.match(regEx);
}
UIUtil.Spinner = function (isLoading, message, showWaitMsg) {
	var $txtField = $("#spinner #userDefinedText");
	var $waitMsg = $("#spinner #pleaseWait");
	if (message) {
		$txtField.text(message);
	}
	else {
		$txtField.text("test");//TODO: make blank
	}
	if (!showWaitMsg) {
		showWaitMsg = false;
	}
	if (showWaitMsg) {
		$waitMsg.show();
	}
	else {
		$waitMsg.hide();
	}
	if (isLoading) {
		$("#spinner").show();
		//$body.addClass("loading");
	}
	else {
		$("#spinner").hide();
		//$body.removeClass("loading");
	}
}

function TagSelection(element, tag) {
	//add opening an closing tags 
	//around selected text in a control
	//(textarea or text input)
	//e.g.: given text 'one two three' in element and 'two' is selected,
	//if tag = "b", then text would be changed to 'one <b>two</b> three'
	var selectedText;
	var openTag = "<" + tag + ">";
	var closeTag = "</" + tag + ">";
	// IE version
	if (document.selection != undefined) {
		//won't work
	}
		// Mozilla version
	else if (element.selectionStart != undefined) {
		var startPos = element.selectionStart;
		var endPos = element.selectionEnd;
		//double-clicking on a 
		selectedText = element.value.substring(startPos, endPos)
		var val = element.value.trim();
		val = val.insert(startPos, openTag);
		val = val.insert(endPos + openTag.length, closeTag);
		element.value = val;
	}
}

$.fn.pageMe = function (opts) {
	var $this = this,
				defaults = {
					perPage: 7,
					showPrevNext: false,
					showFirstLast: false,
					numbersPerPage: 5,
					hidePageNumbers: false
				},
				settings = $.extend(defaults, opts);

	var listElement = $this;
	var perPage = settings.perPage;
	var children = listElement.children();
	var pager = $('.pagination');

	if (typeof settings.childSelector != "undefined") {
		children = listElement.find(settings.childSelector);
	}

	if (typeof settings.pagerSelector != "undefined") {
		pager = $(settings.pagerSelector);
	}

	var numItems = children.size();
	var numPages = Math.ceil(numItems / perPage);

	pager.data("curr", 0);

	if (settings.showFirstLast) {
		$('<li><a href="#" class="first_link">|&lt;</a></li>').appendTo(pager);
	}

	if (settings.showPrevNext) {
		$('<li><a href="#" class="prev_link">«</a></li>').appendTo(pager);
	}

	var curr = 0;
	while (numPages > curr && (settings.hidePageNumbers == false)) {
		$('<li><a href="#" class="page_link">' + (curr + 1) + '</a></li>').appendTo(pager);
		curr++;
	}

	if (settings.numbersPerPage > 1) {
		$('.page_link').hide();
		$('.page_link').slice(pager.data("curr"), settings.numbersPerPage).show();
	}

	if (settings.showPrevNext) {
		$('<li><a href="#" class="next_link">»</a></li>').appendTo(pager);
	}

	if (settings.showFirstLast) {
		$('<li><a href="#" class="last_link">&gt;|</a></li>').appendTo(pager);
	}

	pager.find('.page_link:first').addClass('active');
	pager.find('.prev_link').hide();
	if (numPages <= 1) {
		pager.find('.next_link').hide();
	}
	pager.children().eq(1).addClass("active");

	children.hide();
	children.slice(0, perPage).show();

	pager.find('li .page_link').click(function () {
		var clickedPage = $(this).html().valueOf() - 1;
		goTo(clickedPage, perPage);
		return false;
	});
	pager.find('li .first_link').click(function () {
		var clickedPage = 0;
		goTo(clickedPage, perPage);
		return false;
	});
	pager.find('li .prev_link').click(function () {
		previous();
		return false;
	});
	pager.find('li .next_link').click(function () {
		next();
		return false;
	});
	pager.find('li .last_link').click(function () {
		var clickedPage = numPages - 1;
		goTo(clickedPage, perPage);
		return false;
	});

	function previous() {
		var goToPage = parseInt(pager.data("curr")) - 1;
		goTo(goToPage);
	}

	function next() {
		goToPage = parseInt(pager.data("curr")) + 1;
		goTo(goToPage);
	}

	function goTo(page) {
		var startAt = page * perPage,
						endOn = startAt + perPage;

		children.css('display', 'none').slice(startAt, endOn).show();

		if (page >= 1) {
			pager.find('.prev_link').show();
		}
		else {
			pager.find('.prev_link').hide();
		}

		if (page < (numPages - settings.numbersPerPage)) {
			pager.find('.next_link').show();
		}
		else {
			pager.find('.next_link').hide();
		}

		pager.data("curr", page);

		if (settings.numbersPerPage > 1) {
			$('.page_link').hide();
			$('.page_link').slice(page, settings.numbersPerPage + page).show();
		}

		pager.children().removeClass("active");
		pager.children().eq(page + 1).addClass("active");

	}
};

function OpenWindow(url, width, height) {
	var leftPosition, topPosition;
	//Allow for borders.
	leftPosition = (window.screen.width / 2) - ((width / 2) + 10);
	//Allow for title and status bars.
	topPosition = (window.screen.height / 2) - ((height / 2) + 50);
	//Open the window.
	var win = window.open(url, "_blank",	"status=no,height=" + height + ",width=" + width + ",resizable=yes,left="
		+ leftPosition + ",top=" + topPosition + ",screenX=" + leftPosition + ",screenY="
		+ topPosition + ",toolbar=no,menubar=no,scrollbars=no,location=no,directories=no");
	return win;
}
function OpenWindowResponsive(url) {
	var width = window.screen.width - 50;
	var height = window.screen.height - 20;
	return OpenWindow(url, width, height);
};
