");
#line default
#line hidden
- #line 587 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 595 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
Write(Html.EditorFor(model => model.DeviceBatch.Comments));
#line default
#line hidden
- #line 587 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 595 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
@@ -1879,7 +1884,7 @@ WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(@">
$(function () {
var model = {
- $DeviceBatch_Comments: $('#DeviceBatch_Comments'),
+ $field: $('#DeviceBatch_Comments'),
$ajax_loading: null,
$ajax_ok: null,
updated: function () {
@@ -1888,12 +1893,12 @@ WriteLiteral(@">
if (!model.$ajax_ok)
model.$ajax_ok = $('#ajaxComments_ok');
model.$ajax_loading.show();
- var data = { Comments: model.$DeviceBatch_Comments.tinymce().getContent() };
+ var data = { Comments: model.$field.tinymce().getContent() };
$.ajax({
url: '");
- #line 602 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 610 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
Write(Url.Action(MVC.API.DeviceBatch.UpdateComments(Model.DeviceBatch.Id)));
@@ -1914,16 +1919,17 @@ WriteLiteral("\',\r\n dataType: \'json\',\r\n
" + errorThrown);\r\n model.$ajax_loading.hi" +
"de();\r\n }\r\n })" +
"\r\n }\r\n };\r\n\r\n " +
-" model.$DeviceBatch_Comments.tinymce({\r\n theme:" +
-" \'simple\',\r\n setup: function (ed) {\r\n " +
-" //ed.onChange.add(model.updatedThrottle);\r\n " +
-" ed.onInit.add(function (ed) {\r\n $(" +
-"ed.getWin()).blur(model.updated);\r\n });\r\n " +
-" }\r\n });\r\n });\r\n " +
-" \r\n");
+" model.$field.tinymce({\r\n theme: \'simple\',\r\n " +
+" add_unload_trigger: false,\r\n " +
+" schema: \"html5\",\r\n statusbar: false,\r\n " +
+" setup: function (ed) {\r\n ed.on(\'ini" +
+"t\', function () {\r\n $(ed.getWin()).blur(model" +
+".updated);\r\n });\r\n }\r\n" +
+" });\r\n });\r\n \r" +
+"\n");
- #line 635 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 645 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
}
else
{
@@ -1939,7 +1945,7 @@ WriteLiteral(" class=\"smallMessage\"");
WriteLiteral("><None Specified>");
- #line 639 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 649 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
}
else
{
@@ -1947,14 +1953,14 @@ WriteLiteral("><None Specified>");
#line default
#line hidden
- #line 641 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 651 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
Write(new HtmlString(Model.DeviceBatch.Comments));
#line default
#line hidden
- #line 641 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 651 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
}
}
@@ -1968,13 +1974,13 @@ WriteLiteral(" class=\"actionBar\"");
WriteLiteral(">\r\n");
- #line 648 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 658 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
#line default
#line hidden
- #line 648 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 658 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
if (Model.CanDelete)
{
@@ -1982,14 +1988,14 @@ WriteLiteral(">\r\n");
#line default
#line hidden
- #line 650 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 660 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
Write(Html.ActionLinkButton("Delete", MVC.API.DeviceBatch.Delete(Model.DeviceBatch.Id, true), "buttonDelete"));
#line default
#line hidden
- #line 650 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 660 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
}
@@ -1999,7 +2005,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" ");
- #line 652 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 662 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
if (Model.DeviceCount > 0)
{
if (Authorization.Has(Claims.Device.Actions.Export))
@@ -2009,14 +2015,14 @@ WriteLiteral(" ");
#line default
#line hidden
- #line 656 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 666 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
Write(Html.ActionLinkButton("Export Devices", MVC.API.DeviceBatch.ExportDevices(Model.DeviceBatch.Id)));
#line default
#line hidden
- #line 656 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 666 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
}
if (Authorization.Has(Claims.Device.Search))
@@ -2026,14 +2032,14 @@ WriteLiteral(" ");
#line default
#line hidden
- #line 660 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 670 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
Write(Html.ActionLinkButton("View Devices", MVC.Search.Query(Model.DeviceBatch.Id.ToString(), "DeviceBatch")));
#line default
#line hidden
- #line 660 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
+ #line 670 "..\..\Areas\Config\Views\DeviceBatch\Show.cshtml"
}
}
diff --git a/Disco.Web/ClientSource/Scripts/Core.js b/Disco.Web/ClientSource/Scripts/Core.js
index 5726dc1a..8f5f8d75 100644
--- a/Disco.Web/ClientSource/Scripts/Core.js
+++ b/Disco.Web/ClientSource/Scripts/Core.js
@@ -1393,9 +1393,9 @@ window.Modernizr = (function( window, document, undefined ) {
})(this, this.document);
-///#source 1 1 /ClientSource/Scripts/Core/jquery-2.0.2.js
+///#source 1 1 /ClientSource/Scripts/Core/jquery-2.0.3.js
/*!
- * jQuery JavaScript Library v2.0.2
+ * jQuery JavaScript Library v2.0.3
* http://jquery.com/
*
* Includes Sizzle.js
@@ -1405,7 +1405,7 @@ window.Modernizr = (function( window, document, undefined ) {
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2013-05-30T21:25Z
+ * Date: 2013-07-03T13:30Z
*/
(function( window, undefined ) {
@@ -1442,7 +1442,7 @@ var
// List of deleted data cache ids, so we can reuse them
core_deletedIds = [],
- core_version = "2.0.2",
+ core_version = "2.0.3",
// Save a reference to some core methods
core_concat = core_deletedIds.concat,
@@ -2268,7 +2268,7 @@ rootjQuery = jQuery(document);
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2013-05-27
+ * Date: 2013-06-03
*/
(function( window, undefined ) {
@@ -2301,7 +2301,13 @@ var i,
tokenCache = createCache(),
compilerCache = createCache(),
hasDuplicate = false,
- sortOrder = function() { return 0; },
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+ return 0;
+ },
// General-purpose constants
strundefined = typeof undefined,
@@ -2544,14 +2550,6 @@ function Sizzle( selector, context, results, seed ) {
return select( selector.replace( rtrim, "$1" ), context, results, seed );
}
-/**
- * For feature detection
- * @param {Function} fn The function to test for native support
- */
-function isNative( fn ) {
- return rnative.test( fn + "" );
-}
-
/**
* Create key-value caches of limited size
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with
@@ -2605,58 +2603,14 @@ function assert( fn ) {
/**
* Adds the same handler for all of the specified attrs
* @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied if the test fails
- * @param {Boolean} test The result of a test. If true, null will be set as the handler in leiu of the specified handler
+ * @param {Function} handler The method that will be applied
*/
-function addHandle( attrs, handler, test ) {
- attrs = attrs.split("|");
- var current,
- i = attrs.length,
- setHandle = test ? null : handler;
+function addHandle( attrs, handler ) {
+ var arr = attrs.split("|"),
+ i = attrs.length;
while ( i-- ) {
- // Don't override a user's handler
- if ( !(current = Expr.attrHandle[ attrs[i] ]) || current === handler ) {
- Expr.attrHandle[ attrs[i] ] = setHandle;
- }
- }
-}
-
-/**
- * Fetches boolean attributes by node
- * @param {Element} elem
- * @param {String} name
- */
-function boolHandler( elem, name ) {
- // XML does not need to be checked as this will not be assigned for XML documents
- var val = elem.getAttributeNode( name );
- return val && val.specified ?
- val.value :
- elem[ name ] === true ? name.toLowerCase() : null;
-}
-
-/**
- * Fetches attributes without interpolation
- * http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
- * @param {Element} elem
- * @param {String} name
- */
-function interpolationHandler( elem, name ) {
- // XML does not need to be checked as this will not be assigned for XML documents
- return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
-}
-
-/**
- * Uses defaultValue to retrieve value in IE6/7
- * @param {Element} elem
- * @param {String} name
- */
-function valueHandler( elem ) {
- // Ignore the value *property* on inputs by using defaultValue
- // Fallback to Sizzle.attr by returning undefined where appropriate
- // XML does not need to be checked as this will not be assigned for XML documents
- if ( elem.nodeName.toLowerCase() === "input" ) {
- return elem.defaultValue;
+ Expr.attrHandle[ arr[i] ] = handler;
}
}
@@ -2664,7 +2618,7 @@ function valueHandler( elem ) {
* Checks document order of two siblings
* @param {Element} a
* @param {Element} b
- * @returns Returns -1 if a precedes b, 1 if a follows b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
*/
function siblingCheck( a, b ) {
var cur = b && a,
@@ -2754,7 +2708,7 @@ support = Sizzle.support = {};
*/
setDocument = Sizzle.setDocument = function( node ) {
var doc = node ? node.ownerDocument || node : preferredDoc,
- parent = doc.parentWindow;
+ parent = doc.defaultView;
// If no document and documentElement is available, return
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
@@ -2771,7 +2725,8 @@ setDocument = Sizzle.setDocument = function( node ) {
// Support: IE>8
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
- if ( parent && parent.frameElement ) {
+ // IE6-8 do not support the defaultView property so parent will be undefined
+ if ( parent && parent.attachEvent && parent !== parent.top ) {
parent.attachEvent( "onbeforeunload", function() {
setDocument();
});
@@ -2783,32 +2738,10 @@ setDocument = Sizzle.setDocument = function( node ) {
// Support: IE<8
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
support.attributes = assert(function( div ) {
-
- // Support: IE<8
- // Prevent attribute/property "interpolation"
- div.innerHTML = "";
- addHandle( "type|href|height|width", interpolationHandler, div.firstChild.getAttribute("href") === "#" );
-
- // Support: IE<9
- // Use getAttributeNode to fetch booleans when getAttribute lies
- addHandle( booleans, boolHandler, div.getAttribute("disabled") == null );
-
div.className = "i";
return !div.getAttribute("className");
});
- // Support: IE<9
- // Retrieving value should defer to defaultValue
- support.input = assert(function( div ) {
- div.innerHTML = "";
- div.firstChild.setAttribute( "value", "" );
- return div.firstChild.getAttribute( "value" ) === "";
- });
-
- // IE6/7 still return empty string for value,
- // but are actually retrieving the property
- addHandle( "value", valueHandler, support.attributes && support.input );
-
/* getElement(s)By*
---------------------------------------------------------------------- */
@@ -2917,7 +2850,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// See http://bugs.jquery.com/ticket/13378
rbuggyQSA = [];
- if ( (support.qsa = isNative(doc.querySelectorAll)) ) {
+ if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
// Build QSA regex
// Regex strategy adopted from Diego Perini
assert(function( div ) {
@@ -2969,7 +2902,7 @@ setDocument = Sizzle.setDocument = function( node ) {
});
}
- if ( (support.matchesSelector = isNative( (matches = docElem.webkitMatchesSelector ||
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
docElem.mozMatchesSelector ||
docElem.oMatchesSelector ||
docElem.msMatchesSelector) )) ) {
@@ -2995,7 +2928,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Element contains another
// Purposefully does not implement inclusive descendent
// As in, an element does not contain itself
- contains = isNative(docElem.contains) || docElem.compareDocumentPosition ?
+ contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
function( a, b ) {
var adown = a.nodeType === 9 ? a.documentElement : a,
bup = b && b.parentNode;
@@ -3019,13 +2952,6 @@ setDocument = Sizzle.setDocument = function( node ) {
/* Sorting
---------------------------------------------------------------------- */
- // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
- // Detached nodes confoundingly follow *each other*
- support.sortDetached = assert(function( div1 ) {
- // Should return 1, but returns 4 (following)
- return div1.compareDocumentPosition( doc.createElement("div") ) & 1;
- });
-
// Document order sorting
sortOrder = docElem.compareDocumentPosition ?
function( a, b ) {
@@ -3168,9 +3094,9 @@ Sizzle.attr = function( elem, name ) {
var fn = Expr.attrHandle[ name.toLowerCase() ],
// Don't get fooled by Object.prototype properties (jQuery #13807)
- val = ( fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
fn( elem, name, !documentIsHTML ) :
- undefined );
+ undefined;
return val === undefined ?
support.attributes || !documentIsHTML ?
@@ -3715,6 +3641,8 @@ Expr = Sizzle.selectors = {
}
};
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
// Add button/input type pseudos
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
Expr.pseudos[ i ] = createInputPseudo( i );
@@ -3723,6 +3651,11 @@ for ( i in { submit: true, reset: true } ) {
Expr.pseudos[ i ] = createButtonPseudo( i );
}
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
function tokenize( selector, parseOnly ) {
var matched, match, tokens, type,
soFar, groups, preFilters,
@@ -4234,26 +4167,67 @@ function select( selector, context, results, seed ) {
return results;
}
-// Deprecated
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
// One-time assignments
// Sort stability
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+// Support: Chrome<14
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = hasDuplicate;
+
// Initialize against the default document
setDocument();
-// Support: Chrome<<14
-// Always assume duplicates if they aren't passed to the comparison function
-[0, 0].sort( sortOrder );
-support.detectDuplicates = hasDuplicate;
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+ // Should return 1, but returns 4 (following)
+ return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+ div.innerHTML = "";
+ return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+ }
+ });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+ div.innerHTML = "";
+ div.firstChild.setAttribute( "value", "" );
+ return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+ addHandle( "value", function( elem, name, isXML ) {
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+ return elem.defaultValue;
+ }
+ });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+ return div.getAttribute("disabled") == null;
+}) ) {
+ addHandle( booleans, function( elem, name, isXML ) {
+ var val;
+ if ( !isXML ) {
+ return (val = elem.getAttributeNode( name )) && val.specified ?
+ val.value :
+ elem[ name ] === true ? name.toLowerCase() : null;
+ }
+ });
+}
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
@@ -4438,9 +4412,9 @@ jQuery.Callbacks = function( options ) {
},
// Call all callbacks with the given context and arguments
fireWith: function( context, args ) {
- args = args || [];
- args = [ context, args.slice ? args.slice() : args ];
if ( list && ( !fired || stack ) ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
if ( firing ) {
stack.push( args );
} else {
@@ -4831,6 +4805,7 @@ Data.prototype = {
cache : cache[ key ];
},
access: function( owner, key, value ) {
+ var stored;
// In cases where either:
//
// 1. No key was specified
@@ -4844,7 +4819,11 @@ Data.prototype = {
//
if ( key === undefined ||
((key && typeof key === "string") && value === undefined) ) {
- return this.get( owner, key );
+
+ stored = this.get( owner, key );
+
+ return stored !== undefined ?
+ stored : this.get( owner, jQuery.camelCase(key) );
}
// [*]When the key is not a string, or both a key and value
@@ -5316,8 +5295,11 @@ jQuery.fn.extend({
},
toggleClass: function( value, stateVal ) {
- var type = typeof value,
- isBool = typeof stateVal === "boolean";
+ var type = typeof value;
+
+ if ( typeof stateVal === "boolean" && type === "string" ) {
+ return stateVal ? this.addClass( value ) : this.removeClass( value );
+ }
if ( jQuery.isFunction( value ) ) {
return this.each(function( i ) {
@@ -5331,13 +5313,15 @@ jQuery.fn.extend({
var className,
i = 0,
self = jQuery( this ),
- state = stateVal,
classNames = value.match( core_rnotwhite ) || [];
while ( (className = classNames[ i++ ]) ) {
// check each className given, space separated list
- state = isBool ? state : !self.hasClass( className );
- self[ state ? "addClass" : "removeClass" ]( className );
+ if ( self.hasClass( className ) ) {
+ self.removeClass( className );
+ } else {
+ self.addClass( className );
+ }
}
// Toggle whole class name
@@ -7202,7 +7186,7 @@ jQuery.extend({
// Descend through wrappers to the right content
j = wrap[ 0 ];
while ( j-- ) {
- tmp = tmp.firstChild;
+ tmp = tmp.lastChild;
}
// Support: QtWebKit
@@ -7606,10 +7590,12 @@ jQuery.fn.extend({
return showHide( this );
},
toggle: function( state ) {
- var bool = typeof state === "boolean";
+ if ( typeof state === "boolean" ) {
+ return state ? this.show() : this.hide();
+ }
return this.each(function() {
- if ( bool ? state : isHidden( this ) ) {
+ if ( isHidden( this ) ) {
jQuery( this ).show();
} else {
jQuery( this ).hide();
@@ -7640,6 +7626,7 @@ jQuery.extend({
"fontWeight": true,
"lineHeight": true,
"opacity": true,
+ "order": true,
"orphans": true,
"widows": true,
"zIndex": true,
@@ -11471,373 +11458,351 @@ $.format = $.validator.format;
}(jQuery));
///#source 1 1 /ClientSource/Scripts/Core/jquery.validate.unobtrusive.js
+/* NUGET: BEGIN LICENSE TEXT
+*
+* Microsoft grants you the right to use these script files for the sole
+* purpose of either: (i) interacting through your browser with the Microsoft
+* website or online service, subject to the applicable licensing or use
+* terms; or (ii) using the files as included with a Microsoft product subject
+* to that product's license terms. Microsoft reserves all other rights to the
+* files not expressly granted by Microsoft, whether by implication, estoppel
+* or otherwise. Insofar as a script file is dual licensed under GPL,
+* Microsoft neither took the code under GPL nor distributes it thereunder but
+* under the terms set out in this paragraph. All notices and licenses
+* below are for informational purposes only.
+*
+* NUGET: END LICENSE TEXT */
/*!
** Unobtrusive validation support library for jQuery and jQuery Validate
** Copyright (C) Microsoft Corporation. All rights reserved.
*/
-
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */
-
(function ($) {
- var $jQval = $.validator,
- adapters,
- data_validation = "unobtrusiveValidation";
+var $jQval = $.validator,
+adapters,
+data_validation = "unobtrusiveValidation";
+function setValidationValues(options, ruleName, value) {
+options.rules[ruleName] = value;
+if (options.message) {
+options.messages[ruleName] = options.message;
+}
+}
+function splitAndTrim(value) {
+return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
+}
+function escapeAttributeValue(value) {
+// As mentioned on http://api.jquery.com/category/selectors/
+return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
+}
+function getModelPrefix(fieldName) {
+return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
+}
+function appendModelPrefix(value, prefix) {
+if (value.indexOf("*.") === 0) {
+value = value.replace("*.", prefix);
+}
+return value;
+}
+function onError(error, inputElement) { // 'this' is the form element
+var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
+replaceAttrValue = container.attr("data-valmsg-replace"),
+replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
+container.removeClass("field-validation-valid").addClass("field-validation-error");
+error.data("unobtrusiveContainer", container);
+if (replace) {
+container.empty();
+error.removeClass("input-validation-error").appendTo(container);
+}
+else {
+error.hide();
+}
+}
+function onErrors(event, validator) { // 'this' is the form element
+var container = $(this).find("[data-valmsg-summary=true]"),
+list = container.find("ul");
+if (list && list.length && validator.errorList.length) {
+list.empty();
+container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
+$.each(validator.errorList, function () {
+$("").html(this.message).appendTo(list);
+});
+}
+}
+function onSuccess(error) { // 'this' is the form element
+var container = error.data("unobtrusiveContainer"),
+replaceAttrValue = container.attr("data-valmsg-replace"),
+replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
+if (container) {
+container.addClass("field-validation-valid").removeClass("field-validation-error");
+error.removeData("unobtrusiveContainer");
+if (replace) {
+container.empty();
+}
+}
+}
+function onReset(event) { // 'this' is the form element
+var $form = $(this);
+$form.data("validator").resetForm();
+$form.find(".validation-summary-errors")
+.addClass("validation-summary-valid")
+.removeClass("validation-summary-errors");
+$form.find(".field-validation-error")
+.addClass("field-validation-valid")
+.removeClass("field-validation-error")
+.removeData("unobtrusiveContainer")
+.find(">*") // If we were using valmsg-replace, get the underlying error
+.removeData("unobtrusiveContainer");
+}
+function validationInfo(form) {
+var $form = $(form),
+result = $form.data(data_validation),
+onResetProxy = $.proxy(onReset, form);
+if (!result) {
+result = {
+options: { // options structure passed to jQuery Validate's validate() method
+errorClass: "input-validation-error",
+errorElement: "span",
+errorPlacement: $.proxy(onError, form),
+invalidHandler: $.proxy(onErrors, form),
+messages: {},
+rules: {},
+success: $.proxy(onSuccess, form)
+},
+attachValidation: function () {
+$form
+.unbind("reset." + data_validation, onResetProxy)
+.bind("reset." + data_validation, onResetProxy)
+.validate(this.options);
+},
+validate: function () { // a validation function that is called by unobtrusive Ajax
+$form.validate();
+return $form.valid();
+}
+};
+$form.data(data_validation, result);
+}
+return result;
+}
+$jQval.unobtrusive = {
+adapters: [],
+parseElement: function (element, skipAttach) {
+///
+/// Parses a single HTML element for unobtrusive validation attributes.
+///
+/// The HTML element to be parsed.
+/// [Optional] true to skip attaching the
+/// validation to the form. If parsing just this single element, you should specify true.
+/// If parsing several elements, you should specify false, and manually attach the validation
+/// to the form when you are finished. The default is false.
+var $element = $(element),
+form = $element.parents("form")[0],
+valInfo, rules, messages;
+if (!form) { // Cannot do client-side validation without a form
+return;
+}
+valInfo = validationInfo(form);
+valInfo.options.rules[element.name] = rules = {};
+valInfo.options.messages[element.name] = messages = {};
+$.each(this.adapters, function () {
+var prefix = "data-val-" + this.name,
+message = $element.attr(prefix),
+paramValues = {};
+if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
+prefix += "-";
+$.each(this.params, function () {
+paramValues[this] = $element.attr(prefix + this);
+});
+this.adapt({
+element: element,
+form: form,
+message: message,
+params: paramValues,
+rules: rules,
+messages: messages
+});
+}
+});
+$.extend(rules, { "__dummy__": true });
+if (!skipAttach) {
+valInfo.attachValidation();
+}
+},
+parse: function (selector) {
+///
+/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
+/// with the [data-val=true] attribute value and enables validation according to the data-val-*
+/// attribute values.
+///
+/// Any valid jQuery selector.
+var $forms = $(selector)
+.parents("form")
+.andSelf()
+.add($(selector).find("form"))
+.filter("form");
+// :input is a psuedoselector provided by jQuery which selects input and input-like elements
+// combining :input with other selectors significantly decreases performance.
+$(selector).find(":input").filter("[data-val=true]").each(function () {
+$jQval.unobtrusive.parseElement(this, true);
+});
+$forms.each(function () {
+var info = validationInfo(this);
+if (info) {
+info.attachValidation();
+}
+});
+}
+};
+adapters = $jQval.unobtrusive.adapters;
+adapters.add = function (adapterName, params, fn) {
+/// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.
+/// The name of the adapter to be added. This matches the name used
+/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
+/// [Optional] An array of parameter names (strings) that will
+/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
+/// mmmm is the parameter name).
+/// The function to call, which adapts the values from the HTML
+/// attributes into jQuery Validate rules and/or messages.
+///
+if (!fn) { // Called with no params, just a function
+fn = params;
+params = [];
+}
+this.push({ name: adapterName, params: params, adapt: fn });
+return this;
+};
+adapters.addBool = function (adapterName, ruleName) {
+/// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
+/// the jQuery Validate validation rule has no parameter values.
+/// The name of the adapter to be added. This matches the name used
+/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
+/// [Optional] The name of the jQuery Validate rule. If not provided, the value
+/// of adapterName will be used instead.
+///
+return this.add(adapterName, function (options) {
+setValidationValues(options, ruleName || adapterName, true);
+});
+};
+adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
+/// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
+/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
+/// one for min-and-max). The HTML parameters are expected to be named -min and -max.
+/// The name of the adapter to be added. This matches the name used
+/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
+/// The name of the jQuery Validate rule to be used when you only
+/// have a minimum value.
+/// The name of the jQuery Validate rule to be used when you only
+/// have a maximum value.
+/// The name of the jQuery Validate rule to be used when you
+/// have both a minimum and maximum value.
+/// [Optional] The name of the HTML attribute that
+/// contains the minimum value. The default is "min".
+/// [Optional] The name of the HTML attribute that
+/// contains the maximum value. The default is "max".
+///
+return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
+var min = options.params.min,
+max = options.params.max;
+if (min && max) {
+setValidationValues(options, minMaxRuleName, [min, max]);
+}
+else if (min) {
+setValidationValues(options, minRuleName, min);
+}
+else if (max) {
+setValidationValues(options, maxRuleName, max);
+}
+});
+};
+adapters.addSingleVal = function (adapterName, attribute, ruleName) {
+/// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
+/// the jQuery Validate validation rule has a single value.
+/// The name of the adapter to be added. This matches the name used
+/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).
+/// [Optional] The name of the HTML attribute that contains the value.
+/// The default is "val".
+/// [Optional] The name of the jQuery Validate rule. If not provided, the value
+/// of adapterName will be used instead.
+///
+return this.add(adapterName, [attribute || "val"], function (options) {
+setValidationValues(options, ruleName || adapterName, options.params[attribute]);
+});
+};
+$jQval.addMethod("__dummy__", function (value, element, params) {
+return true;
+});
+$jQval.addMethod("regex", function (value, element, params) {
+var match;
+if (this.optional(element)) {
+return true;
+}
+match = new RegExp(params).exec(value);
+return (match && (match.index === 0) && (match[0].length === value.length));
+});
+$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
+var match;
+if (nonalphamin) {
+match = value.match(/\W/g);
+match = match && match.length >= nonalphamin;
+}
+return match;
+});
+if ($jQval.methods.extension) {
+adapters.addSingleVal("accept", "mimtype");
+adapters.addSingleVal("extension", "extension");
+} else {
+// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
+// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
+// validating the extension, and ignore mime-type validations as they are not supported.
+adapters.addSingleVal("extension", "extension", "accept");
+}
+adapters.addSingleVal("regex", "pattern");
+adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
+adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
+adapters.add("equalto", ["other"], function (options) {
+var prefix = getModelPrefix(options.element.name),
+other = options.params.other,
+fullOtherName = appendModelPrefix(other, prefix),
+element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
+setValidationValues(options, "equalTo", element);
+});
+adapters.add("required", function (options) {
+// jQuery Validate equates "required" with "mandatory" for checkbox elements
+if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
+setValidationValues(options, "required", true);
+}
+});
+adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
+var value = {
+url: options.params.url,
+type: options.params.type || "GET",
+data: {}
+},
+prefix = getModelPrefix(options.element.name);
+$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
+var paramName = appendModelPrefix(fieldName, prefix);
+value.data[paramName] = function () {
+return $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']").val();
+};
+});
+setValidationValues(options, "remote", value);
+});
+adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
+if (options.params.min) {
+setValidationValues(options, "minlength", options.params.min);
+}
+if (options.params.nonalphamin) {
+setValidationValues(options, "nonalphamin", options.params.nonalphamin);
+}
+if (options.params.regex) {
+setValidationValues(options, "regex", options.params.regex);
+}
+});
+$(function () {
+$jQval.unobtrusive.parse(document);
+});
+}(jQuery));
- function setValidationValues(options, ruleName, value) {
- options.rules[ruleName] = value;
- if (options.message) {
- options.messages[ruleName] = options.message;
- }
- }
-
- function splitAndTrim(value) {
- return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
- }
-
- function escapeAttributeValue(value) {
- // As mentioned on http://api.jquery.com/category/selectors/
- return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
- }
-
- function getModelPrefix(fieldName) {
- return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
- }
-
- function appendModelPrefix(value, prefix) {
- if (value.indexOf("*.") === 0) {
- value = value.replace("*.", prefix);
- }
- return value;
- }
-
- function onError(error, inputElement) { // 'this' is the form element
- var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
- replaceAttrValue = container.attr("data-valmsg-replace"),
- replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
-
- container.removeClass("field-validation-valid").addClass("field-validation-error");
- error.data("unobtrusiveContainer", container);
-
- if (replace) {
- container.empty();
- error.removeClass("input-validation-error").appendTo(container);
- }
- else {
- error.hide();
- }
- }
-
- function onErrors(event, validator) { // 'this' is the form element
- var container = $(this).find("[data-valmsg-summary=true]"),
- list = container.find("ul");
-
- if (list && list.length && validator.errorList.length) {
- list.empty();
- container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
-
- $.each(validator.errorList, function () {
- $("").html(this.message).appendTo(list);
- });
- }
- }
-
- function onSuccess(error) { // 'this' is the form element
- var container = error.data("unobtrusiveContainer"),
- replaceAttrValue = container.attr("data-valmsg-replace"),
- replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
-
- if (container) {
- container.addClass("field-validation-valid").removeClass("field-validation-error");
- error.removeData("unobtrusiveContainer");
-
- if (replace) {
- container.empty();
- }
- }
- }
-
- function onReset(event) { // 'this' is the form element
- var $form = $(this);
- $form.data("validator").resetForm();
- $form.find(".validation-summary-errors")
- .addClass("validation-summary-valid")
- .removeClass("validation-summary-errors");
- $form.find(".field-validation-error")
- .addClass("field-validation-valid")
- .removeClass("field-validation-error")
- .removeData("unobtrusiveContainer")
- .find(">*") // If we were using valmsg-replace, get the underlying error
- .removeData("unobtrusiveContainer");
- }
-
- function validationInfo(form) {
- var $form = $(form),
- result = $form.data(data_validation),
- onResetProxy = $.proxy(onReset, form);
-
- if (!result) {
- result = {
- options: { // options structure passed to jQuery Validate's validate() method
- errorClass: "input-validation-error",
- errorElement: "span",
- errorPlacement: $.proxy(onError, form),
- invalidHandler: $.proxy(onErrors, form),
- messages: {},
- rules: {},
- success: $.proxy(onSuccess, form)
- },
- attachValidation: function () {
- $form
- .unbind("reset." + data_validation, onResetProxy)
- .bind("reset." + data_validation, onResetProxy)
- .validate(this.options);
- },
- validate: function () { // a validation function that is called by unobtrusive Ajax
- $form.validate();
- return $form.valid();
- }
- };
- $form.data(data_validation, result);
- }
-
- return result;
- }
-
- $jQval.unobtrusive = {
- adapters: [],
-
- parseElement: function (element, skipAttach) {
- ///
- /// Parses a single HTML element for unobtrusive validation attributes.
- ///
- /// The HTML element to be parsed.
- /// [Optional] true to skip attaching the
- /// validation to the form. If parsing just this single element, you should specify true.
- /// If parsing several elements, you should specify false, and manually attach the validation
- /// to the form when you are finished. The default is false.
- var $element = $(element),
- form = $element.parents("form")[0],
- valInfo, rules, messages;
-
- if (!form) { // Cannot do client-side validation without a form
- return;
- }
-
- valInfo = validationInfo(form);
- valInfo.options.rules[element.name] = rules = {};
- valInfo.options.messages[element.name] = messages = {};
-
- $.each(this.adapters, function () {
- var prefix = "data-val-" + this.name,
- message = $element.attr(prefix),
- paramValues = {};
-
- if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
- prefix += "-";
-
- $.each(this.params, function () {
- paramValues[this] = $element.attr(prefix + this);
- });
-
- this.adapt({
- element: element,
- form: form,
- message: message,
- params: paramValues,
- rules: rules,
- messages: messages
- });
- }
- });
-
- $.extend(rules, { "__dummy__": true });
-
- if (!skipAttach) {
- valInfo.attachValidation();
- }
- },
-
- parse: function (selector) {
- ///
- /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
- /// with the [data-val=true] attribute value and enables validation according to the data-val-*
- /// attribute values.
- ///
- /// Any valid jQuery selector.
- var $forms = $(selector)
- .parents("form")
- .andSelf()
- .add($(selector).find("form"))
- .filter("form");
-
- $(selector).find(":input[data-val=true]").each(function () {
- $jQval.unobtrusive.parseElement(this, true);
- });
-
- $forms.each(function () {
- var info = validationInfo(this);
- if (info) {
- info.attachValidation();
- }
- });
- }
- };
-
- adapters = $jQval.unobtrusive.adapters;
-
- adapters.add = function (adapterName, params, fn) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
- /// [Optional] An array of parameter names (strings) that will
- /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
- /// mmmm is the parameter name).
- /// The function to call, which adapts the values from the HTML
- /// attributes into jQuery Validate rules and/or messages.
- ///
- if (!fn) { // Called with no params, just a function
- fn = params;
- params = [];
- }
- this.push({ name: adapterName, params: params, adapt: fn });
- return this;
- };
-
- adapters.addBool = function (adapterName, ruleName) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
- /// the jQuery Validate validation rule has no parameter values.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
- /// [Optional] The name of the jQuery Validate rule. If not provided, the value
- /// of adapterName will be used instead.
- ///
- return this.add(adapterName, function (options) {
- setValidationValues(options, ruleName || adapterName, true);
- });
- };
-
- adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
- /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
- /// one for min-and-max). The HTML parameters are expected to be named -min and -max.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
- /// The name of the jQuery Validate rule to be used when you only
- /// have a minimum value.
- /// The name of the jQuery Validate rule to be used when you only
- /// have a maximum value.
- /// The name of the jQuery Validate rule to be used when you
- /// have both a minimum and maximum value.
- /// [Optional] The name of the HTML attribute that
- /// contains the minimum value. The default is "min".
- /// [Optional] The name of the HTML attribute that
- /// contains the maximum value. The default is "max".
- ///
- return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
- var min = options.params.min,
- max = options.params.max;
-
- if (min && max) {
- setValidationValues(options, minMaxRuleName, [min, max]);
- }
- else if (min) {
- setValidationValues(options, minRuleName, min);
- }
- else if (max) {
- setValidationValues(options, maxRuleName, max);
- }
- });
- };
-
- adapters.addSingleVal = function (adapterName, attribute, ruleName) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
- /// the jQuery Validate validation rule has a single value.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).
- /// [Optional] The name of the HTML attribute that contains the value.
- /// The default is "val".
- /// [Optional] The name of the jQuery Validate rule. If not provided, the value
- /// of adapterName will be used instead.
- ///
- return this.add(adapterName, [attribute || "val"], function (options) {
- setValidationValues(options, ruleName || adapterName, options.params[attribute]);
- });
- };
-
- $jQval.addMethod("__dummy__", function (value, element, params) {
- return true;
- });
-
- $jQval.addMethod("regex", function (value, element, params) {
- var match;
- if (this.optional(element)) {
- return true;
- }
-
- match = new RegExp(params).exec(value);
- return (match && (match.index === 0) && (match[0].length === value.length));
- });
-
- $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
- var match;
- if (nonalphamin) {
- match = value.match(/\W/g);
- match = match && match.length >= nonalphamin;
- }
- return match;
- });
-
- adapters.addSingleVal("accept", "exts").addSingleVal("regex", "pattern");
- adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
- adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
- adapters.add("equalto", ["other"], function (options) {
- var prefix = getModelPrefix(options.element.name),
- other = options.params.other,
- fullOtherName = appendModelPrefix(other, prefix),
- element = $(options.form).find(":input[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
-
- setValidationValues(options, "equalTo", element);
- });
- adapters.add("required", function (options) {
- // jQuery Validate equates "required" with "mandatory" for checkbox elements
- if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
- setValidationValues(options, "required", true);
- }
- });
- adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
- var value = {
- url: options.params.url,
- type: options.params.type || "GET",
- data: {}
- },
- prefix = getModelPrefix(options.element.name);
-
- $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
- var paramName = appendModelPrefix(fieldName, prefix);
- value.data[paramName] = function () {
- return $(options.form).find(":input[name='" + escapeAttributeValue(paramName) + "']").val();
- };
- });
-
- setValidationValues(options, "remote", value);
- });
- adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
- if (options.params.min) {
- setValidationValues(options, "minlength", options.params.min);
- }
- if (options.params.nonalphamin) {
- setValidationValues(options, "nonalphamin", options.params.nonalphamin);
- }
- if (options.params.regex) {
- setValidationValues(options, "regex", options.params.regex);
- }
- });
-
- $(function () {
- $jQval.unobtrusive.parse(document);
- });
-} (jQuery));
///#source 1 1 /ClientSource/Scripts/Core/disco.unobtrusiveValidation.extensions.js
// Adapted from: http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/
(function ($) {
diff --git a/Disco.Web/ClientSource/Scripts/Core.js.bundle b/Disco.Web/ClientSource/Scripts/Core.js.bundle
index 38091f96..5531c398 100644
--- a/Disco.Web/ClientSource/Scripts/Core.js.bundle
+++ b/Disco.Web/ClientSource/Scripts/Core.js.bundle
@@ -1,7 +1,7 @@
/ClientSource/Scripts/Core/modernizr-2.6.2.js
- /ClientSource/Scripts/Core/jquery-2.0.2.js
+ /ClientSource/Scripts/Core/jquery-2.0.3.js/ClientSource/Scripts/Core/jquery.validate.js/ClientSource/Scripts/Core/jquery.validate.unobtrusive.js/ClientSource/Scripts/Core/disco.unobtrusiveValidation.extensions.js
diff --git a/Disco.Web/ClientSource/Scripts/Core.min.js b/Disco.Web/ClientSource/Scripts/Core.min.js
index 802e2a89..d9763586 100644
--- a/Disco.Web/ClientSource/Scripts/Core.min.js
+++ b/Disco.Web/ClientSource/Scripts/Core.min.js
@@ -1,2 +1,2 @@
-window.Modernizr=function(n,t,i){function a(n){c.cssText=n}function vt(n,t){return a(y.join(n+";")+(t||""))}function h(n,t){return typeof n===t}function v(n,t){return!!~(""+n).indexOf(t)}function lt(n,t){var u,r;for(u in n)if(r=n[u],!v(r,"-")&&c[r]!==i)return t=="pfx"?r:!0;return!1}function yt(n,t,r){var f,u;for(f in n)if(u=t[n[f]],u!==i)return r===!1?n[f]:h(u,"function")?u.bind(r||t):u;return!1}function f(n,t,i){var r=n.charAt(0).toUpperCase()+n.slice(1),u=(n+" "+ot.join(r+" ")+r).split(" ");return h(t,"string")||h(t,"undefined")?lt(u,t):(u=(n+" "+st.join(r+" ")+r).split(" "),yt(u,t,i))}function pt(){u.input=function(i){for(var r=0,u=i.length;r',n,"<\/style>"].join(""),f.id=e,(h?f:o).innerHTML+=l,o.appendChild(f),h||(o.style.background="",o.style.overflow="hidden",v=s.style.overflow,s.style.overflow="hidden",s.appendChild(o)),a=i(f,n),h?f.parentNode.removeChild(f):(o.parentNode.removeChild(o),s.style.overflow=v),!!a},at=function(t){var i=n.matchMedia||n.msMatchMedia,r;return i?i(t).matches:(l("@media "+t+" { #"+e+" { position: absolute; } }",function(t){r=(n.getComputedStyle?getComputedStyle(t,null):t.currentStyle).position=="absolute"}),r)},ct=function(){function r(r,u){u=u||t.createElement(n[r]||"div"),r="on"+r;var f=r in u;return f||(u.setAttribute||(u=t.createElement("div")),u.setAttribute&&u.removeAttribute&&(u.setAttribute(r,""),f=h(u[r],"function"),h(u[r],"undefined")||(u[r]=i),u.removeAttribute(r))),u=null,f}var n={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return r}(),it={}.hasOwnProperty,rt,k;rt=h(it,"undefined")||h(it.call,"undefined")?function(n,t){return t in n&&h(n.constructor.prototype[t],"undefined")}:function(n,t){return it.call(n,t)},Function.prototype.bind||(Function.prototype.bind=function(n){var t=this,i,r;if(typeof t!="function")throw new TypeError;return i=tt.call(arguments,1),r=function(){var f,e,u;return this instanceof r?(f=function(){},f.prototype=t.prototype,e=new f,u=t.apply(e,i.concat(tt.call(arguments))),Object(u)===u)?u:e:t.apply(n,i.concat(tt.call(arguments)))},r}),r.flexbox=function(){return f("flexWrap")},r.flexboxlegacy=function(){return f("boxDirection")},r.canvas=function(){var n=t.createElement("canvas");return!!(n.getContext&&n.getContext("2d"))},r.canvastext=function(){return!!(u.canvas&&h(t.createElement("canvas").getContext("2d").fillText,"function"))},r.webgl=function(){return!!n.WebGLRenderingContext},r.touch=function(){var i;return"ontouchstart"in n||n.DocumentTouch&&t instanceof DocumentTouch?i=!0:l(["@media (",y.join("touch-enabled),("),e,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(n){i=n.offsetTop===9}),i},r.geolocation=function(){return"geolocation"in navigator},r.postmessage=function(){return!!n.postMessage},r.websqldatabase=function(){return!!n.openDatabase},r.indexedDB=function(){return!!f("indexedDB",n)},r.hashchange=function(){return ct("hashchange",n)&&(t.documentMode===i||t.documentMode>7)},r.history=function(){return!!(n.history&&history.pushState)},r.draganddrop=function(){var n=t.createElement("div");return"draggable"in n||"ondragstart"in n&&"ondrop"in n},r.websockets=function(){return"WebSocket"in n||"MozWebSocket"in n},r.rgba=function(){return a("background-color:rgba(150,255,150,.5)"),v(c.backgroundColor,"rgba")},r.hsla=function(){return a("background-color:hsla(120,40%,100%,.5)"),v(c.backgroundColor,"rgba")||v(c.backgroundColor,"hsla")},r.multiplebgs=function(){return a("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(c.background)},r.backgroundsize=function(){return f("backgroundSize")},r.borderimage=function(){return f("borderImage")},r.borderradius=function(){return f("borderRadius")},r.boxshadow=function(){return f("boxShadow")},r.textshadow=function(){return t.createElement("div").style.textShadow===""},r.opacity=function(){return vt("opacity:.55"),/^0.55$/.test(c.opacity)},r.cssanimations=function(){return f("animationName")},r.csscolumns=function(){return f("columnCount")},r.cssgradients=function(){var n="background-image:";return a((n+"-webkit- ".split(" ").join("gradient(linear,left top,right bottom,from(#9f9),to(white));"+n)+y.join("linear-gradient(left top,#9f9, white);"+n)).slice(0,-n.length)),v(c.backgroundImage,"gradient")},r.cssreflections=function(){return f("boxReflect")},r.csstransforms=function(){return!!f("transform")},r.csstransforms3d=function(){var n=!!f("perspective");return n&&"webkitPerspective"in s.style&&l("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t){n=t.offsetLeft===9&&t.offsetHeight===3}),n},r.csstransitions=function(){return f("transition")},r.fontface=function(){var n;return l('@font-face {font-family:"font";src:url("https://")}',function(i,r){var f=t.getElementById("smodernizr"),u=f.sheet||f.styleSheet,e=u?u.cssRules&&u.cssRules[0]?u.cssRules[0].cssText:u.cssText||"":"";n=/src/i.test(e)&&e.indexOf(r.split(" ")[0])===0}),n},r.generatedcontent=function(){var n;return l(["#",e,"{font:0/0 a}#",e,':after{content:"',g,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){n=t.offsetHeight>=3}),n},r.video=function(){var i=t.createElement("video"),n=!1;try{(n=!!i.canPlayType)&&(n=new Boolean(n),n.ogg=i.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=i.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=i.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(r){}return n},r.audio=function(){var i=t.createElement("audio"),n=!1;try{(n=!!i.canPlayType)&&(n=new Boolean(n),n.ogg=i.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=i.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=i.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(i.canPlayType("audio/x-m4a;")||i.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(r){}return n},r.localstorage=function(){try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(n){return!1}},r.sessionstorage=function(){try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(n){return!1}},r.webworkers=function(){return!!n.Worker},r.applicationcache=function(){return!!n.applicationCache},r.svg=function(){return!!t.createElementNS&&!!t.createElementNS(p.svg,"svg").createSVGRect},r.inlinesvg=function(){var n=t.createElement("div");return n.innerHTML="",(n.firstChild&&n.firstChild.namespaceURI)==p.svg},r.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(ft.call(t.createElementNS(p.svg,"animate")))},r.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(ft.call(t.createElementNS(p.svg,"clipPath")))};for(k in r)rt(r,k)&&(b=k.toLowerCase(),u[b]=r[k](),nt.push((u[b]?"":"no-")+b));return u.input||pt(),u.addTest=function(n,t){if(typeof n=="object")for(var r in n)rt(n,r)&&u.addTest(r,n[r]);else{if(n=n.toLowerCase(),u[n]!==i)return u;t=typeof t=="function"?t():t,typeof d!="undefined"&&d&&(s.className+=" "+(t?"":"no-")+n),u[n]=t}return u},a(""),ut=o=null,function(n,t){function p(n,t){var i=n.createElement("p"),r=n.getElementsByTagName("head")[0]||n.documentElement;return i.innerHTML="x