text: /*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */
  !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c;
  }catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=N.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function W(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&T.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var X=/^(?:checkbox|radio)$/i,Y=/<([\w:-]+)/,Z=/^$|\/(?:java|ecma)script/i,$={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||d,e=c.documentElement,f=c.body,a.pageX=b.clientX+(e&&e.scrollLeft||f&&f.scrollLeft||0)-(e&&e.clientLeft||f&&f.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||f&&f.scrollTop||0)-(e&&e.clientTop||f&&f.clientTop||0)),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ea.test(f)?this.mouseHooks:da.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=d),3===a.target.nodeType&&(a.target=a.target.parentNode),h.filter?h.filter(a,g):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==ia()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===ia()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ga:ha):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:ha,isPropagationStopped:ha,isImmediatePropagationStopped:ha,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ga,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ga,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ga,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),n.fn.extend({on:function(a,b,c,d){return ja(this,a,b,c,d)},one:function(a,b,c,d){return ja(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=ha),this.each(function(){n.event.remove(this,a,c,b)})}});var ka=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,la=/<script|<style|<link/i,ma=/checked\s*(?:[^=]|=\s*.checked.)/i,na=/^true\/(.*)/,oa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=wa[0].contentDocument,b.write(),b.close(),c=ya(a,b),wa.detach()),xa[a]=c),c}var Aa=/^margin/,Ba=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ca=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Da=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Ea=d.documentElement;!function(){var b,c,e,f,g=d.createElement("div"),h=d.createElement("div");if(h.style){h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,g.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",g.appendChild(h);function i(){h.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",h.innerHTML="",Ea.appendChild(g);var d=a.getComputedStyle(h);b="1%"!==d.top,f="2px"===d.marginLeft,c="4px"===d.width,h.style.marginRight="50%",e="4px"===d.marginRight,Ea.removeChild(g)}n.extend(l,{pixelPosition:function(){return i(),b},boxSizingReliable:function(){return null==c&&i(),c},pixelMarginRight:function(){return null==c&&i(),e},reliableMarginLeft:function(){return null==c&&i(),f},reliableMarginRight:function(){var b,c=h.appendChild(d.createElement("div"));return c.style.cssText=h.style.cssText="-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",h.style.width="1px",Ea.appendChild(g),b=!parseFloat(a.getComputedStyle(c).marginRight),Ea.removeChild(g),h.removeChild(c),b}})}}();function Fa(a,b,c){var d,e,f,g,h=a.style;return c=c||Ca(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Ba.test(g)&&Aa.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0!==g?g+"":g}function Ga(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Ha=/^(none|table(?!-c[ea]).+)/,Ia={position:"absolute",visibility:"hidden",display:"block"},Ja={letterSpacing:"0",fontWeight:"400"},Ka=["Webkit","O","Moz","ms"],La=d.createElement("div").style;function Ma(a){if(a in La)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ka.length;while(c--)if(a=Ka[c]+b,a in La)return a}function Na(a,b,c){var d=T.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Oa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Pa(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ca(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Fa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ba.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Oa(a,b,c||(g?"border":"content"),d,f)+"px"}function Qa(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=N.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=N.access(d,"olddisplay",za(d.nodeName)))):(e=V(d),"none"===c&&e||N.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Fa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=T.exec(c))&&e[1]&&(c=W(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Fa(a,b,d)),"normal"===e&&b in Ja&&(e=Ja[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Ha.test(n.css(a,"display"))&&0===a.offsetWidth?Da(a,Ia,function(){return Pa(a,b,d)}):Pa(a,b,d):void 0},set:function(a,c,d){var e,f=d&&Ca(a),g=d&&Oa(a,b,d,"border-box"===n.css(a,"boxSizing",!1,f),f);return g&&(e=T.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=n.css(a,b)),Na(a,c,g)}}}),n.cssHooks.marginLeft=Ga(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Fa(a,"marginLeft"))||a.getBoundingClientRect().left-Da(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),n.cssHooks.marginRight=Ga(l.reliableMarginRight,function(a,b){return b?Da(a,{display:"inline-block"},Fa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Aa.test(a)||(n.cssHooks[a+b].set=Na)}),n.fn.extend({css:function(a,b){return K(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ca(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Qa(this,!0)},hide:function(){return Qa(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function Ra(a,b,c,d,e){return new Ra.prototype.init(a,b,c,d,e)}n.Tween=Ra,Ra.prototype={constructor:Ra,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ra.propHooks[this.prop];return a&&a.get?a.get(this):Ra.propHooks._default.get(this)},run:function(a){var b,c=Ra.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ra.propHooks._default.set(this),this}},Ra.prototype.init.prototype=Ra.prototype,Ra.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},Ra.propHooks.scrollTop=Ra.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=Ra.prototype.init,n.fx.step={};var Sa,Ta,Ua=/^(?:toggle|show|hide)$/,Va=/queueHooks$/;function Wa(){return a.setTimeout(function(){Sa=void 0}),Sa=n.now()}function Xa(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=U[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ya(a,b,c){for(var d,e=(_a.tweeners[b]||[]).concat(_a.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Za(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&V(a),q=N.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?N.get(a,"olddisplay")||za(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Ua.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?za(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=N.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;N.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ya(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function $a(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function _a(a,b,c){var d,e,f=0,g=_a.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Sa||Wa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:Sa||Wa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for($a(k,j.opts.specialEasing);g>f;f++)if(d=_a.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,Ya,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(_a,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return W(c.elem,a,T.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],_a.tweeners[c]=_a.tweeners[c]||[],_a.tweeners[c].unshift(b)},prefilters:[Za],prefilter:function(a,b){b?_a.prefilters.unshift(a):_a.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=_a(this,n.extend({},a),f);(e||N.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=N.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Va.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=N.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Xa(b,!0),a,d,e)}}),n.each({slideDown:Xa("show"),slideUp:Xa("hide"),slideToggle:Xa("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Sa=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Sa=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ta||(Ta=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(Ta),Ta=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=d.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var ab,bb=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return K(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ab:void 0)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)}}),ab={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=bb[b]||n.find.attr;bb[b]=function(a,b,d){var e,f;return d||(f=bb[b],bb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,bb[b]=f),e}});var cb=/^(?:input|select|textarea|button)$/i,db=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return K(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),
  void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):cb.test(a.nodeName)||db.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var eb=/[\t\r\n\f]/g;function fb(a){return a.getAttribute&&a.getAttribute("class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,fb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,fb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,fb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=fb(this),b&&N.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":N.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+fb(c)+" ").replace(eb," ").indexOf(b)>-1)return!0;return!1}});var gb=/\r/g,hb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(gb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(hb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(n.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var ib=/^(?:focusinfocus|focusoutblur)$/;n.extend(n.event,{trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!ib.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),l=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},f||!o.trigger||o.trigger.apply(e,c)!==!1)){if(!f&&!o.noBubble&&!n.isWindow(e)){for(j=o.delegateType||q,ib.test(j+q)||(h=h.parentNode);h;h=h.parentNode)p.push(h),i=h;i===(e.ownerDocument||d)&&p.push(i.defaultView||i.parentWindow||a)}g=0;while((h=p[g++])&&!b.isPropagationStopped())b.type=g>1?j:o.bindType||q,m=(N.get(h,"events")||{})[b.type]&&N.get(h,"handle"),m&&m.apply(h,c),m=l&&h[l],m&&m.apply&&L(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=q,f||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!L(e)||l&&n.isFunction(e[q])&&!n.isWindow(e)&&(i=e[l],i&&(e[l]=null),n.event.triggered=q,e[q](),n.event.triggered=void 0,i&&(e[l]=i)),b.result}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b)}}),n.fn.extend({trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),l.focusin="onfocusin"in a,l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=N.access(d,b);e||d.addEventListener(a,c,!0),N.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=N.access(d,b)-1;e?N.access(d,b,e):(d.removeEventListener(a,c,!0),N.remove(d,b))}}});var jb=a.location,kb=n.now(),lb=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var mb=/#.*$/,nb=/([?&])_=[^&]*/,ob=/^(.*?):[ \t]*([^\r\n]*)$/gm,pb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,qb=/^(?:GET|HEAD)$/,rb=/^\/\//,sb={},tb={},ub="*/".concat("*"),vb=d.createElement("a");vb.href=jb.href;function wb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function xb(a,b,c,d){var e={},f=a===tb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function yb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function zb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Ab(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:jb.href,type:"GET",isLocal:pb.test(jb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":ub,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?yb(yb(a,n.ajaxSettings),b):yb(n.ajaxSettings,a)},ajaxPrefilter:wb(sb),ajaxTransport:wb(tb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m=n.ajaxSetup({},c),o=m.context||m,p=m.context&&(o.nodeType||o.jquery)?n(o):n.event,q=n.Deferred(),r=n.Callbacks("once memory"),s=m.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,getResponseHeader:function(a){var b;if(2===v){if(!h){h={};while(b=ob.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===v?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return v||(a=u[c]=u[c]||a,t[a]=b),this},overrideMimeType:function(a){return v||(m.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>v)for(b in a)s[b]=[s[b],a[b]];else x.always(a[x.status]);return this},abort:function(a){var b=a||w;return e&&e.abort(b),z(0,b),this}};if(q.promise(x).complete=r.add,x.success=x.done,x.error=x.fail,m.url=((b||m.url||jb.href)+"").replace(mb,"").replace(rb,jb.protocol+"//"),m.type=c.method||c.type||m.method||m.type,m.dataTypes=n.trim(m.dataType||"*").toLowerCase().match(G)||[""],null==m.crossDomain){j=d.createElement("a");try{j.href=m.url,j.href=j.href,m.crossDomain=vb.protocol+"//"+vb.host!=j.protocol+"//"+j.host}catch(y){m.crossDomain=!0}}if(m.data&&m.processData&&"string"!=typeof m.data&&(m.data=n.param(m.data,m.traditional)),xb(sb,m,c,x),2===v)return x;k=n.event&&m.global,k&&0===n.active++&&n.event.trigger("ajaxStart"),m.type=m.type.toUpperCase(),m.hasContent=!qb.test(m.type),f=m.url,m.hasContent||(m.data&&(f=m.url+=(lb.test(f)?"&":"?")+m.data,delete m.data),m.cache===!1&&(m.url=nb.test(f)?f.replace(nb,"$1_="+kb++):f+(lb.test(f)?"&":"?")+"_="+kb++)),m.ifModified&&(n.lastModified[f]&&x.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&x.setRequestHeader("If-None-Match",n.etag[f])),(m.data&&m.hasContent&&m.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",m.contentType),x.setRequestHeader("Accept",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+("*"!==m.dataTypes[0]?", "+ub+"; q=0.01":""):m.accepts["*"]);for(l in m.headers)x.setRequestHeader(l,m.headers[l]);if(m.beforeSend&&(m.beforeSend.call(o,x,m)===!1||2===v))return x.abort();w="abort";for(l in{success:1,error:1,complete:1})x[l](m[l]);if(e=xb(tb,m,c,x)){if(x.readyState=1,k&&p.trigger("ajaxSend",[x,m]),2===v)return x;m.async&&m.timeout>0&&(i=a.setTimeout(function(){x.abort("timeout")},m.timeout));try{v=1,e.send(t,z)}catch(y){if(!(2>v))throw y;z(-1,y)}}else z(-1,"No Transport");function z(b,c,d,h){var j,l,t,u,w,y=c;2!==v&&(v=2,i&&a.clearTimeout(i),e=void 0,g=h||"",x.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(u=zb(m,x,d)),u=Ab(m,u,x,j),j?(m.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(n.lastModified[f]=w),w=x.getResponseHeader("etag"),w&&(n.etag[f]=w)),204===b||"HEAD"===m.type?y="nocontent":304===b?y="notmodified":(y=u.state,l=u.data,t=u.error,j=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),x.status=b,x.statusText=(c||y)+"",j?q.resolveWith(o,[l,y,x]):q.rejectWith(o,[x,y,t]),x.statusCode(s),s=void 0,k&&p.trigger(j?"ajaxSuccess":"ajaxError",[x,m,j?l:t]),r.fireWith(o,[x,y]),k&&(p.trigger("ajaxComplete",[x,m]),--n.active||n.event.trigger("ajaxStop")))}return x},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return!n.expr.filters.visible(a)},n.expr.filters.visible=function(a){return a.offsetWidth>0||a.offsetHeight>0||a.getClientRects().length>0};var Bb=/%20/g,Cb=/\[\]$/,Db=/\r?\n/g,Eb=/^(?:submit|button|image|reset|file)$/i,Fb=/^(?:input|select|textarea|keygen)/i;function Gb(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Cb.test(a)?d(a,e):Gb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Gb(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Gb(c,a[c],b,e);return d.join("&").replace(Bb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Fb.test(this.nodeName)&&!Eb.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Db,"\r\n")}}):{name:b.name,value:c.replace(Db,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Hb={0:200,1223:204},Ib=n.ajaxSettings.xhr();l.cors=!!Ib&&"withCredentials"in Ib,l.ajax=Ib=!!Ib,n.ajaxTransport(function(b){var c,d;return l.cors||Ib&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Hb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=n("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Jb=[],Kb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Jb.pop()||n.expando+"_"+kb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Kb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Kb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Kb,"$1"+e):b.jsonp!==!1&&(b.url+=(lb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Jb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ca([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var Lb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Lb)return Lb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function Mb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(e=d.getBoundingClientRect(),c=Mb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ea})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;n.fn[a]=function(d){return K(this,function(a,d,e){var f=Mb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ga(l.pixelPosition,function(a,c){return c?(c=Fa(a,b),Ba.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return K(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)},size:function(){return this.length}}),n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Nb=a.jQuery,Ob=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Ob),b&&a.jQuery===n&&(a.jQuery=Nb),n},b||(a.jQuery=a.$=n),n});
  ;
  //     Underscore.js 1.8.3
  //     http://underscorejs.org
  //     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  //     Underscore may be freely distributed under the MIT license.
  (function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])<u?i=a+1:o=a}return i},m.indexOf=r(1,m.findIndex,m.sortedIndex),m.lastIndexOf=r(-1,m.findLastIndex),m.range=function(n,t,r){null==t&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e<arguments.length;)i.push(arguments[e++]);return E(n,r,this,this,i)};return r},m.bindAll=function(n){var t,r,e=arguments.length;if(1>=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this);
  
  (function(t){var e=typeof self=="object"&&self.self==self&&self||typeof global=="object"&&global.global==global&&global;if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,n){e.Backbone=t(e,n,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore"),r;try{r=require("jquery")}catch(n){}t(e,exports,i,r)}else{e.Backbone=t(e,{},e._,e.jQuery||e.Zepto||e.ender||e.$)}})(function(t,e,i,r){var n=t.Backbone;var s=Array.prototype.slice;e.VERSION="1.2.3";e.$=r;e.noConflict=function(){t.Backbone=n;return this};e.emulateHTTP=false;e.emulateJSON=false;var a=function(t,e,r){switch(t){case 1:return function(){return i[e](this[r])};case 2:return function(t){return i[e](this[r],t)};case 3:return function(t,n){return i[e](this[r],h(t,this),n)};case 4:return function(t,n,s){return i[e](this[r],h(t,this),n,s)};default:return function(){var t=s.call(arguments);t.unshift(this[r]);return i[e].apply(i,t)}}};var o=function(t,e,r){i.each(e,function(e,n){if(i[n])t.prototype[n]=a(e,n,r)})};var h=function(t,e){if(i.isFunction(t))return t;if(i.isObject(t)&&!e._isModel(t))return u(t);if(i.isString(t))return function(e){return e.get(t)};return t};var u=function(t){var e=i.matches(t);return function(t){return e(t.attributes)}};var l=e.Events={};var c=/\s+/;var f=function(t,e,r,n,s){var a=0,o;if(r&&typeof r==="object"){if(n!==void 0&&"context"in s&&s.context===void 0)s.context=n;for(o=i.keys(r);a<o.length;a++){e=f(t,e,o[a],r[o[a]],s)}}else if(r&&c.test(r)){for(o=r.split(c);a<o.length;a++){e=t(e,o[a],n,s)}}else{e=t(e,r,n,s)}return e};l.on=function(t,e,i){return d(this,t,e,i)};var d=function(t,e,i,r,n){t._events=f(v,t._events||{},e,i,{context:r,ctx:t,listening:n});if(n){var s=t._listeners||(t._listeners={});s[n.id]=n}return t};l.listenTo=function(t,e,r){if(!t)return this;var n=t._listenId||(t._listenId=i.uniqueId("l"));var s=this._listeningTo||(this._listeningTo={});var a=s[n];if(!a){var o=this._listenId||(this._listenId=i.uniqueId("l"));a=s[n]={obj:t,objId:n,id:o,listeningTo:s,count:0}}d(t,e,r,this,a);return this};var v=function(t,e,i,r){if(i){var n=t[e]||(t[e]=[]);var s=r.context,a=r.ctx,o=r.listening;if(o)o.count++;n.push({callback:i,context:s,ctx:s||a,listening:o})}return t};l.off=function(t,e,i){if(!this._events)return this;this._events=f(g,this._events,t,e,{context:i,listeners:this._listeners});return this};l.stopListening=function(t,e,r){var n=this._listeningTo;if(!n)return this;var s=t?[t._listenId]:i.keys(n);for(var a=0;a<s.length;a++){var o=n[s[a]];if(!o)break;o.obj.off(e,r,this)}if(i.isEmpty(n))this._listeningTo=void 0;return this};var g=function(t,e,r,n){if(!t)return;var s=0,a;var o=n.context,h=n.listeners;if(!e&&!r&&!o){var u=i.keys(h);for(;s<u.length;s++){a=h[u[s]];delete h[a.id];delete a.listeningTo[a.objId]}return}var l=e?[e]:i.keys(t);for(;s<l.length;s++){e=l[s];var c=t[e];if(!c)break;var f=[];for(var d=0;d<c.length;d++){var v=c[d];if(r&&r!==v.callback&&r!==v.callback._callback||o&&o!==v.context){f.push(v)}else{a=v.listening;if(a&&--a.count===0){delete h[a.id];delete a.listeningTo[a.objId]}}}if(f.length){t[e]=f}else{delete t[e]}}if(i.size(t))return t};l.once=function(t,e,r){var n=f(p,{},t,e,i.bind(this.off,this));return this.on(n,void 0,r)};l.listenToOnce=function(t,e,r){var n=f(p,{},e,r,i.bind(this.stopListening,this,t));return this.listenTo(t,n)};var p=function(t,e,r,n){if(r){var s=t[e]=i.once(function(){n(e,s);r.apply(this,arguments)});s._callback=r}return t};l.trigger=function(t){if(!this._events)return this;var e=Math.max(0,arguments.length-1);var i=Array(e);for(var r=0;r<e;r++)i[r]=arguments[r+1];f(m,this._events,t,void 0,i);return this};var m=function(t,e,i,r){if(t){var n=t[e];var s=t.all;if(n&&s)s=s.slice();if(n)_(n,r);if(s)_(s,[e].concat(r))}return t};var _=function(t,e){var i,r=-1,n=t.length,s=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<n)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<n)(i=t[r]).callback.call(i.ctx,s);return;case 2:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a);return;case 3:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a,o);return;default:while(++r<n)(i=t[r]).callback.apply(i.ctx,e);return}};l.bind=l.on;l.unbind=l.off;i.extend(e,l);var y=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId(this.cidPrefix);this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(y.prototype,l,{changed:null,validationError:null,idAttribute:"id",cidPrefix:"c",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},matches:function(t){return!!i.iteratee(t,this)(this.attributes)},set:function(t,e,r){if(t==null)return this;var n;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;var s=r.unset;var a=r.silent;var o=[];var h=this._changing;this._changing=true;if(!h){this._previousAttributes=i.clone(this.attributes);this.changed={}}var u=this.attributes;var l=this.changed;var c=this._previousAttributes;for(var f in n){e=n[f];if(!i.isEqual(u[f],e))o.push(f);if(!i.isEqual(c[f],e)){l[f]=e}else{delete l[f]}s?delete u[f]:u[f]=e}this.id=this.get(this.idAttribute);if(!a){if(o.length)this._pending=r;for(var d=0;d<o.length;d++){this.trigger("change:"+o[d],this,u[o[d]],r)}}if(h)return this;if(!a){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e=this._changing?this._previousAttributes:this.attributes;var r={};for(var n in t){var s=t[n];if(i.isEqual(e[n],s))continue;r[n]=s}return i.size(r)?r:false},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=i.extend({parse:true},t);var e=this;var r=t.success;t.success=function(i){var n=t.parse?e.parse(i,t):i;if(!e.set(n,t))return false;if(r)r.call(t.context,e,i,t);e.trigger("sync",e,i,t)};z(this,t);return this.sync("read",this,t)},save:function(t,e,r){var n;if(t==null||typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r=i.extend({validate:true,parse:true},r);var s=r.wait;if(n&&!s){if(!this.set(n,r))return false}else{if(!this._validate(n,r))return false}var a=this;var o=r.success;var h=this.attributes;r.success=function(t){a.attributes=h;var e=r.parse?a.parse(t,r):t;if(s)e=i.extend({},n,e);if(e&&!a.set(e,r))return false;if(o)o.call(r.context,a,t,r);a.trigger("sync",a,t,r)};z(this,r);if(n&&s)this.attributes=i.extend({},h,n);var u=this.isNew()?"create":r.patch?"patch":"update";if(u==="patch"&&!r.attrs)r.attrs=n;var l=this.sync(u,this,r);this.attributes=h;return l},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var n=t.wait;var s=function(){e.stopListening();e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(n)s();if(r)r.call(t.context,e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};var a=false;if(this.isNew()){i.defer(t.success)}else{z(this,t);a=this.sync("delete",this,t)}if(!n)s();return a},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||F();if(this.isNew())return t;var e=this.get(this.idAttribute);return t.replace(/[^\/]$/,"$&/")+encodeURIComponent(e)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.defaults({validate:true},t))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var b={keys:1,values:1,pairs:1,invert:1,pick:0,omit:0,chain:1,isEmpty:1};o(y,b,"attributes");var x=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var w={add:true,remove:true,merge:true};var E={add:true,remove:false};var k=function(t,e,i){i=Math.min(Math.max(i,0),t.length);var r=Array(t.length-i);var n=e.length;for(var s=0;s<r.length;s++)r[s]=t[s+i];for(s=0;s<n;s++)t[s+i]=e[s];for(s=0;s<r.length;s++)t[s+n+i]=r[s]};i.extend(x.prototype,l,{model:y,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,E))},remove:function(t,e){e=i.extend({},e);var r=!i.isArray(t);t=r?[t]:i.clone(t);var n=this._removeModels(t,e);if(!e.silent&&n)this.trigger("update",this,e);return r?n[0]:n},set:function(t,e){if(t==null)return;e=i.defaults({},e,w);if(e.parse&&!this._isModel(t))t=this.parse(t,e);var r=!i.isArray(t);t=r?[t]:t.slice();var n=e.at;if(n!=null)n=+n;if(n<0)n+=this.length+1;var s=[];var a=[];var o=[];var h={};var u=e.add;var l=e.merge;var c=e.remove;var f=false;var d=this.comparator&&n==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g;for(var p=0;p<t.length;p++){g=t[p];var m=this.get(g);if(m){if(l&&g!==m){var _=this._isModel(g)?g.attributes:g;if(e.parse)_=m.parse(_,e);m.set(_,e);if(d&&!f)f=m.hasChanged(v)}if(!h[m.cid]){h[m.cid]=true;s.push(m)}t[p]=m}else if(u){g=t[p]=this._prepareModel(g,e);if(g){a.push(g);this._addReference(g,e);h[g.cid]=true;s.push(g)}}}if(c){for(p=0;p<this.length;p++){g=this.models[p];if(!h[g.cid])o.push(g)}if(o.length)this._removeModels(o,e)}var y=false;var b=!d&&u&&c;if(s.length&&b){y=this.length!=s.length||i.some(this.models,function(t,e){return t!==s[e]});this.models.length=0;k(this.models,s,0);this.length=this.models.length}else if(a.length){if(d)f=true;k(this.models,a,n==null?this.length:n);this.length=this.models.length}if(f)this.sort({silent:true});if(!e.silent){for(p=0;p<a.length;p++){if(n!=null)e.index=n+p;g=a[p];g.trigger("add",g,this,e)}if(f||y)this.trigger("sort",this,e);if(a.length||o.length)this.trigger("update",this,e)}return r?t[0]:t},reset:function(t,e){e=e?i.clone(e):{};for(var r=0;r<this.models.length;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);return this.remove(e,t)},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);return this.remove(e,t)},slice:function(){return s.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;var e=this.modelId(this._isModel(t)?t.attributes:t);return this._byId[t]||this._byId[e]||this._byId[t.cid]},at:function(t){if(t<0)t+=this.length;return this.models[t]},where:function(t,e){return this[e?"find":"filter"](t)},findWhere:function(t){return this.where(t,true)},sort:function(t){var e=this.comparator;if(!e)throw new Error("Cannot sort a set without a comparator");t||(t={});var r=e.length;if(i.isFunction(e))e=i.bind(e,this);if(r===1||i.isString(e)){this.models=this.sortBy(e)}else{this.models.sort(e)}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=i.extend({parse:true},t);var e=t.success;var r=this;t.success=function(i){var n=t.reset?"reset":"set";r[n](i,t);if(e)e.call(t.context,r,i,t);r.trigger("sync",r,i,t)};z(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};var r=e.wait;t=this._prepareModel(t,e);if(!t)return false;if(!r)this.add(t,e);var n=this;var s=e.success;e.success=function(t,e,i){if(r)n.add(t,i);if(s)s.call(i.context,t,e,i)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models,{model:this.model,comparator:this.comparator})},modelId:function(t){return t[this.model.prototype.idAttribute||"id"]},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(this._isModel(t)){if(!t.collection)t.collection=this;return t}e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_removeModels:function(t,e){var i=[];for(var r=0;r<t.length;r++){var n=this.get(t[r]);if(!n)continue;var s=this.indexOf(n);this.models.splice(s,1);this.length--;if(!e.silent){e.index=s;n.trigger("remove",n,this,e)}i.push(n);this._removeReference(n,e)}return i.length?i:false},_isModel:function(t){return t instanceof y},_addReference:function(t,e){this._byId[t.cid]=t;var i=this.modelId(t.attributes);if(i!=null)this._byId[i]=t;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){delete this._byId[t.cid];var i=this.modelId(t.attributes);if(i!=null)delete this._byId[i];if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(t==="change"){var n=this.modelId(e.previousAttributes());var s=this.modelId(e.attributes);if(n!==s){if(n!=null)delete this._byId[n];if(s!=null)this._byId[s]=e}}this.trigger.apply(this,arguments)}});var S={forEach:3,each:3,map:3,collect:3,reduce:4,foldl:4,inject:4,reduceRight:4,foldr:4,find:3,detect:3,filter:3,select:3,reject:3,every:3,all:3,some:3,any:3,include:3,includes:3,contains:3,invoke:0,max:3,min:3,toArray:1,size:1,first:3,head:3,take:3,initial:3,rest:3,tail:3,drop:3,last:3,without:0,difference:0,indexOf:3,shuffle:1,lastIndexOf:3,isEmpty:1,chain:1,sample:3,partition:3,groupBy:3,countBy:3,sortBy:3,indexBy:3};o(x,S,"models");var I=e.View=function(t){this.cid=i.uniqueId("view");i.extend(this,i.pick(t,P));this._ensureElement();this.initialize.apply(this,arguments)};var T=/^(\S+)\s*(.*)$/;var P=["model","collection","el","id","attributes","className","tagName","events"];i.extend(I.prototype,l,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this._removeElement();this.stopListening();return this},_removeElement:function(){this.$el.remove()},setElement:function(t){this.undelegateEvents();this._setElement(t);this.delegateEvents();return this},_setElement:function(t){this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0]},delegateEvents:function(t){t||(t=i.result(this,"events"));if(!t)return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[r];if(!r)continue;var n=e.match(T);this.delegate(n[1],n[2],i.bind(r,this))}return this},delegate:function(t,e,i){this.$el.on(t+".delegateEvents"+this.cid,e,i);return this},undelegateEvents:function(){if(this.$el)this.$el.off(".delegateEvents"+this.cid);return this},undelegate:function(t,e,i){this.$el.off(t+".delegateEvents"+this.cid,e,i);return this},_createElement:function(t){return document.createElement(t)},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");this.setElement(this._createElement(i.result(this,"tagName")));this._setAttributes(t)}else{this.setElement(i.result(this,"el"))}},_setAttributes:function(t){this.$el.attr(t)}});e.sync=function(t,r,n){var s=H[t];i.defaults(n||(n={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:s,dataType:"json"};if(!n.url){a.url=i.result(r,"url")||F()}if(n.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(n.attrs||r.toJSON(n))}if(n.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(n.emulateHTTP&&(s==="PUT"||s==="DELETE"||s==="PATCH")){a.type="POST";if(n.emulateJSON)a.data._method=s;var o=n.beforeSend;n.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",s);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!n.emulateJSON){a.processData=false}var h=n.error;n.error=function(t,e,i){n.textStatus=e;n.errorThrown=i;if(h)h.call(n.context,t,e,i)};var u=n.xhr=e.ajax(i.extend(a,n));r.trigger("request",r,u,n);return u};var H={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var A=/\((.*?)\)/g;var C=/(\(\?)?:\w+/g;var R=/\*\w+/g;var j=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,l,{initialize:function(){},route:function(t,r,n){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){n=r;r=""}if(!n)n=this[r];var s=this;e.history.route(t,function(i){var a=s._extractParameters(t,i);if(s.execute(n,a,r)!==false){s.trigger.apply(s,["route:"+r].concat(a));s.trigger("route",r,a);e.history.trigger("route",s,r,a)}});return this},execute:function(t,e,i){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(j,"\\$&").replace(A,"(?:$1)?").replace(C,function(t,e){return e?t:"([^/?]+)"}).replace(R,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var M=e.History=function(){this.handlers=[];this.checkUrl=i.bind(this.checkUrl,this);if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var N=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var U=/#.*$/;M.started=false;i.extend(M.prototype,l,{interval:50,atRoot:function(){var t=this.location.pathname.replace(/[^\/]$/,"$&/");return t===this.root&&!this.getSearch()},matchRoot:function(){var t=this.decodeFragment(this.location.pathname);var e=t.slice(0,this.root.length-1)+"/";return e===this.root},decodeFragment:function(t){return decodeURI(t.replace(/%25/g,"%2525"))},getSearch:function(){var t=this.location.href.replace(/#.*/,"").match(/\?.+/);return t?t[0]:""},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getPath:function(){var t=this.decodeFragment(this.location.pathname+this.getSearch()).slice(this.root.length-1);return t.charAt(0)==="/"?t.slice(1):t},getFragment:function(t){if(t==null){if(this._usePushState||!this._wantsHashChange){t=this.getPath()}else{t=this.getHash()}}return t.replace(N,"")},start:function(t){if(M.started)throw new Error("Backbone.history has already been started");M.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._hasHashChange="onhashchange"in window&&(document.documentMode===void 0||document.documentMode>7);this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=("/"+this.root+"/").replace(O,"/");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||"/";this.location.replace(e+"#"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe");this.iframe.src="javascript:0";this.iframe.style.display="none";this.iframe.tabIndex=-1;var r=document.body;var n=r.insertBefore(this.iframe,r.firstChild).contentWindow;n.document.open();n.document.close();n.location.hash="#"+this.fragment}var s=window.addEventListener||function(t,e){return attachEvent("on"+t,e)};if(this._usePushState){s("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){s("hashchange",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent("on"+t,e)};if(this._usePushState){t("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t("hashchange",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);M.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe.contentWindow)}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){if(!this.matchRoot())return false;t=this.fragment=this.getFragment(t);return i.some(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!M.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||"");var i=this.root;if(t===""||t.charAt(0)==="?"){i=i.slice(0,-1)||"/"}var r=i+t;t=this.decodeFragment(t.replace(U,""));if(this.fragment===t)return;this.fragment=t;if(this._usePushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,r)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe.contentWindow)){var n=this.iframe.contentWindow;if(!e.replace){n.document.open();n.document.close()}this._updateHash(n.location,t,e.replace)}}else{return this.location.assign(r)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new M;var q=function(t,e){var r=this;var n;if(t&&i.has(t,"constructor")){n=t.constructor}else{n=function(){return r.apply(this,arguments)}}i.extend(n,r,e);var s=function(){this.constructor=n};s.prototype=r.prototype;n.prototype=new s;if(t)i.extend(n.prototype,t);n.__super__=r.prototype;return n};y.extend=x.extend=$.extend=I.extend=M.extend=q;var F=function(){throw new Error('A "url" property or function must be specified')};var z=function(t,e){var i=e.error;e.error=function(r){if(i)i.call(e.context,t,r,e);t.trigger("error",t,r,e)}};return e});
  
  /*!
   * jQuery Once v2.1.1 - http://github.com/robloach/jquery-once
   * @license MIT, GPL-2.0
   *   http://opensource.org/licenses/MIT
   *   http://opensource.org/licenses/GPL-2.0
   */
  (function(e){"use strict";if(typeof exports==="object"){e(require("jquery"))}else if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(function(e){"use strict";var n=function(e){e=e||"once";if(typeof e!=="string"){throw new Error("The jQuery Once id parameter must be a string")}return e};e.fn.once=function(t){var r="jquery-once-"+n(t);return this.filter(function(){return e(this).data(r)!==true}).data(r,true)};e.fn.removeOnce=function(e){return this.findOnce(e).removeData("jquery-once-"+n(e))};e.fn.findOnce=function(t){var r="jquery-once-"+n(t);return this.filter(function(){return e(this).data(r)===true})}});
  
  /**
   * @file
   * Parse inline JSON and initialize the drupalSettings global object.
   */
  
  (function () {
  
    'use strict';
  
    // Use direct child elements to harden against XSS exploits when CSP is on.
    var settingsElement = document.querySelector('head > script[type="application/json"][data-drupal-selector="drupal-settings-json"], body > script[type="application/json"][data-drupal-selector="drupal-settings-json"]');
  
    /**
     * Variable generated by Drupal with all the configuration created from PHP.
     *
     * @global
     *
     * @type {object}
     */
    window.drupalSettings = {};
  
    if (settingsElement !== null) {
      window.drupalSettings = JSON.parse(settingsElement.textContent);
    }
  })();
  ;
  window.drupalTranslations = {"strings":{"":{"An AJAX HTTP error occurred.":"Hubo un error HTTP AJAX.","HTTP Result Code: !status":"C\u00f3digo de Resultado HTTP: !status","An AJAX HTTP request terminated abnormally.":"Una solicitud HTTP de AJAX termin\u00f3 de manera anormal.","Debugging information follows.":"A continuaci\u00f3n se detalla la informaci\u00f3n de depuraci\u00f3n.","Path: !uri":"Ruta: !uri","StatusText: !statusText":"StatusText: !statusText","ResponseText: !responseText":"ResponseText: !responseText","ReadyState: !readyState":"ReadyState: !readyState","CustomMessage: !customMessage":"CustomMessage: !customMessage","Please wait...":"Espere, por favor...","The response failed verification so will not be processed.":"La respuesta de verificaci\u00f3n fall\u00f3, por lo que no se procesar\u00e1.","The callback URL is not local and not trusted: !url":"La URL de llamada no es local y no es confiable: !url","Changed":"Cambiado","Home":"Inicio","closed":"cerrado","Cancel":"Cancelar","new":"nuevo","Edit":"Editar","Link":"Enlace","Image":"Imagen","Save":"Guardar","Open":"Abierta","Add":"Agregar","Continue":"Continuar","OK":"OK","Close":"Cerrar","Show":"Mostrar","Select all rows in this table":"Seleccionar todas las filas de esta tabla","Deselect all rows in this table":"Quitar la selecci\u00f3n a todas las filas de esta tabla","Extend":"Ampliar","Not published":"No publicado","Loading...":"Cargando...","Hide":"Ocultar","1 new comment\u0003@count new comments":"1 comentario nuevo\u0003@count comentarios nuevos","Unlink":"Desvincular","Not promoted":"No publicado en p\u00e1gina principal","Quick edit":"Edici\u00f3n r\u00e1pida","Edit Link":"Editar enlace","Remove group":"Eliminar grupo","By @name on @date":"Por @name en @date","By @name":"Por @name","Not in menu":"No est\u00e1 en un men\u00fa","Alias: @alias":"Alias: @alias","No alias":"Sin alias","@label":"@label","New revision":"Nueva revisi\u00f3n","Drag to re-order":"Arrastre para reordenar","Discard changes":"\u00bfDescartar cambios?","Saving":"Guardando","No revision":"Sin revisi\u00f3n","Requires a title":"Necesita un t\u00edtulo","Not restricted":"Sin restricci\u00f3n","(active tab)":"(solapa activa)","Restricted to certain pages":"Restringido a algunas p\u00e1ginas","The block cannot be placed in this region.":"El bloque no se puede colocar en esta regi\u00f3n.","Hide summary":"Ocultar resumen","Edit summary":"Editar resumen","Don\u0027t display post information":"No mostrar informaci\u00f3n del env\u00edo","Collapse":"Plegar","The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.":"El archivo seleccionado %filename no se puede subir al srvidor. Solo se permiten archivos con las siguientes extensiones: %extensions.","Re-order rows by numerical weight instead of dragging.":"Reordenar las filas por peso num\u00e9rico en lugar de arrastrar.","Show row weights":"Mostrar pesos de la fila","Hide row weights":"Ocultar pesos de la fila","Apply (all displays)":"Aplicar (todas las presentaciones)","Apply (this display)":"Aplicar (esta presentaci\u00f3n)","Revert to default":"Volver al valor inicial","You have unsaved changes":"Usted tiene cambios no guaradados","Needs to be updated":"Necesita ser actualizado","Does not need to be updated":"No necesita ser actualizado","Show all columns":"Mostrar todas las columnas","Show table cells that were hidden to make the table fit within a small screen.":"Mostrar celdas de tablas que estaban ocultas para que la tabla se ajuste a una pantalla peque\u00f1a.","List additional actions":"Lista adicional de acciones","Flag other translations as outdated":"Marcar las otras traducciones como desfasadas","Do not flag other translations as outdated":"No marcar las otras traducciones como desfasadas","opened":"abierto","Horizontal orientation":"Orientaci\u00f3n horizontal","Vertical orientation":"Orientaci\u00f3n vertical","Tray orientation changed to @orientation.":"La orientaci\u00f3n de la bandeja se ha cambiado a @orientation.","You have unsaved changes.":"Tiene cambios sin guardar.","@action @title configuration options":"@action @title opciones de configuraci\u00f3n","Tabbing is no longer constrained by the Contextual module.":"Tabulando (Tabbing) ya no se ver\u00e1 limitado por el m\u00f3dulo Contextual (Contextual).","Tabbing is constrained to a set of @contextualsCount and the edit mode toggle.":"La tabulaci\u00f3n est\u00e1 restringida a un conjunto de @contextualsCount y al cambio a modo de edici\u00f3n.","Press the esc key to exit.":"Presionar tecla esc para salir.","@count contextual link\u0003@count contextual links":"@count enlace contextual\u0003@count enlaces contextuales","!tour_item of !total":"!tour_item de !total","End tour":"Final del recorrido","Discard changes?":"\u00bfDescartar cambios?","The toolbar cannot be set to a horizontal orientation when it is locked.":"La barra de herramientas no puede ser puesta en orientaci\u00f3n horizontal cuando esta bloqueada.","Could not load the form for \u003Cq\u003E@field-label\u003C\/q\u003E, either due to a website problem or a network connection problem.\u003Cbr\u003EPlease try again.":"No se pudo cargar el formulario para \u003Cq\u003E@field-label\u003C\/q\u003E, ya sea debido a un problema en el sitio, ya por un problema de conexi\u00f3n de red.\u003Cbr\u003EPor favor, int\u00e9ntelo de nuevo.","Your changes to \u003Cq\u003E@entity-title\u003C\/q\u003E could not be saved, either due to a website problem or a network connection problem.\u003Cbr\u003EPlease try again.":"Los cambios en \u003Cq\u003E@entity-title\u003C\/q\u003E no podr\u00e1n salvarse, debido a un problema en el sitio web o un problema de conexi\u00f3n de red.\u003Cbr\u003EPor favor, int\u00e9ntelo de nuevo.","Changing the text format to %text_format will permanently remove content that is not allowed in that text format.\u003Cbr\u003E\u003Cbr\u003ESave your changes before switching the text format to avoid losing data.":"Cambiar el formato de texto a %text_format eliminar\u00e1 permanentemente el contenido que no est\u00e1 permitido en ese formato de texto.\u003Cbr\u003E\u003Cbr\u003EGuarde sus datos antes de cambiar el formato de texto para evitar perder datos.","Change text format?":"\u00bfCambiar el formato de texto?","Rich Text Editor, !label field":"Editor de texto con formato, campo !label","Tray \u0022@tray\u0022 @action.":"Bandeja \u0022@tray\u0022 @action","Tray @action.":"Bandeja @action.","Hide lower priority columns":"Ocultar columnas de menor prioridad","!modules modules are available in the modified list.":"!modules m\u00f3dulos est\u00e1n disponibles en la lista modificada.","Network problem!":"Problema de red!","Authored on @date":"Escrito el @date"}},"pluralFormula":{"1":0,"default":1}};;
  /**
   * @file
   * Defines the Drupal JavaScript API.
   */
  
  /**
   * A jQuery object, typically the return value from a `$(selector)` call.
   *
   * Holds an HTMLElement or a collection of HTMLElements.
   *
   * @typedef {object} jQuery
   *
   * @prop {number} length=0
   *   Number of elements contained in the jQuery object.
   */
  
  /**
   * Variable generated by Drupal that holds all translated strings from PHP.
   *
   * Content of this variable is automatically created by Drupal when using the
   * Interface Translation module. It holds the translation of strings used on
   * the page.
   *
   * This variable is used to pass data from the backend to the frontend. Data
   * contained in `drupalSettings` is used during behavior initialization.
   *
   * @global
   *
   * @var {object} drupalTranslations
   */
  
  /**
   * Global Drupal object.
   *
   * All Drupal JavaScript APIs are contained in this namespace.
   *
   * @global
   *
   * @namespace
   */
  window.Drupal = {behaviors: {}, locale: {}};
  
  // JavaScript should be made compatible with libraries other than jQuery by
  // wrapping it in an anonymous closure.
  (function (Drupal, drupalSettings, drupalTranslations) {
  
    'use strict';
  
    /**
     * Helper to rethrow errors asynchronously.
     *
     * This way Errors bubbles up outside of the original callstack, making it
     * easier to debug errors in the browser.
     *
     * @param {Error|string} error
     *   The error to be thrown.
     */
    Drupal.throwError = function (error) {
      setTimeout(function () { throw error; }, 0);
    };
  
    /**
     * Custom error thrown after attach/detach if one or more behaviors failed.
     * Initializes the JavaScript behaviors for page loads and Ajax requests.
     *
     * @callback Drupal~behaviorAttach
     *
     * @param {HTMLDocument|HTMLElement} context
     *   An element to detach behaviors from.
     * @param {?object} settings
     *   An object containing settings for the current context. It is rarely used.
     *
     * @see Drupal.attachBehaviors
     */
  
    /**
     * Reverts and cleans up JavaScript behavior initialization.
     *
     * @callback Drupal~behaviorDetach
     *
     * @param {HTMLDocument|HTMLElement} context
     *   An element to attach behaviors to.
     * @param {object} settings
     *   An object containing settings for the current context.
     * @param {string} trigger
     *   One of `'unload'`, `'move'`, or `'serialize'`.
     *
     * @see Drupal.detachBehaviors
     */
  
    /**
     * @typedef {object} Drupal~behavior
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Function run on page load and after an Ajax call.
     * @prop {Drupal~behaviorDetach} detach
     *   Function run when content is serialized or removed from the page.
     */
  
    /**
     * Holds all initialization methods.
     *
     * @namespace Drupal.behaviors
     *
     * @type {Object.<string, Drupal~behavior>}
     */
  
    /**
     * Defines a behavior to be run during attach and detach phases.
     *
     * Attaches all registered behaviors to a page element.
     *
     * Behaviors are event-triggered actions that attach to page elements,
     * enhancing default non-JavaScript UIs. Behaviors are registered in the
     * {@link Drupal.behaviors} object using the method 'attach' and optionally
     * also 'detach'.
     *
     * {@link Drupal.attachBehaviors} is added below to the `jQuery.ready` event
     * and therefore runs on initial page load. Developers implementing Ajax in
     * their solutions should also call this function after new page content has
     * been loaded, feeding in an element to be processed, in order to attach all
     * behaviors to the new content.
     *
     * Behaviors should use `var elements =
     * $(context).find(selector).once('behavior-name');` to ensure the behavior is
     * attached only once to a given element. (Doing so enables the reprocessing
     * of given elements, which may be needed on occasion despite the ability to
     * limit behavior attachment to a particular element.)
     *
     * @example
     * Drupal.behaviors.behaviorName = {
     *   attach: function (context, settings) {
     *     // ...
     *   },
     *   detach: function (context, settings, trigger) {
     *     // ...
     *   }
     * };
     *
     * @param {HTMLDocument|HTMLElement} [context=document]
     *   An element to attach behaviors to.
     * @param {object} [settings=drupalSettings]
     *   An object containing settings for the current context. If none is given,
     *   the global {@link drupalSettings} object is used.
     *
     * @see Drupal~behaviorAttach
     * @see Drupal.detachBehaviors
     *
     * @throws {Drupal~DrupalBehaviorError}
     */
    Drupal.attachBehaviors = function (context, settings) {
      context = context || document;
      settings = settings || drupalSettings;
      var behaviors = Drupal.behaviors;
      // Execute all of them.
      for (var i in behaviors) {
        if (behaviors.hasOwnProperty(i) && typeof behaviors[i].attach === 'function') {
          // Don't stop the execution of behaviors in case of an error.
          try {
            behaviors[i].attach(context, settings);
          }
          catch (e) {
            Drupal.throwError(e);
          }
        }
      }
    };
  
    /**
     * Detaches registered behaviors from a page element.
     *
     * Developers implementing Ajax in their solutions should call this function
     * before page content is about to be removed, feeding in an element to be
     * processed, in order to allow special behaviors to detach from the content.
     *
     * Such implementations should use `.findOnce()` and `.removeOnce()` to find
     * elements with their corresponding `Drupal.behaviors.behaviorName.attach`
     * implementation, i.e. `.removeOnce('behaviorName')`, to ensure the behavior
     * is detached only from previously processed elements.
     *
     * @param {HTMLDocument|HTMLElement} [context=document]
     *   An element to detach behaviors from.
     * @param {object} [settings=drupalSettings]
     *   An object containing settings for the current context. If none given,
     *   the global {@link drupalSettings} object is used.
     * @param {string} [trigger='unload']
     *   A string containing what's causing the behaviors to be detached. The
     *   possible triggers are:
     *   - `'unload'`: The context element is being removed from the DOM.
     *   - `'move'`: The element is about to be moved within the DOM (for example,
     *     during a tabledrag row swap). After the move is completed,
     *     {@link Drupal.attachBehaviors} is called, so that the behavior can undo
     *     whatever it did in response to the move. Many behaviors won't need to
     *     do anything simply in response to the element being moved, but because
     *     IFRAME elements reload their "src" when being moved within the DOM,
     *     behaviors bound to IFRAME elements (like WYSIWYG editors) may need to
     *     take some action.
     *   - `'serialize'`: When an Ajax form is submitted, this is called with the
     *     form as the context. This provides every behavior within the form an
     *     opportunity to ensure that the field elements have correct content
     *     in them before the form is serialized. The canonical use-case is so
     *     that WYSIWYG editors can update the hidden textarea to which they are
     *     bound.
     *
     * @throws {Drupal~DrupalBehaviorError}
     *
     * @see Drupal~behaviorDetach
     * @see Drupal.attachBehaviors
     */
    Drupal.detachBehaviors = function (context, settings, trigger) {
      context = context || document;
      settings = settings || drupalSettings;
      trigger = trigger || 'unload';
      var behaviors = Drupal.behaviors;
      // Execute all of them.
      for (var i in behaviors) {
        if (behaviors.hasOwnProperty(i) && typeof behaviors[i].detach === 'function') {
          // Don't stop the execution of behaviors in case of an error.
          try {
            behaviors[i].detach(context, settings, trigger);
          }
          catch (e) {
            Drupal.throwError(e);
          }
        }
      }
    };
  
    /**
     * Encodes special characters in a plain-text string for display as HTML.
     *
     * @param {string} str
     *   The string to be encoded.
     *
     * @return {string}
     *   The encoded string.
     *
     * @ingroup sanitization
     */
    Drupal.checkPlain = function (str) {
      str = str.toString()
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
      return str;
    };
  
    /**
     * Replaces placeholders with sanitized values in a string.
     *
     * @param {string} str
     *   A string with placeholders.
     * @param {object} args
     *   An object of replacements pairs to make. Incidences of any key in this
     *   array are replaced with the corresponding value. Based on the first
     *   character of the key, the value is escaped and/or themed:
     *    - `'!variable'`: inserted as is.
     *    - `'@variable'`: escape plain text to HTML ({@link Drupal.checkPlain}).
     *    - `'%variable'`: escape text and theme as a placeholder for user-
     *      submitted content ({@link Drupal.checkPlain} +
     *      `{@link Drupal.theme}('placeholder')`).
     *
     * @return {string}
     *   The formatted string.
     *
     * @see Drupal.t
     */
    Drupal.formatString = function (str, args) {
      // Keep args intact.
      var processedArgs = {};
      // Transform arguments before inserting them.
      for (var key in args) {
        if (args.hasOwnProperty(key)) {
          switch (key.charAt(0)) {
            // Escaped only.
            case '@':
              processedArgs[key] = Drupal.checkPlain(args[key]);
              break;
  
            // Pass-through.
            case '!':
              processedArgs[key] = args[key];
              break;
  
            // Escaped and placeholder.
            default:
              processedArgs[key] = Drupal.theme('placeholder', args[key]);
              break;
          }
        }
      }
  
      return Drupal.stringReplace(str, processedArgs, null);
    };
  
    /**
     * Replaces substring.
     *
     * The longest keys will be tried first. Once a substring has been replaced,
     * its new value will not be searched again.
     *
     * @param {string} str
     *   A string with placeholders.
     * @param {object} args
     *   Key-value pairs.
     * @param {Array|null} keys
     *   Array of keys from `args`. Internal use only.
     *
     * @return {string}
     *   The replaced string.
     */
    Drupal.stringReplace = function (str, args, keys) {
      if (str.length === 0) {
        return str;
      }
  
      // If the array of keys is not passed then collect the keys from the args.
      if (!Array.isArray(keys)) {
        keys = [];
        for (var k in args) {
          if (args.hasOwnProperty(k)) {
            keys.push(k);
          }
        }
  
        // Order the keys by the character length. The shortest one is the first.
        keys.sort(function (a, b) { return a.length - b.length; });
      }
  
      if (keys.length === 0) {
        return str;
      }
  
      // Take next longest one from the end.
      var key = keys.pop();
      var fragments = str.split(key);
  
      if (keys.length) {
        for (var i = 0; i < fragments.length; i++) {
          // Process each fragment with a copy of remaining keys.
          fragments[i] = Drupal.stringReplace(fragments[i], args, keys.slice(0));
        }
      }
  
      return fragments.join(args[key]);
    };
  
    /**
     * Translates strings to the page language, or a given language.
     *
     * See the documentation of the server-side t() function for further details.
     *
     * @param {string} str
     *   A string containing the English text to translate.
     * @param {Object.<string, string>} [args]
     *   An object of replacements pairs to make after translation. Incidences
     *   of any key in this array are replaced with the corresponding value.
     *   See {@link Drupal.formatString}.
     * @param {object} [options]
     *   Additional options for translation.
     * @param {string} [options.context='']
     *   The context the source string belongs to.
     *
     * @return {string}
     *   The formatted string.
     *   The translated string.
     */
    Drupal.t = function (str, args, options) {
      options = options || {};
      options.context = options.context || '';
  
      // Fetch the localized version of the string.
      if (typeof drupalTranslations !== 'undefined' && drupalTranslations.strings && drupalTranslations.strings[options.context] && drupalTranslations.strings[options.context][str]) {
        str = drupalTranslations.strings[options.context][str];
      }
  
      if (args) {
        str = Drupal.formatString(str, args);
      }
      return str;
    };
  
    /**
     * Returns the URL to a Drupal page.
     *
     * @param {string} path
     *   Drupal path to transform to URL.
     *
     * @return {string}
     *   The full URL.
     */
    Drupal.url = function (path) {
      return drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + path;
    };
  
    /**
     * Returns the passed in URL as an absolute URL.
     *
     * @param {string} url
     *   The URL string to be normalized to an absolute URL.
     *
     * @return {string}
     *   The normalized, absolute URL.
     *
     * @see https://github.com/angular/angular.js/blob/v1.4.4/src/ng/urlUtils.js
     * @see https://grack.com/blog/2009/11/17/absolutizing-url-in-javascript
     * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L53
     */
    Drupal.url.toAbsolute = function (url) {
      var urlParsingNode = document.createElement('a');
  
      // Decode the URL first; this is required by IE <= 6. Decoding non-UTF-8
      // strings may throw an exception.
      try {
        url = decodeURIComponent(url);
      }
      catch (e) {
        // Empty.
      }
  
      urlParsingNode.setAttribute('href', url);
  
      // IE <= 7 normalizes the URL when assigned to the anchor node similar to
      // the other browsers.
      return urlParsingNode.cloneNode(false).href;
    };
  
    /**
     * Returns true if the URL is within Drupal's base path.
     *
     * @param {string} url
     *   The URL string to be tested.
     *
     * @return {bool}
     *   `true` if local.
     *
     * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L58
     */
    Drupal.url.isLocal = function (url) {
      // Always use browser-derived absolute URLs in the comparison, to avoid
      // attempts to break out of the base path using directory traversal.
      var absoluteUrl = Drupal.url.toAbsolute(url);
      var protocol = location.protocol;
  
      // Consider URLs that match this site's base URL but use HTTPS instead of HTTP
      // as local as well.
      if (protocol === 'http:' && absoluteUrl.indexOf('https:') === 0) {
        protocol = 'https:';
      }
      var baseUrl = protocol + '//' + location.host + drupalSettings.path.baseUrl.slice(0, -1);
  
      // Decoding non-UTF-8 strings may throw an exception.
      try {
        absoluteUrl = decodeURIComponent(absoluteUrl);
      }
      catch (e) {
        // Empty.
      }
      try {
        baseUrl = decodeURIComponent(baseUrl);
      }
      catch (e) {
        // Empty.
      }
  
      // The given URL matches the site's base URL, or has a path under the site's
      // base URL.
      return absoluteUrl === baseUrl || absoluteUrl.indexOf(baseUrl + '/') === 0;
    };
  
    /**
     * Formats a string containing a count of items.
     *
     * This function ensures that the string is pluralized correctly. Since
     * {@link Drupal.t} is called by this function, make sure not to pass
     * already-localized strings to it.
     *
     * See the documentation of the server-side
     * \Drupal\Core\StringTranslation\TranslationInterface::formatPlural()
     * function for more details.
     *
     * @param {number} count
     *   The item count to display.
     * @param {string} singular
     *   The string for the singular case. Please make sure it is clear this is
     *   singular, to ease translation (e.g. use "1 new comment" instead of "1
     *   new"). Do not use @count in the singular string.
     * @param {string} plural
     *   The string for the plural case. Please make sure it is clear this is
     *   plural, to ease translation. Use @count in place of the item count, as in
     *   "@count new comments".
     * @param {object} [args]
     *   An object of replacements pairs to make after translation. Incidences
     *   of any key in this array are replaced with the corresponding value.
     *   See {@link Drupal.formatString}.
     *   Note that you do not need to include @count in this array.
     *   This replacement is done automatically for the plural case.
     * @param {object} [options]
     *   The options to pass to the {@link Drupal.t} function.
     *
     * @return {string}
     *   A translated string.
     */
    Drupal.formatPlural = function (count, singular, plural, args, options) {
      args = args || {};
      args['@count'] = count;
  
      var pluralDelimiter = drupalSettings.pluralDelimiter;
      var translations = Drupal.t(singular + pluralDelimiter + plural, args, options).split(pluralDelimiter);
      var index = 0;
  
      // Determine the index of the plural form.
      if (typeof drupalTranslations !== 'undefined' && drupalTranslations.pluralFormula) {
        index = count in drupalTranslations.pluralFormula ? drupalTranslations.pluralFormula[count] : drupalTranslations.pluralFormula['default'];
      }
      else if (args['@count'] !== 1) {
        index = 1;
      }
  
      return translations[index];
    };
  
    /**
     * Encodes a Drupal path for use in a URL.
     *
     * For aesthetic reasons slashes are not escaped.
     *
     * @param {string} item
     *   Unencoded path.
     *
     * @return {string}
     *   The encoded path.
     */
    Drupal.encodePath = function (item) {
      return window.encodeURIComponent(item).replace(/%2F/g, '/');
    };
  
    /**
     * Generates the themed representation of a Drupal object.
     *
     * All requests for themed output must go through this function. It examines
     * the request and routes it to the appropriate theme function. If the current
     * theme does not provide an override function, the generic theme function is
     * called.
     *
     * @example
     * <caption>To retrieve the HTML for text that should be emphasized and
     * displayed as a placeholder inside a sentence.</caption>
     * Drupal.theme('placeholder', text);
     *
     * @namespace
     *
     * @param {function} func
     *   The name of the theme function to call.
     * @param {...args}
     *   Additional arguments to pass along to the theme function.
     *
     * @return {string|object|HTMLElement|jQuery}
     *   Any data the theme function returns. This could be a plain HTML string,
     *   but also a complex object.
     */
    Drupal.theme = function (func) {
      var args = Array.prototype.slice.apply(arguments, [1]);
      if (func in Drupal.theme) {
        return Drupal.theme[func].apply(this, args);
      }
    };
  
    /**
     * Formats text for emphasized display in a placeholder inside a sentence.
     *
     * @param {string} str
     *   The text to format (plain-text).
     *
     * @return {string}
     *   The formatted text (html).
     */
    Drupal.theme.placeholder = function (str) {
      return '<em class="placeholder">' + Drupal.checkPlain(str) + '</em>';
    };
  
  })(Drupal, window.drupalSettings, window.drupalTranslations);
  ;
  // Allow other JavaScript libraries to use $.
  if (window.jQuery) {
    jQuery.noConflict();
  }
  
  // Class indicating that JS is enabled; used for styling purpose.
  document.documentElement.className += ' js';
  
  // JavaScript should be made compatible with libraries other than jQuery by
  // wrapping it in an anonymous closure.
  
  (function (domready, Drupal, drupalSettings) {
  
    'use strict';
  
    // Attach all behaviors.
    domready(function () { Drupal.attachBehaviors(document, drupalSettings); });
  
  })(domready, Drupal, window.drupalSettings);
  ;
  /*!
   * jQuery UI Core 1.11.4
   * http://jqueryui.com
   *
   * Copyright jQuery Foundation and other contributors
   * Released under the MIT license.
   * http://jquery.org/license
   *
   * http://api.jqueryui.com/category/ui-core/
   */(function(e){typeof define=="function"&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,r){var i,s,o,u=t.nodeName.toLowerCase();return"area"===u?(i=t.parentNode,s=i.name,!t.href||!s||i.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap='#"+s+"']")[0],!!o&&n(o))):(/^(input|select|textarea|button|object)$/.test(u)?!t.disabled:"a"===u?t.href||r:r)&&n(t)}function n(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return e.css(this,"visibility")==="hidden"}).length}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var n=this.css("position"),r=n==="absolute",i=t?/(auto|scroll|hidden)/:/(auto|scroll)/,s=this.parents().filter(function(){var t=e(this);return r&&t.css("position")==="static"?!1:i.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return n==="fixed"||!s.length?e(this[0].ownerDocument||document):s},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(n){return t(n,!isNaN(e.attr(n,"tabindex")))},tabbable:function(n){var r=e.attr(n,"tabindex"),i=isNaN(r);return(i||r>=0)&&t(n,!i)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(t,n){function o(t,n,i,s){return e.each(r,function(){n-=parseFloat(e.css(t,"padding"+this))||0,i&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var r=n==="Width"?["Left","Right"]:["Top","Bottom"],i=n.toLowerCase(),s={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+n]=function(t){return t===undefined?s["inner"+n].call(this):this.each(function(){e(this).css(i,o(this,t)+"px")})},e.fn["outer"+n]=function(t,r){return typeof t!="number"?s["outer"+n].call(this,t):this.each(function(){e(this).css(i,o(this,t,!0,r)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(n,r){return typeof n=="number"?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),r&&r.call(t)},n)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(t!==undefined)return this.css("zIndex",t);if(this.length){var n=e(this[0]),r,i;while(n.length&&n[0]!==document){r=n.css("position");if(r==="absolute"||r==="relative"||r==="fixed"){i=parseInt(n.css("zIndex"),10);if(!isNaN(i)&&i!==0)return i}n=n.parent()}}return 0}}),e.ui.plugin={add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n,r){var i,s=e.plugins[t];if(!s)return;if(!r&&(!e.element[0].parentNode||e.element[0].parentNode.nodeType===11))return;for(i=0;i<s.length;i++)e.options[s[i][0]]&&s[i][1].apply(e.element,n)}}});;
  /**
   * @file
   * Attaches behaviors for the Contextual module.
   */
  
  (function ($, Drupal, drupalSettings, _, Backbone, JSON, storage) {
  
    'use strict';
  
    var options = $.extend(drupalSettings.contextual,
      // Merge strings on top of drupalSettings so that they are not mutable.
      {
        strings: {
          open: Drupal.t('Open'),
          close: Drupal.t('Close')
        }
      }
    );
  
    // Clear the cached contextual links whenever the current user's set of
    // permissions changes.
    var cachedPermissionsHash = storage.getItem('Drupal.contextual.permissionsHash');
    var permissionsHash = drupalSettings.user.permissionsHash;
    if (cachedPermissionsHash !== permissionsHash) {
      if (typeof permissionsHash === 'string') {
        _.chain(storage).keys().each(function (key) {
          if (key.substring(0, 18) === 'Drupal.contextual.') {
            storage.removeItem(key);
          }
        });
      }
      storage.setItem('Drupal.contextual.permissionsHash', permissionsHash);
    }
  
    /**
     * Initializes a contextual link: updates its DOM, sets up model and views.
     *
     * @param {jQuery} $contextual
     *   A contextual links placeholder DOM element, containing the actual
     *   contextual links as rendered by the server.
     * @param {string} html
     *   The server-side rendered HTML for this contextual link.
     */
    function initContextual($contextual, html) {
      var $region = $contextual.closest('.contextual-region');
      var contextual = Drupal.contextual;
  
      $contextual
        // Update the placeholder to contain its rendered contextual links.
        .html(html)
        // Use the placeholder as a wrapper with a specific class to provide
        // positioning and behavior attachment context.
        .addClass('contextual')
        // Ensure a trigger element exists before the actual contextual links.
        .prepend(Drupal.theme('contextualTrigger'));
  
      // Set the destination parameter on each of the contextual links.
      var destination = 'destination=' + Drupal.encodePath(drupalSettings.path.currentPath);
      $contextual.find('.contextual-links a').each(function () {
        var url = this.getAttribute('href');
        var glue = (url.indexOf('?') === -1) ? '?' : '&';
        this.setAttribute('href', url + glue + destination);
      });
  
      // Create a model and the appropriate views.
      var model = new contextual.StateModel({
        title: $region.find('h2').eq(0).text().trim()
      });
      var viewOptions = $.extend({el: $contextual, model: model}, options);
      contextual.views.push({
        visual: new contextual.VisualView(viewOptions),
        aural: new contextual.AuralView(viewOptions),
        keyboard: new contextual.KeyboardView(viewOptions)
      });
      contextual.regionViews.push(new contextual.RegionView(
        $.extend({el: $region, model: model}, options))
      );
  
      // Add the model to the collection. This must happen after the views have
      // been associated with it, otherwise collection change event handlers can't
      // trigger the model change event handler in its views.
      contextual.collection.add(model);
  
      // Let other JavaScript react to the adding of a new contextual link.
      $(document).trigger('drupalContextualLinkAdded', {
        $el: $contextual,
        $region: $region,
        model: model
      });
  
      // Fix visual collisions between contextual link triggers.
      adjustIfNestedAndOverlapping($contextual);
    }
  
    /**
     * Determines if a contextual link is nested & overlapping, if so: adjusts it.
     *
     * This only deals with two levels of nesting; deeper levels are not touched.
     *
     * @param {jQuery} $contextual
     *   A contextual links placeholder DOM element, containing the actual
     *   contextual links as rendered by the server.
     */
    function adjustIfNestedAndOverlapping($contextual) {
      var $contextuals = $contextual
        // @todo confirm that .closest() is not sufficient
        .parents('.contextual-region').eq(-1)
        .find('.contextual');
  
      // Early-return when there's no nesting.
      if ($contextuals.length === 1) {
        return;
      }
  
      // If the two contextual links overlap, then we move the second one.
      var firstTop = $contextuals.eq(0).offset().top;
      var secondTop = $contextuals.eq(1).offset().top;
      if (firstTop === secondTop) {
        var $nestedContextual = $contextuals.eq(1);
  
        // Retrieve height of nested contextual link.
        var height = 0;
        var $trigger = $nestedContextual.find('.trigger');
        // Elements with the .visually-hidden class have no dimensions, so this
        // class must be temporarily removed to the calculate the height.
        $trigger.removeClass('visually-hidden');
        height = $nestedContextual.height();
        $trigger.addClass('visually-hidden');
  
        // Adjust nested contextual link's position.
        $nestedContextual.css({top: $nestedContextual.position().top + height});
      }
    }
  
    /**
     * Attaches outline behavior for regions associated with contextual links.
     *
     * Events
     *   Contextual triggers an event that can be used by other scripts.
     *   - drupalContextualLinkAdded: Triggered when a contextual link is added.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *  Attaches the outline behavior to the right context.
     */
    Drupal.behaviors.contextual = {
      attach: function (context) {
        var $context = $(context);
  
        // Find all contextual links placeholders, if any.
        var $placeholders = $context.find('[data-contextual-id]').once('contextual-render');
        if ($placeholders.length === 0) {
          return;
        }
  
        // Collect the IDs for all contextual links placeholders.
        var ids = [];
        $placeholders.each(function () {
          ids.push($(this).attr('data-contextual-id'));
        });
  
        // Update all contextual links placeholders whose HTML is cached.
        var uncachedIDs = _.filter(ids, function initIfCached(contextualID) {
          var html = storage.getItem('Drupal.contextual.' + contextualID);
          if (html && html.length) {
            // Initialize after the current execution cycle, to make the AJAX
            // request for retrieving the uncached contextual links as soon as
            // possible, but also to ensure that other Drupal behaviors have had
            // the chance to set up an event listener on the Backbone collection
            // Drupal.contextual.collection.
            window.setTimeout(function () {
              initContextual($context.find('[data-contextual-id="' + contextualID + '"]'), html);
            });
            return false;
          }
          return true;
        });
  
        // Perform an AJAX request to let the server render the contextual links
        // for each of the placeholders.
        if (uncachedIDs.length > 0) {
          $.ajax({
            url: Drupal.url('contextual/render'),
            type: 'POST',
            data: {'ids[]': uncachedIDs},
            dataType: 'json',
            success: function (results) {
              _.each(results, function (html, contextualID) {
                // Store the metadata.
                storage.setItem('Drupal.contextual.' + contextualID, html);
                // If the rendered contextual links are empty, then the current
                // user does not have permission to access the associated links:
                // don't render anything.
                if (html.length > 0) {
                  // Update the placeholders to contain its rendered contextual
                  // links. Usually there will only be one placeholder, but it's
                  // possible for multiple identical placeholders exist on the
                  // page (probably because the same content appears more than
                  // once).
                  $placeholders = $context.find('[data-contextual-id="' + contextualID + '"]');
  
                  // Initialize the contextual links.
                  for (var i = 0; i < $placeholders.length; i++) {
                    initContextual($placeholders.eq(i), html);
                  }
                }
              });
            }
          });
        }
      }
    };
  
    /**
     * Namespace for contextual related functionality.
     *
     * @namespace
     */
    Drupal.contextual = {
  
      /**
       * The {@link Drupal.contextual.View} instances associated with each list
       * element of contextual links.
       *
       * @type {Array}
       */
      views: [],
  
      /**
       * The {@link Drupal.contextual.RegionView} instances associated with each
       * contextual region element.
       *
       * @type {Array}
       */
      regionViews: []
    };
  
    /**
     * A Backbone.Collection of {@link Drupal.contextual.StateModel} instances.
     *
     * @type {Backbone.Collection}
     */
    Drupal.contextual.collection = new Backbone.Collection([], {model: Drupal.contextual.StateModel});
  
    /**
     * A trigger is an interactive element often bound to a click handler.
     *
     * @return {string}
     *   A string representing a DOM fragment.
     */
    Drupal.theme.contextualTrigger = function () {
      return '<button class="trigger visually-hidden focusable" type="button"></button>';
    };
  
  })(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage);
  ;
  /**
   * @file
   * A Backbone Model for the state of a contextual link's trigger, list & region.
   */
  
  (function (Drupal, Backbone) {
  
    'use strict';
  
    /**
     * Models the state of a contextual link's trigger, list & region.
     *
     * @constructor
     *
     * @augments Backbone.Model
     */
    Drupal.contextual.StateModel = Backbone.Model.extend(/** @lends Drupal.contextual.StateModel# */{
  
      /**
       * @type {object}
       *
       * @prop {string} title
       * @prop {bool} regionIsHovered
       * @prop {bool} hasFocus
       * @prop {bool} isOpen
       * @prop {bool} isLocked
       */
      defaults: /** @lends Drupal.contextual.StateModel# */{
  
        /**
         * The title of the entity to which these contextual links apply.
         *
         * @type {string}
         */
        title: '',
  
        /**
         * Represents if the contextual region is being hovered.
         *
         * @type {bool}
         */
        regionIsHovered: false,
  
        /**
         * Represents if the contextual trigger or options have focus.
         *
         * @type {bool}
         */
        hasFocus: false,
  
        /**
         * Represents if the contextual options for an entity are available to
         * be selected (i.e. whether the list of options is visible).
         *
         * @type {bool}
         */
        isOpen: false,
  
        /**
         * When the model is locked, the trigger remains active.
         *
         * @type {bool}
         */
        isLocked: false
      },
  
      /**
       * Opens or closes the contextual link.
       *
       * If it is opened, then also give focus.
       *
       * @return {Drupal.contextual.StateModel}
       *   The current contextual state model.
       */
      toggleOpen: function () {
        var newIsOpen = !this.get('isOpen');
        this.set('isOpen', newIsOpen);
        if (newIsOpen) {
          this.focus();
        }
        return this;
      },
  
      /**
       * Closes this contextual link.
       *
       * Does not call blur() because we want to allow a contextual link to have
       * focus, yet be closed for example when hovering.
       *
       * @return {Drupal.contextual.StateModel}
       *   The current contextual state model.
       */
      close: function () {
        this.set('isOpen', false);
        return this;
      },
  
      /**
       * Gives focus to this contextual link.
       *
       * Also closes + removes focus from every other contextual link.
       *
       * @return {Drupal.contextual.StateModel}
       *   The current contextual state model.
       */
      focus: function () {
        this.set('hasFocus', true);
        var cid = this.cid;
        this.collection.each(function (model) {
          if (model.cid !== cid) {
            model.close().blur();
          }
        });
        return this;
      },
  
      /**
       * Removes focus from this contextual link, unless it is open.
       *
       * @return {Drupal.contextual.StateModel}
       *   The current contextual state model.
       */
      blur: function () {
        if (!this.get('isOpen')) {
          this.set('hasFocus', false);
        }
        return this;
      }
  
    });
  
  })(Drupal, Backbone);
  ;
  /**
   * @file
   * A Backbone View that provides the aural view of a contextual link.
   */
  
  (function (Drupal, Backbone) {
  
    'use strict';
  
    Drupal.contextual.AuralView = Backbone.View.extend(/** @lends Drupal.contextual.AuralView# */{
  
      /**
       * Renders the aural view of a contextual link (i.e. screen reader support).
       *
       * @constructs
       *
       * @augments Backbone.View
       *
       * @param {object} options
       *   Options for the view.
       */
      initialize: function (options) {
        this.options = options;
  
        this.listenTo(this.model, 'change', this.render);
  
        // Use aria-role form so that the number of items in the list is spoken.
        this.$el.attr('role', 'form');
  
        // Initial render.
        this.render();
      },
  
      /**
       * @inheritdoc
       */
      render: function () {
        var isOpen = this.model.get('isOpen');
  
        // Set the hidden property of the links.
        this.$el.find('.contextual-links')
          .prop('hidden', !isOpen);
  
        // Update the view of the trigger.
        this.$el.find('.trigger')
          .text(Drupal.t('@action @title configuration options', {
            '@action': (!isOpen) ? this.options.strings.open : this.options.strings.close,
            '@title': this.model.get('title')
          }))
          .attr('aria-pressed', isOpen);
      }
  
    });
  
  })(Drupal, Backbone);
  ;
  /**
   * @file
   * A Backbone View that provides keyboard interaction for a contextual link.
   */
  
  (function (Drupal, Backbone) {
  
    'use strict';
  
    Drupal.contextual.KeyboardView = Backbone.View.extend(/** @lends Drupal.contextual.KeyboardView# */{
  
      /**
       * @type {object}
       */
      events: {
        'focus .trigger': 'focus',
        'focus .contextual-links a': 'focus',
        'blur .trigger': function () { this.model.blur(); },
        'blur .contextual-links a': function () {
          // Set up a timeout to allow a user to tab between the trigger and the
          // contextual links without the menu dismissing.
          var that = this;
          this.timer = window.setTimeout(function () {
            that.model.close().blur();
          }, 150);
        }
      },
  
      /**
       * Provides keyboard interaction for a contextual link.
       *
       * @constructs
       *
       * @augments Backbone.View
       */
      initialize: function () {
  
        /**
         * The timer is used to create a delay before dismissing the contextual
         * links on blur. This is only necessary when keyboard users tab into
         * contextual links without edit mode (i.e. without TabbingManager).
         * That means that if we decide to disable tabbing of contextual links
         * without edit mode, all this timer logic can go away.
         *
         * @type {NaN|number}
         */
        this.timer = NaN;
      },
  
      /**
       * Sets focus on the model; Clears the timer that dismisses the links.
       */
      focus: function () {
        // Clear the timeout that might have been set by blurring a link.
        window.clearTimeout(this.timer);
        this.model.focus();
      }
  
    });
  
  })(Drupal, Backbone);
  ;
  /**
   * @file
   * A Backbone View that renders the visual view of a contextual region element.
   */
  
  (function (Drupal, Backbone, Modernizr) {
  
    'use strict';
  
    Drupal.contextual.RegionView = Backbone.View.extend(/** @lends Drupal.contextual.RegionView# */{
  
      /**
       * Events for the Backbone view.
       *
       * @return {object}
       *   A mapping of events to be used in the view.
       */
      events: function () {
        var mapping = {
          mouseenter: function () { this.model.set('regionIsHovered', true); },
          mouseleave: function () {
            this.model.close().blur().set('regionIsHovered', false);
          }
        };
        // We don't want mouse hover events on touch.
        if (Modernizr.touchevents) {
          mapping = {};
        }
        return mapping;
      },
  
      /**
       * Renders the visual view of a contextual region element.
       *
       * @constructs
       *
       * @augments Backbone.View
       */
      initialize: function () {
        this.listenTo(this.model, 'change:hasFocus', this.render);
      },
  
      /**
       * @inheritdoc
       *
       * @return {Drupal.contextual.RegionView}
       *   The current contextual region view.
       */
      render: function () {
        this.$el.toggleClass('focus', this.model.get('hasFocus'));
  
        return this;
      }
  
    });
  
  })(Drupal, Backbone, Modernizr);
  ;
  /**
   * @file
   * A Backbone View that provides the visual view of a contextual link.
   */
  
  (function (Drupal, Backbone, Modernizr) {
  
    'use strict';
  
    Drupal.contextual.VisualView = Backbone.View.extend(/** @lends Drupal.contextual.VisualView# */{
  
      /**
       * Events for the Backbone view.
       *
       * @return {object}
       *   A mapping of events to be used in the view.
       */
      events: function () {
        // Prevents delay and simulated mouse events.
        var touchEndToClick = function (event) {
          event.preventDefault();
          event.target.click();
        };
        var mapping = {
          'click .trigger': function () { this.model.toggleOpen(); },
          'touchend .trigger': touchEndToClick,
          'click .contextual-links a': function () { this.model.close().blur(); },
          'touchend .contextual-links a': touchEndToClick
        };
        // We only want mouse hover events on non-touch.
        if (!Modernizr.touchevents) {
          mapping.mouseenter = function () { this.model.focus(); };
        }
        return mapping;
      },
  
      /**
       * Renders the visual view of a contextual link. Listens to mouse & touch.
       *
       * @constructs
       *
       * @augments Backbone.View
       */
      initialize: function () {
        this.listenTo(this.model, 'change', this.render);
      },
  
      /**
       * @inheritdoc
       *
       * @return {Drupal.contextual.VisualView}
       *   The current contextual visual view.
       */
      render: function () {
        var isOpen = this.model.get('isOpen');
        // The trigger should be visible when:
        //  - the mouse hovered over the region,
        //  - the trigger is locked,
        //  - and for as long as the contextual menu is open.
        var isVisible = this.model.get('isLocked') || this.model.get('regionIsHovered') || isOpen;
  
        this.$el
          // The open state determines if the links are visible.
          .toggleClass('open', isOpen)
          // Update the visibility of the trigger.
          .find('.trigger').toggleClass('visually-hidden', !isVisible);
  
        // Nested contextual region handling: hide any nested contextual triggers.
        if ('isOpen' in this.model.changed) {
          this.$el.closest('.contextual-region')
            .find('.contextual .trigger:not(:first)')
            .toggle(!isOpen);
        }
  
        return this;
      }
  
    });
  
  })(Drupal, Backbone, Modernizr);
  ;
  /**
   * @file
   * Provide dragging capabilities to admin uis.
   */
  
  /**
   * Triggers when weights columns are toggled.
   *
   * @event columnschange
   */
  
  (function ($, Drupal, drupalSettings) {
  
    'use strict';
  
    /**
     * Store the state of weight columns display for all tables.
     *
     * Default value is to hide weight columns.
     */
    var showWeight = JSON.parse(localStorage.getItem('Drupal.tableDrag.showWeight'));
  
    /**
     * Drag and drop table rows with field manipulation.
     *
     * Using the drupal_attach_tabledrag() function, any table with weights or
     * parent relationships may be made into draggable tables. Columns containing
     * a field may optionally be hidden, providing a better user experience.
     *
     * Created tableDrag instances may be modified with custom behaviors by
     * overriding the .onDrag, .onDrop, .row.onSwap, and .row.onIndent methods.
     * See blocks.js for an example of adding additional functionality to
     * tableDrag.
     *
     * @type {Drupal~behavior}
     */
    Drupal.behaviors.tableDrag = {
      attach: function (context, settings) {
        function initTableDrag(table, base) {
          if (table.length) {
            // Create the new tableDrag instance. Save in the Drupal variable
            // to allow other scripts access to the object.
            Drupal.tableDrag[base] = new Drupal.tableDrag(table[0], settings.tableDrag[base]);
          }
        }
  
        for (var base in settings.tableDrag) {
          if (settings.tableDrag.hasOwnProperty(base)) {
            initTableDrag($(context).find('#' + base).once('tabledrag'), base);
          }
        }
      }
    };
  
    /**
     * Provides table and field manipulation.
     *
     * @constructor
     *
     * @param {HTMLElement} table
     *   DOM object for the table to be made draggable.
     * @param {object} tableSettings
     *   Settings for the table added via drupal_add_dragtable().
     */
    Drupal.tableDrag = function (table, tableSettings) {
      var self = this;
      var $table = $(table);
  
      /**
       * @type {jQuery}
       */
      this.$table = $(table);
  
      /**
       *
       * @type {HTMLElement}
       */
      this.table = table;
  
      /**
       * @type {object}
       */
      this.tableSettings = tableSettings;
  
      /**
       * Used to hold information about a current drag operation.
       *
       * @type {?HTMLElement}
       */
      this.dragObject = null;
  
      /**
       * Provides operations for row manipulation.
       *
       * @type {?HTMLElement}
       */
      this.rowObject = null;
  
      /**
       * Remember the previous element.
       *
       * @type {?HTMLElement}
       */
      this.oldRowElement = null;
  
      /**
       * Used to determine up or down direction from last mouse move.
       *
       * @type {number}
       */
      this.oldY = 0;
  
      /**
       * Whether anything in the entire table has changed.
       *
       * @type {bool}
       */
      this.changed = false;
  
      /**
       * Maximum amount of allowed parenting.
       *
       * @type {number}
       */
      this.maxDepth = 0;
  
      /**
       * Direction of the table.
       *
       * @type {number}
       */
      this.rtl = $(this.table).css('direction') === 'rtl' ? -1 : 1;
  
      /**
       *
       * @type {bool}
       */
      this.striping = $(this.table).data('striping') === 1;
  
      /**
       * Configure the scroll settings.
       *
       * @type {object}
       *
       * @prop {number} amount
       * @prop {number} interval
       * @prop {number} trigger
       */
      this.scrollSettings = {amount: 4, interval: 50, trigger: 70};
  
      /**
       *
       * @type {?number}
       */
      this.scrollInterval = null;
  
      /**
       *
       * @type {number}
       */
      this.scrollY = 0;
  
      /**
       *
       * @type {number}
       */
      this.windowHeight = 0;
  
      /**
       * Check this table's settings for parent relationships.
       *
       * For efficiency, large sections of code can be skipped if we don't need to
       * track horizontal movement and indentations.
       *
       * @type {bool}
       */
      this.indentEnabled = false;
      for (var group in tableSettings) {
        if (tableSettings.hasOwnProperty(group)) {
          for (var n in tableSettings[group]) {
            if (tableSettings[group].hasOwnProperty(n)) {
              if (tableSettings[group][n].relationship === 'parent') {
                this.indentEnabled = true;
              }
              if (tableSettings[group][n].limit > 0) {
                this.maxDepth = tableSettings[group][n].limit;
              }
            }
          }
        }
      }
      if (this.indentEnabled) {
  
        /**
         * Total width of indents, set in makeDraggable.
         *
         * @type {number}
         */
        this.indentCount = 1;
        // Find the width of indentations to measure mouse movements against.
        // Because the table doesn't need to start with any indentations, we
        // manually append 2 indentations in the first draggable row, measure
        // the offset, then remove.
        var indent = Drupal.theme('tableDragIndentation');
        var testRow = $('<tr/>').addClass('draggable').appendTo(table);
        var testCell = $('<td/>').appendTo(testRow).prepend(indent).prepend(indent);
        var $indentation = testCell.find('.js-indentation');
  
        /**
         *
         * @type {number}
         */
        this.indentAmount = $indentation.get(1).offsetLeft - $indentation.get(0).offsetLeft;
        testRow.remove();
      }
  
      // Make each applicable row draggable.
      // Match immediate children of the parent element to allow nesting.
      $table.find('> tr.draggable, > tbody > tr.draggable').each(function () { self.makeDraggable(this); });
  
      // Add a link before the table for users to show or hide weight columns.
      $table.before($('<button type="button" class="link tabledrag-toggle-weight"></button>')
        .attr('title', Drupal.t('Re-order rows by numerical weight instead of dragging.'))
        .on('click', $.proxy(function (e) {
          e.preventDefault();
          this.toggleColumns();
        }, this))
        .wrap('<div class="tabledrag-toggle-weight-wrapper"></div>')
        .parent()
      );
  
      // Initialize the specified columns (for example, weight or parent columns)
      // to show or hide according to user preference. This aids accessibility
      // so that, e.g., screen reader users can choose to enter weight values and
      // manipulate form elements directly, rather than using drag-and-drop..
      self.initColumns();
  
      // Add event bindings to the document. The self variable is passed along
      // as event handlers do not have direct access to the tableDrag object.
      $(document).on('touchmove', function (event) { return self.dragRow(event.originalEvent.touches[0], self); });
      $(document).on('touchend', function (event) { return self.dropRow(event.originalEvent.touches[0], self); });
      $(document).on('mousemove pointermove', function (event) { return self.dragRow(event, self); });
      $(document).on('mouseup pointerup', function (event) { return self.dropRow(event, self); });
  
      // React to localStorage event showing or hiding weight columns.
      $(window).on('storage', $.proxy(function (e) {
        // Only react to 'Drupal.tableDrag.showWeight' value change.
        if (e.originalEvent.key === 'Drupal.tableDrag.showWeight') {
          // This was changed in another window, get the new value for this
          // window.
          showWeight = JSON.parse(e.originalEvent.newValue);
          this.displayColumns(showWeight);
        }
      }, this));
    };
  
    /**
     * Initialize columns containing form elements to be hidden by default.
     *
     * Identify and mark each cell with a CSS class so we can easily toggle
     * show/hide it. Finally, hide columns if user does not have a
     * 'Drupal.tableDrag.showWeight' localStorage value.
     */
    Drupal.tableDrag.prototype.initColumns = function () {
      var $table = this.$table;
      var hidden;
      var cell;
      var columnIndex;
      for (var group in this.tableSettings) {
        if (this.tableSettings.hasOwnProperty(group)) {
  
          // Find the first field in this group.
          for (var d in this.tableSettings[group]) {
            if (this.tableSettings[group].hasOwnProperty(d)) {
              var field = $table.find('.' + this.tableSettings[group][d].target).eq(0);
              if (field.length && this.tableSettings[group][d].hidden) {
                hidden = this.tableSettings[group][d].hidden;
                cell = field.closest('td');
                break;
              }
            }
          }
  
          // Mark the column containing this field so it can be hidden.
          if (hidden && cell[0]) {
            // Add 1 to our indexes. The nth-child selector is 1 based, not 0
            // based. Match immediate children of the parent element to allow
            // nesting.
            columnIndex = cell.parent().find('> td').index(cell.get(0)) + 1;
            $table.find('> thead > tr, > tbody > tr, > tr').each(this.addColspanClass(columnIndex));
          }
        }
      }
      this.displayColumns(showWeight);
    };
  
    /**
     * Mark cells that have colspan.
     *
     * In order to adjust the colspan instead of hiding them altogether.
     *
     * @param {number} columnIndex
     *   The column index to add colspan class to.
     *
     * @return {function}
     *   Function to add colspan class.
     */
    Drupal.tableDrag.prototype.addColspanClass = function (columnIndex) {
      return function () {
        // Get the columnIndex and adjust for any colspans in this row.
        var $row = $(this);
        var index = columnIndex;
        var cells = $row.children();
        var cell;
        cells.each(function (n) {
          if (n < index && this.colSpan && this.colSpan > 1) {
            index -= this.colSpan - 1;
          }
        });
        if (index > 0) {
          cell = cells.filter(':nth-child(' + index + ')');
          if (cell[0].colSpan && cell[0].colSpan > 1) {
            // If this cell has a colspan, mark it so we can reduce the colspan.
            cell.addClass('tabledrag-has-colspan');
          }
          else {
            // Mark this cell so we can hide it.
            cell.addClass('tabledrag-hide');
          }
        }
      };
    };
  
    /**
     * Hide or display weight columns. Triggers an event on change.
     *
     * @fires event:columnschange
     *
     * @param {bool} displayWeight
     *   'true' will show weight columns.
     */
    Drupal.tableDrag.prototype.displayColumns = function (displayWeight) {
      if (displayWeight) {
        this.showColumns();
      }
      // Default action is to hide columns.
      else {
        this.hideColumns();
      }
      // Trigger an event to allow other scripts to react to this display change.
      // Force the extra parameter as a bool.
      $('table').findOnce('tabledrag').trigger('columnschange', !!displayWeight);
    };
  
    /**
     * Toggle the weight column depending on 'showWeight' value.
     *
     * Store only default override.
     */
    Drupal.tableDrag.prototype.toggleColumns = function () {
      showWeight = !showWeight;
      this.displayColumns(showWeight);
      if (showWeight) {
        // Save default override.
        localStorage.setItem('Drupal.tableDrag.showWeight', showWeight);
      }
      else {
        // Reset the value to its default.
        localStorage.removeItem('Drupal.tableDrag.showWeight');
      }
    };
  
    /**
     * Hide the columns containing weight/parent form elements.
     *
     * Undo showColumns().
     */
    Drupal.tableDrag.prototype.hideColumns = function () {
      var $tables = $('table').findOnce('tabledrag');
      // Hide weight/parent cells and headers.
      $tables.find('.tabledrag-hide').css('display', 'none');
      // Show TableDrag handles.
      $tables.find('.tabledrag-handle').css('display', '');
      // Reduce the colspan of any effected multi-span columns.
      $tables.find('.tabledrag-has-colspan').each(function () {
        this.colSpan = this.colSpan - 1;
      });
      // Change link text.
      $('.tabledrag-toggle-weight').text(Drupal.t('Show row weights'));
    };
  
    /**
     * Show the columns containing weight/parent form elements.
     *
     * Undo hideColumns().
     */
    Drupal.tableDrag.prototype.showColumns = function () {
      var $tables = $('table').findOnce('tabledrag');
      // Show weight/parent cells and headers.
      $tables.find('.tabledrag-hide').css('display', '');
      // Hide TableDrag handles.
      $tables.find('.tabledrag-handle').css('display', 'none');
      // Increase the colspan for any columns where it was previously reduced.
      $tables.find('.tabledrag-has-colspan').each(function () {
        this.colSpan = this.colSpan + 1;
      });
      // Change link text.
      $('.tabledrag-toggle-weight').text(Drupal.t('Hide row weights'));
    };
  
    /**
     * Find the target used within a particular row and group.
     *
     * @param {string} group
     *   Group selector.
     * @param {HTMLElement} row
     *   The row HTML element.
     *
     * @return {object}
     *   The table row settings.
     */
    Drupal.tableDrag.prototype.rowSettings = function (group, row) {
      var field = $(row).find('.' + group);
      var tableSettingsGroup = this.tableSettings[group];
      for (var delta in tableSettingsGroup) {
        if (tableSettingsGroup.hasOwnProperty(delta)) {
          var targetClass = tableSettingsGroup[delta].target;
          if (field.is('.' + targetClass)) {
            // Return a copy of the row settings.
            var rowSettings = {};
            for (var n in tableSettingsGroup[delta]) {
              if (tableSettingsGroup[delta].hasOwnProperty(n)) {
                rowSettings[n] = tableSettingsGroup[delta][n];
              }
            }
            return rowSettings;
          }
        }
      }
    };
  
    /**
     * Take an item and add event handlers to make it become draggable.
     *
     * @param {HTMLElement} item
     *   The item to add event handlers to.
     */
    Drupal.tableDrag.prototype.makeDraggable = function (item) {
      var self = this;
      var $item = $(item);
      // Add a class to the title link.
      $item.find('td:first-of-type').find('a').addClass('menu-item__link');
      // Create the handle.
      var handle = $('<a href="#" class="tabledrag-handle"><div class="handle">&nbsp;</div></a>').attr('title', Drupal.t('Drag to re-order'));
      // Insert the handle after indentations (if any).
      var $indentationLast = $item.find('td:first-of-type').find('.js-indentation').eq(-1);
      if ($indentationLast.length) {
        $indentationLast.after(handle);
        // Update the total width of indentation in this entire table.
        self.indentCount = Math.max($item.find('.js-indentation').length, self.indentCount);
      }
      else {
        $item.find('td').eq(0).prepend(handle);
      }
  
      handle.on('mousedown touchstart pointerdown', function (event) {
        event.preventDefault();
        if (event.originalEvent.type === 'touchstart') {
          event = event.originalEvent.touches[0];
        }
        self.dragStart(event, self, item);
      });
  
      // Prevent the anchor tag from jumping us to the top of the page.
      handle.on('click', function (e) {
        e.preventDefault();
      });
  
      // Set blur cleanup when a handle is focused.
      handle.on('focus', function () {
        self.safeBlur = true;
      });
  
      // On blur, fire the same function as a touchend/mouseup. This is used to
      // update values after a row has been moved through the keyboard support.
      handle.on('blur', function (event) {
        if (self.rowObject && self.safeBlur) {
          self.dropRow(event, self);
        }
      });
  
      // Add arrow-key support to the handle.
      handle.on('keydown', function (event) {
        // If a rowObject doesn't yet exist and this isn't the tab key.
        if (event.keyCode !== 9 && !self.rowObject) {
          self.rowObject = new self.row(item, 'keyboard', self.indentEnabled, self.maxDepth, true);
        }
  
        var keyChange = false;
        var groupHeight;
  
        /* eslint-disable no-fallthrough */
  
        switch (event.keyCode) {
          // Left arrow.
          case 37:
          // Safari left arrow.
          case 63234:
            keyChange = true;
            self.rowObject.indent(-1 * self.rtl);
            break;
  
          // Up arrow.
          case 38:
          // Safari up arrow.
          case 63232:
            var $previousRow = $(self.rowObject.element).prev('tr:first-of-type');
            var previousRow = $previousRow.get(0);
            while (previousRow && $previousRow.is(':hidden')) {
              $previousRow = $(previousRow).prev('tr:first-of-type');
              previousRow = $previousRow.get(0);
            }
            if (previousRow) {
              // Do not allow the onBlur cleanup.
              self.safeBlur = false;
              self.rowObject.direction = 'up';
              keyChange = true;
  
              if ($(item).is('.tabledrag-root')) {
                // Swap with the previous top-level row.
                groupHeight = 0;
                while (previousRow && $previousRow.find('.js-indentation').length) {
                  $previousRow = $(previousRow).prev('tr:first-of-type');
                  previousRow = $previousRow.get(0);
                  groupHeight += $previousRow.is(':hidden') ? 0 : previousRow.offsetHeight;
                }
                if (previousRow) {
                  self.rowObject.swap('before', previousRow);
                  // No need to check for indentation, 0 is the only valid one.
                  window.scrollBy(0, -groupHeight);
                }
              }
              else if (self.table.tBodies[0].rows[0] !== previousRow || $previousRow.is('.draggable')) {
                // Swap with the previous row (unless previous row is the first
                // one and undraggable).
                self.rowObject.swap('before', previousRow);
                self.rowObject.interval = null;
                self.rowObject.indent(0);
                window.scrollBy(0, -parseInt(item.offsetHeight, 10));
              }
              // Regain focus after the DOM manipulation.
              handle.trigger('focus');
            }
            break;
  
          // Right arrow.
          case 39:
          // Safari right arrow.
          case 63235:
            keyChange = true;
            self.rowObject.indent(self.rtl);
            break;
  
          // Down arrow.
          case 40:
          // Safari down arrow.
          case 63233:
            var $nextRow = $(self.rowObject.group).eq(-1).next('tr:first-of-type');
            var nextRow = $nextRow.get(0);
            while (nextRow && $nextRow.is(':hidden')) {
              $nextRow = $(nextRow).next('tr:first-of-type');
              nextRow = $nextRow.get(0);
            }
            if (nextRow) {
              // Do not allow the onBlur cleanup.
              self.safeBlur = false;
              self.rowObject.direction = 'down';
              keyChange = true;
  
              if ($(item).is('.tabledrag-root')) {
                // Swap with the next group (necessarily a top-level one).
                groupHeight = 0;
                var nextGroup = new self.row(nextRow, 'keyboard', self.indentEnabled, self.maxDepth, false);
                if (nextGroup) {
                  $(nextGroup.group).each(function () {
                    groupHeight += $(this).is(':hidden') ? 0 : this.offsetHeight;
                  });
                  var nextGroupRow = $(nextGroup.group).eq(-1).get(0);
                  self.rowObject.swap('after', nextGroupRow);
                  // No need to check for indentation, 0 is the only valid one.
                  window.scrollBy(0, parseInt(groupHeight, 10));
                }
              }
              else {
                // Swap with the next row.
                self.rowObject.swap('after', nextRow);
                self.rowObject.interval = null;
                self.rowObject.indent(0);
                window.scrollBy(0, parseInt(item.offsetHeight, 10));
              }
              // Regain focus after the DOM manipulation.
              handle.trigger('focus');
            }
            break;
        }
  
        /* eslint-enable no-fallthrough */
  
        if (self.rowObject && self.rowObject.changed === true) {
          $(item).addClass('drag');
          if (self.oldRowElement) {
            $(self.oldRowElement).removeClass('drag-previous');
          }
          self.oldRowElement = item;
          if (self.striping === true) {
            self.restripeTable();
          }
          self.onDrag();
        }
  
        // Returning false if we have an arrow key to prevent scrolling.
        if (keyChange) {
          return false;
        }
      });
  
      // Compatibility addition, return false on keypress to prevent unwanted
      // scrolling. IE and Safari will suppress scrolling on keydown, but all
      // other browsers need to return false on keypress.
      // http://www.quirksmode.org/js/keys.html
      handle.on('keypress', function (event) {
  
        /* eslint-disable no-fallthrough */
  
        switch (event.keyCode) {
          // Left arrow.
          case 37:
          // Up arrow.
          case 38:
          // Right arrow.
          case 39:
          // Down arrow.
          case 40:
            return false;
        }
  
        /* eslint-enable no-fallthrough */
  
      });
    };
  
    /**
     * Pointer event initiator, creates drag object and information.
     *
     * @param {jQuery.Event} event
     *   The event object that trigger the drag.
     * @param {Drupal.tableDrag} self
     *   The drag handle.
     * @param {HTMLElement} item
     *   The item that that is being dragged.
     */
    Drupal.tableDrag.prototype.dragStart = function (event, self, item) {
      // Create a new dragObject recording the pointer information.
      self.dragObject = {};
      self.dragObject.initOffset = self.getPointerOffset(item, event);
      self.dragObject.initPointerCoords = self.pointerCoords(event);
      if (self.indentEnabled) {
        self.dragObject.indentPointerPos = self.dragObject.initPointerCoords;
      }
  
      // If there's a lingering row object from the keyboard, remove its focus.
      if (self.rowObject) {
        $(self.rowObject.element).find('a.tabledrag-handle').trigger('blur');
      }
  
      // Create a new rowObject for manipulation of this row.
      self.rowObject = new self.row(item, 'pointer', self.indentEnabled, self.maxDepth, true);
  
      // Save the position of the table.
      self.table.topY = $(self.table).offset().top;
      self.table.bottomY = self.table.topY + self.table.offsetHeight;
  
      // Add classes to the handle and row.
      $(item).addClass('drag');
  
      // Set the document to use the move cursor during drag.
      $('body').addClass('drag');
      if (self.oldRowElement) {
        $(self.oldRowElement).removeClass('drag-previous');
      }
    };
  
    /**
     * Pointer movement handler, bound to document.
     *
     * @param {jQuery.Event} event
     *   The pointer event.
     * @param {Drupal.tableDrag} self
     *   The tableDrag instance.
     *
     * @return {bool|undefined}
     *   Undefined if no dragObject is defined, false otherwise.
     */
    Drupal.tableDrag.prototype.dragRow = function (event, self) {
      if (self.dragObject) {
        self.currentPointerCoords = self.pointerCoords(event);
        var y = self.currentPointerCoords.y - self.dragObject.initOffset.y;
        var x = self.currentPointerCoords.x - self.dragObject.initOffset.x;
  
        // Check for row swapping and vertical scrolling.
        if (y !== self.oldY) {
          self.rowObject.direction = y > self.oldY ? 'down' : 'up';
          // Update the old value.
          self.oldY = y;
          // Check if the window should be scrolled (and how fast).
          var scrollAmount = self.checkScroll(self.currentPointerCoords.y);
          // Stop any current scrolling.
          clearInterval(self.scrollInterval);
          // Continue scrolling if the mouse has moved in the scroll direction.
          if (scrollAmount > 0 && self.rowObject.direction === 'down' || scrollAmount < 0 && self.rowObject.direction === 'up') {
            self.setScroll(scrollAmount);
          }
  
          // If we have a valid target, perform the swap and restripe the table.
          var currentRow = self.findDropTargetRow(x, y);
          if (currentRow) {
            if (self.rowObject.direction === 'down') {
              self.rowObject.swap('after', currentRow, self);
            }
            else {
              self.rowObject.swap('before', currentRow, self);
            }
            if (self.striping === true) {
              self.restripeTable();
            }
          }
        }
  
        // Similar to row swapping, handle indentations.
        if (self.indentEnabled) {
          var xDiff = self.currentPointerCoords.x - self.dragObject.indentPointerPos.x;
          // Set the number of indentations the pointer has been moved left or
          // right.
          var indentDiff = Math.round(xDiff / self.indentAmount);
          // Indent the row with our estimated diff, which may be further
          // restricted according to the rows around this row.
          var indentChange = self.rowObject.indent(indentDiff);
          // Update table and pointer indentations.
          self.dragObject.indentPointerPos.x += self.indentAmount * indentChange * self.rtl;
          self.indentCount = Math.max(self.indentCount, self.rowObject.indents);
        }
  
        return false;
      }
    };
  
    /**
     * Pointerup behavior.
     *
     * @param {jQuery.Event} event
     *   The pointer event.
     * @param {Drupal.tableDrag} self
     *   The tableDrag instance.
     */
    Drupal.tableDrag.prototype.dropRow = function (event, self) {
      var droppedRow;
      var $droppedRow;
  
      // Drop row functionality.
      if (self.rowObject !== null) {
        droppedRow = self.rowObject.element;
        $droppedRow = $(droppedRow);
        // The row is already in the right place so we just release it.
        if (self.rowObject.changed === true) {
          // Update the fields in the dropped row.
          self.updateFields(droppedRow);
  
          // If a setting exists for affecting the entire group, update all the
          // fields in the entire dragged group.
          for (var group in self.tableSettings) {
            if (self.tableSettings.hasOwnProperty(group)) {
              var rowSettings = self.rowSettings(group, droppedRow);
              if (rowSettings.relationship === 'group') {
                for (var n in self.rowObject.children) {
                  if (self.rowObject.children.hasOwnProperty(n)) {
                    self.updateField(self.rowObject.children[n], group);
                  }
                }
              }
            }
          }
  
          self.rowObject.markChanged();
          if (self.changed === false) {
            $(Drupal.theme('tableDragChangedWarning')).insertBefore(self.table).hide().fadeIn('slow');
            self.changed = true;
          }
        }
  
        if (self.indentEnabled) {
          self.rowObject.removeIndentClasses();
        }
        if (self.oldRowElement) {
          $(self.oldRowElement).removeClass('drag-previous');
        }
        $droppedRow.removeClass('drag').addClass('drag-previous');
        self.oldRowElement = droppedRow;
        self.onDrop();
        self.rowObject = null;
      }
  
      // Functionality specific only to pointerup events.
      if (self.dragObject !== null) {
        self.dragObject = null;
        $('body').removeClass('drag');
        clearInterval(self.scrollInterval);
      }
    };
  
    /**
     * Get the coordinates from the event (allowing for browser differences).
     *
     * @param {jQuery.Event} event
     *   The pointer event.
     *
     * @return {object}
     *   An object with `x` and `y` keys indicating the position.
     */
    Drupal.tableDrag.prototype.pointerCoords = function (event) {
      if (event.pageX || event.pageY) {
        return {x: event.pageX, y: event.pageY};
      }
      return {
        x: event.clientX + document.body.scrollLeft - document.body.clientLeft,
        y: event.clientY + document.body.scrollTop - document.body.clientTop
      };
    };
  
    /**
     * Get the event offset from the target element.
     *
     * Given a target element and a pointer event, get the event offset from that
     * element. To do this we need the element's position and the target position.
     *
     * @param {HTMLElement} target
     *   The target HTML element.
     * @param {jQuery.Event} event
     *   The pointer event.
     *
     * @return {object}
     *   An object with `x` and `y` keys indicating the position.
     */
    Drupal.tableDrag.prototype.getPointerOffset = function (target, event) {
      var docPos = $(target).offset();
      var pointerPos = this.pointerCoords(event);
      return {x: pointerPos.x - docPos.left, y: pointerPos.y - docPos.top};
    };
  
    /**
     * Find the row the mouse is currently over.
     *
     * This row is then taken and swapped with the one being dragged.
     *
     * @param {number} x
     *   The x coordinate of the mouse on the page (not the screen).
     * @param {number} y
     *   The y coordinate of the mouse on the page (not the screen).
     *
     * @return {*}
     *   The drop target row, if found.
     */
    Drupal.tableDrag.prototype.findDropTargetRow = function (x, y) {
      var rows = $(this.table.tBodies[0].rows).not(':hidden');
      for (var n = 0; n < rows.length; n++) {
        var row = rows[n];
        var $row = $(row);
        var rowY = $row.offset().top;
        var rowHeight;
        // Because Safari does not report offsetHeight on table rows, but does on
        // table cells, grab the firstChild of the row and use that instead.
        // http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari.
        if (row.offsetHeight === 0) {
          rowHeight = parseInt(row.firstChild.offsetHeight, 10) / 2;
        }
        // Other browsers.
        else {
          rowHeight = parseInt(row.offsetHeight, 10) / 2;
        }
  
        // Because we always insert before, we need to offset the height a bit.
        if ((y > (rowY - rowHeight)) && (y < (rowY + rowHeight))) {
          if (this.indentEnabled) {
            // Check that this row is not a child of the row being dragged.
            for (n in this.rowObject.group) {
              if (this.rowObject.group[n] === row) {
                return null;
              }
            }
          }
          else {
            // Do not allow a row to be swapped with itself.
            if (row === this.rowObject.element) {
              return null;
            }
          }
  
          // Check that swapping with this row is allowed.
          if (!this.rowObject.isValidSwap(row)) {
            return null;
          }
  
          // We may have found the row the mouse just passed over, but it doesn't
          // take into account hidden rows. Skip backwards until we find a
          // draggable row.
          while ($row.is(':hidden') && $row.prev('tr').is(':hidden')) {
            $row = $row.prev('tr:first-of-type');
            row = $row.get(0);
          }
          return row;
        }
      }
      return null;
    };
  
    /**
     * After the row is dropped, update the table fields.
     *
     * @param {HTMLElement} changedRow
     *   DOM object for the row that was just dropped.
     */
    Drupal.tableDrag.prototype.updateFields = function (changedRow) {
      for (var group in this.tableSettings) {
        if (this.tableSettings.hasOwnProperty(group)) {
          // Each group may have a different setting for relationship, so we find
          // the source rows for each separately.
          this.updateField(changedRow, group);
        }
      }
    };
  
    /**
     * After the row is dropped, update a single table field.
     *
     * @param {HTMLElement} changedRow
     *   DOM object for the row that was just dropped.
     * @param {string} group
     *   The settings group on which field updates will occur.
     */
    Drupal.tableDrag.prototype.updateField = function (changedRow, group) {
      var rowSettings = this.rowSettings(group, changedRow);
      var $changedRow = $(changedRow);
      var sourceRow;
      var $previousRow;
      var previousRow;
      var useSibling;
      // Set the row as its own target.
      if (rowSettings.relationship === 'self' || rowSettings.relationship === 'group') {
        sourceRow = changedRow;
      }
      // Siblings are easy, check previous and next rows.
      else if (rowSettings.relationship === 'sibling') {
        $previousRow = $changedRow.prev('tr:first-of-type');
        previousRow = $previousRow.get(0);
        var $nextRow = $changedRow.next('tr:first-of-type');
        var nextRow = $nextRow.get(0);
        sourceRow = changedRow;
        if ($previousRow.is('.draggable') && $previousRow.find('.' + group).length) {
          if (this.indentEnabled) {
            if ($previousRow.find('.js-indentations').length === $changedRow.find('.js-indentations').length) {
              sourceRow = previousRow;
            }
          }
          else {
            sourceRow = previousRow;
          }
        }
        else if ($nextRow.is('.draggable') && $nextRow.find('.' + group).length) {
          if (this.indentEnabled) {
            if ($nextRow.find('.js-indentations').length === $changedRow.find('.js-indentations').length) {
              sourceRow = nextRow;
            }
          }
          else {
            sourceRow = nextRow;
          }
        }
      }
      // Parents, look up the tree until we find a field not in this group.
      // Go up as many parents as indentations in the changed row.
      else if (rowSettings.relationship === 'parent') {
        $previousRow = $changedRow.prev('tr');
        previousRow = $previousRow;
        while ($previousRow.length && $previousRow.find('.js-indentation').length >= this.rowObject.indents) {
          $previousRow = $previousRow.prev('tr');
          previousRow = $previousRow;
        }
        // If we found a row.
        if ($previousRow.length) {
          sourceRow = $previousRow.get(0);
        }
        // Otherwise we went all the way to the left of the table without finding
        // a parent, meaning this item has been placed at the root level.
        else {
          // Use the first row in the table as source, because it's guaranteed to
          // be at the root level. Find the first item, then compare this row
          // against it as a sibling.
          sourceRow = $(this.table).find('tr.draggable:first-of-type').get(0);
          if (sourceRow === this.rowObject.element) {
            sourceRow = $(this.rowObject.group[this.rowObject.group.length - 1]).next('tr.draggable').get(0);
          }
          useSibling = true;
        }
      }
  
      // Because we may have moved the row from one category to another,
      // take a look at our sibling and borrow its sources and targets.
      this.copyDragClasses(sourceRow, changedRow, group);
      rowSettings = this.rowSettings(group, changedRow);
  
      // In the case that we're looking for a parent, but the row is at the top
      // of the tree, copy our sibling's values.
      if (useSibling) {
        rowSettings.relationship = 'sibling';
        rowSettings.source = rowSettings.target;
      }
  
      var targetClass = '.' + rowSettings.target;
      var targetElement = $changedRow.find(targetClass).get(0);
  
      // Check if a target element exists in this row.
      if (targetElement) {
        var sourceClass = '.' + rowSettings.source;
        var sourceElement = $(sourceClass, sourceRow).get(0);
        switch (rowSettings.action) {
          case 'depth':
            // Get the depth of the target row.
            targetElement.value = $(sourceElement).closest('tr').find('.js-indentation').length;
            break;
  
          case 'match':
            // Update the value.
            targetElement.value = sourceElement.value;
            break;
  
          case 'order':
            var siblings = this.rowObject.findSiblings(rowSettings);
            if ($(targetElement).is('select')) {
              // Get a list of acceptable values.
              var values = [];
              $(targetElement).find('option').each(function () {
                values.push(this.value);
              });
              var maxVal = values[values.length - 1];
              // Populate the values in the siblings.
              $(siblings).find(targetClass).each(function () {
                // If there are more items than possible values, assign the
                // maximum value to the row.
                if (values.length > 0) {
                  this.value = values.shift();
                }
                else {
                  this.value = maxVal;
                }
              });
            }
            else {
              // Assume a numeric input field.
              var weight = parseInt($(siblings[0]).find(targetClass).val(), 10) || 0;
              $(siblings).find(targetClass).each(function () {
                this.value = weight;
                weight++;
              });
            }
            break;
        }
      }
    };
  
    /**
     * Copy all tableDrag related classes from one row to another.
     *
     * Copy all special tableDrag classes from one row's form elements to a
     * different one, removing any special classes that the destination row
     * may have had.
     *
     * @param {HTMLElement} sourceRow
     *   The element for the source row.
     * @param {HTMLElement} targetRow
     *   The element for the target row.
     * @param {string} group
     *   The group selector.
     */
    Drupal.tableDrag.prototype.copyDragClasses = function (sourceRow, targetRow, group) {
      var sourceElement = $(sourceRow).find('.' + group);
      var targetElement = $(targetRow).find('.' + group);
      if (sourceElement.length && targetElement.length) {
        targetElement[0].className = sourceElement[0].className;
      }
    };
  
    /**
     * Check the suggested scroll of the table.
     *
     * @param {number} cursorY
     *   The Y position of the cursor.
     *
     * @return {number}
     *   The suggested scroll.
     */
    Drupal.tableDrag.prototype.checkScroll = function (cursorY) {
      var de = document.documentElement;
      var b = document.body;
  
      var windowHeight = this.windowHeight = window.innerHeight || (de.clientHeight && de.clientWidth !== 0 ? de.clientHeight : b.offsetHeight);
      var scrollY;
      if (document.all) {
        scrollY = this.scrollY = !de.scrollTop ? b.scrollTop : de.scrollTop;
      }
      else {
        scrollY = this.scrollY = window.pageYOffset ? window.pageYOffset : window.scrollY;
      }
      var trigger = this.scrollSettings.trigger;
      var delta = 0;
  
      // Return a scroll speed relative to the edge of the screen.
      if (cursorY - scrollY > windowHeight - trigger) {
        delta = trigger / (windowHeight + scrollY - cursorY);
        delta = (delta > 0 && delta < trigger) ? delta : trigger;
        return delta * this.scrollSettings.amount;
      }
      else if (cursorY - scrollY < trigger) {
        delta = trigger / (cursorY - scrollY);
        delta = (delta > 0 && delta < trigger) ? delta : trigger;
        return -delta * this.scrollSettings.amount;
      }
    };
  
    /**
     * Set the scroll for the table.
     *
     * @param {number} scrollAmount
     *   The amount of scroll to apply to the window.
     */
    Drupal.tableDrag.prototype.setScroll = function (scrollAmount) {
      var self = this;
  
      this.scrollInterval = setInterval(function () {
        // Update the scroll values stored in the object.
        self.checkScroll(self.currentPointerCoords.y);
        var aboveTable = self.scrollY > self.table.topY;
        var belowTable = self.scrollY + self.windowHeight < self.table.bottomY;
        if (scrollAmount > 0 && belowTable || scrollAmount < 0 && aboveTable) {
          window.scrollBy(0, scrollAmount);
        }
      }, this.scrollSettings.interval);
    };
  
    /**
     * Command to restripe table properly.
     */
    Drupal.tableDrag.prototype.restripeTable = function () {
      // :even and :odd are reversed because jQuery counts from 0 and
      // we count from 1, so we're out of sync.
      // Match immediate children of the parent element to allow nesting.
      $(this.table).find('> tbody > tr.draggable:visible, > tr.draggable:visible')
        .removeClass('odd even')
        .filter(':odd').addClass('even').end()
        .filter(':even').addClass('odd');
    };
  
    /**
     * Stub function. Allows a custom handler when a row begins dragging.
     *
     * @return {null}
     *   Returns null when the stub function is used.
     */
    Drupal.tableDrag.prototype.onDrag = function () {
      return null;
    };
  
    /**
     * Stub function. Allows a custom handler when a row is dropped.
     *
     * @return {null}
     *   Returns null when the stub function is used.
     */
    Drupal.tableDrag.prototype.onDrop = function () {
      return null;
    };
  
    /**
     * Constructor to make a new object to manipulate a table row.
     *
     * @param {HTMLElement} tableRow
     *   The DOM element for the table row we will be manipulating.
     * @param {string} method
     *   The method in which this row is being moved. Either 'keyboard' or
     *   'mouse'.
     * @param {bool} indentEnabled
     *   Whether the containing table uses indentations. Used for optimizations.
     * @param {number} maxDepth
     *   The maximum amount of indentations this row may contain.
     * @param {bool} addClasses
     *   Whether we want to add classes to this row to indicate child
     *   relationships.
     */
    Drupal.tableDrag.prototype.row = function (tableRow, method, indentEnabled, maxDepth, addClasses) {
      var $tableRow = $(tableRow);
  
      this.element = tableRow;
      this.method = method;
      this.group = [tableRow];
      this.groupDepth = $tableRow.find('.js-indentation').length;
      this.changed = false;
      this.table = $tableRow.closest('table')[0];
      this.indentEnabled = indentEnabled;
      this.maxDepth = maxDepth;
      // Direction the row is being moved.
      this.direction = '';
      if (this.indentEnabled) {
        this.indents = $tableRow.find('.js-indentation').length;
        this.children = this.findChildren(addClasses);
        this.group = $.merge(this.group, this.children);
        // Find the depth of this entire group.
        for (var n = 0; n < this.group.length; n++) {
          this.groupDepth = Math.max($(this.group[n]).find('.js-indentation').length, this.groupDepth);
        }
      }
    };
  
    /**
     * Find all children of rowObject by indentation.
     *
     * @param {bool} addClasses
     *   Whether we want to add classes to this row to indicate child
     *   relationships.
     *
     * @return {Array}
     *   An array of children of the row.
     */
    Drupal.tableDrag.prototype.row.prototype.findChildren = function (addClasses) {
      var parentIndentation = this.indents;
      var currentRow = $(this.element, this.table).next('tr.draggable');
      var rows = [];
      var child = 0;
  
      function rowIndentation(indentNum, el) {
        var self = $(el);
        if (child === 1 && (indentNum === parentIndentation)) {
          self.addClass('tree-child-first');
        }
        if (indentNum === parentIndentation) {
          self.addClass('tree-child');
        }
        else if (indentNum > parentIndentation) {
          self.addClass('tree-child-horizontal');
        }
      }
  
      while (currentRow.length) {
        // A greater indentation indicates this is a child.
        if (currentRow.find('.js-indentation').length > parentIndentation) {
          child++;
          rows.push(currentRow[0]);
          if (addClasses) {
            currentRow.find('.js-indentation').each(rowIndentation);
          }
        }
        else {
          break;
        }
        currentRow = currentRow.next('tr.draggable');
      }
      if (addClasses && rows.length) {
        $(rows[rows.length - 1]).find('.js-indentation:nth-child(' + (parentIndentation + 1) + ')').addClass('tree-child-last');
      }
      return rows;
    };
  
    /**
     * Ensure that two rows are allowed to be swapped.
     *
     * @param {HTMLElement} row
     *   DOM object for the row being considered for swapping.
     *
     * @return {bool}
     *   Whether the swap is a valid swap or not.
     */
    Drupal.tableDrag.prototype.row.prototype.isValidSwap = function (row) {
      var $row = $(row);
      if (this.indentEnabled) {
        var prevRow;
        var nextRow;
        if (this.direction === 'down') {
          prevRow = row;
          nextRow = $row.next('tr').get(0);
        }
        else {
          prevRow = $row.prev('tr').get(0);
          nextRow = row;
        }
        this.interval = this.validIndentInterval(prevRow, nextRow);
  
        // We have an invalid swap if the valid indentations interval is empty.
        if (this.interval.min > this.interval.max) {
          return false;
        }
      }
  
      // Do not let an un-draggable first row have anything put before it.
      if (this.table.tBodies[0].rows[0] === row && $row.is(':not(.draggable)')) {
        return false;
      }
  
      return true;
    };
  
    /**
     * Perform the swap between two rows.
     *
     * @param {string} position
     *   Whether the swap will occur 'before' or 'after' the given row.
     * @param {HTMLElement} row
     *   DOM element what will be swapped with the row group.
     */
    Drupal.tableDrag.prototype.row.prototype.swap = function (position, row) {
      // Makes sure only DOM object are passed to Drupal.detachBehaviors().
      this.group.forEach(function (row) {
        Drupal.detachBehaviors(row, drupalSettings, 'move');
      });
      $(row)[position](this.group);
      // Makes sure only DOM object are passed to Drupal.attachBehaviors()s.
      this.group.forEach(function (row) {
        Drupal.attachBehaviors(row, drupalSettings);
      });
      this.changed = true;
      this.onSwap(row);
    };
  
    /**
     * Determine the valid indentations interval for the row at a given position.
     *
     * @param {?HTMLElement} prevRow
     *   DOM object for the row before the tested position
     *   (or null for first position in the table).
     * @param {?HTMLElement} nextRow
     *   DOM object for the row after the tested position
     *   (or null for last position in the table).
     *
     * @return {object}
     *   An object with the keys `min` and `max` to indicate the valid indent
     *   interval.
     */
    Drupal.tableDrag.prototype.row.prototype.validIndentInterval = function (prevRow, nextRow) {
      var $prevRow = $(prevRow);
      var minIndent;
      var maxIndent;
  
      // Minimum indentation:
      // Do not orphan the next row.
      minIndent = nextRow ? $(nextRow).find('.js-indentation').length : 0;
  
      // Maximum indentation:
      if (!prevRow || $prevRow.is(':not(.draggable)') || $(this.element).is('.tabledrag-root')) {
        // Do not indent:
        // - the first row in the table,
        // - rows dragged below a non-draggable row,
        // - 'root' rows.
        maxIndent = 0;
      }
      else {
        // Do not go deeper than as a child of the previous row.
        maxIndent = $prevRow.find('.js-indentation').length + ($prevRow.is('.tabledrag-leaf') ? 0 : 1);
        // Limit by the maximum allowed depth for the table.
        if (this.maxDepth) {
          maxIndent = Math.min(maxIndent, this.maxDepth - (this.groupDepth - this.indents));
        }
      }
  
      return {min: minIndent, max: maxIndent};
    };
  
    /**
     * Indent a row within the legal bounds of the table.
     *
     * @param {number} indentDiff
     *   The number of additional indentations proposed for the row (can be
     *   positive or negative). This number will be adjusted to nearest valid
     *   indentation level for the row.
     *
     * @return {number}
     *   The number of indentations applied.
     */
    Drupal.tableDrag.prototype.row.prototype.indent = function (indentDiff) {
      var $group = $(this.group);
      // Determine the valid indentations interval if not available yet.
      if (!this.interval) {
        var prevRow = $(this.element).prev('tr').get(0);
        var nextRow = $group.eq(-1).next('tr').get(0);
        this.interval = this.validIndentInterval(prevRow, nextRow);
      }
  
      // Adjust to the nearest valid indentation.
      var indent = this.indents + indentDiff;
      indent = Math.max(indent, this.interval.min);
      indent = Math.min(indent, this.interval.max);
      indentDiff = indent - this.indents;
  
      for (var n = 1; n <= Math.abs(indentDiff); n++) {
        // Add or remove indentations.
        if (indentDiff < 0) {
          $group.find('.js-indentation:first-of-type').remove();
          this.indents--;
        }
        else {
          $group.find('td:first-of-type').prepend(Drupal.theme('tableDragIndentation'));
          this.indents++;
        }
      }
      if (indentDiff) {
        // Update indentation for this row.
        this.changed = true;
        this.groupDepth += indentDiff;
        this.onIndent();
      }
  
      return indentDiff;
    };
  
    /**
     * Find all siblings for a row.
     *
     * According to its subgroup or indentation. Note that the passed-in row is
     * included in the list of siblings.
     *
     * @param {object} rowSettings
     *   The field settings we're using to identify what constitutes a sibling.
     *
     * @return {Array}
     *   An array of siblings.
     */
    Drupal.tableDrag.prototype.row.prototype.findSiblings = function (rowSettings) {
      var siblings = [];
      var directions = ['prev', 'next'];
      var rowIndentation = this.indents;
      var checkRowIndentation;
      for (var d = 0; d < directions.length; d++) {
        var checkRow = $(this.element)[directions[d]]();
        while (checkRow.length) {
          // Check that the sibling contains a similar target field.
          if (checkRow.find('.' + rowSettings.target)) {
            // Either add immediately if this is a flat table, or check to ensure
            // that this row has the same level of indentation.
            if (this.indentEnabled) {
              checkRowIndentation = checkRow.find('.js-indentation').length;
            }
  
            if (!(this.indentEnabled) || (checkRowIndentation === rowIndentation)) {
              siblings.push(checkRow[0]);
            }
            else if (checkRowIndentation < rowIndentation) {
              // No need to keep looking for siblings when we get to a parent.
              break;
            }
          }
          else {
            break;
          }
          checkRow = checkRow[directions[d]]();
        }
        // Since siblings are added in reverse order for previous, reverse the
        // completed list of previous siblings. Add the current row and continue.
        if (directions[d] === 'prev') {
          siblings.reverse();
          siblings.push(this.element);
        }
      }
      return siblings;
    };
  
    /**
     * Remove indentation helper classes from the current row group.
     */
    Drupal.tableDrag.prototype.row.prototype.removeIndentClasses = function () {
      for (var n in this.children) {
        if (this.children.hasOwnProperty(n)) {
          $(this.children[n]).find('.js-indentation')
            .removeClass('tree-child')
            .removeClass('tree-child-first')
            .removeClass('tree-child-last')
            .removeClass('tree-child-horizontal');
        }
      }
    };
  
    /**
     * Add an asterisk or other marker to the changed row.
     */
    Drupal.tableDrag.prototype.row.prototype.markChanged = function () {
      var marker = Drupal.theme('tableDragChangedMarker');
      var cell = $(this.element).find('td:first-of-type');
      if (cell.find('abbr.tabledrag-changed').length === 0) {
        cell.append(marker);
      }
    };
  
    /**
     * Stub function. Allows a custom handler when a row is indented.
     *
     * @return {null}
     *   Returns null when the stub function is used.
     */
    Drupal.tableDrag.prototype.row.prototype.onIndent = function () {
      return null;
    };
  
    /**
     * Stub function. Allows a custom handler when a row is swapped.
     *
     * @param {HTMLElement} swappedRow
     *   The element for the swapped row.
     *
     * @return {null}
     *   Returns null when the stub function is used.
     */
    Drupal.tableDrag.prototype.row.prototype.onSwap = function (swappedRow) {
      return null;
    };
  
    $.extend(Drupal.theme, /** @lends Drupal.theme */{
  
      /**
       * @return {string}
       *  Markup for the marker.
       */
      tableDragChangedMarker: function () {
        return '<abbr class="warning tabledrag-changed" title="' + Drupal.t('Changed') + '">*</abbr>';
      },
  
      /**
       * @return {string}
       *   Markup for the indentation.
       */
      tableDragIndentation: function () {
        return '<div class="js-indentation indentation">&nbsp;</div>';
      },
  
      /**
       * @return {string}
       *   Markup for the warning.
       */
      tableDragChangedWarning: function () {
        return '<div class="tabledrag-changed-warning messages messages--warning" role="alert">' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t('You have unsaved changes.') + '</div>';
      }
    });
  
  })(jQuery, Drupal, drupalSettings);
  ;
  /**
   * @file
   * Attaches behaviors for Drupal's active link marking.
   */
  
  (function (Drupal, drupalSettings) {
  
    'use strict';
  
    /**
     * Append is-active class.
     *
     * The link is only active if its path corresponds to the current path, the
     * language of the linked path is equal to the current language, and if the
     * query parameters of the link equal those of the current request, since the
     * same request with different query parameters may yield a different page
     * (e.g. pagers, exposed View filters).
     *
     * Does not discriminate based on element type, so allows you to set the
     * is-active class on any element: a, li…
     *
     * @type {Drupal~behavior}
     */
    Drupal.behaviors.activeLinks = {
      attach: function (context) {
        // Start by finding all potentially active links.
        var path = drupalSettings.path;
        var queryString = JSON.stringify(path.currentQuery);
        var querySelector = path.currentQuery ? "[data-drupal-link-query='" + queryString + "']" : ':not([data-drupal-link-query])';
        var originalSelectors = ['[data-drupal-link-system-path="' + path.currentPath + '"]'];
        var selectors;
  
        // If this is the front page, we have to check for the <front> path as
        // well.
        if (path.isFront) {
          originalSelectors.push('[data-drupal-link-system-path="<front>"]');
        }
  
        // Add language filtering.
        selectors = [].concat(
          // Links without any hreflang attributes (most of them).
          originalSelectors.map(function (selector) { return selector + ':not([hreflang])'; }),
          // Links with hreflang equals to the current language.
          originalSelectors.map(function (selector) { return selector + '[hreflang="' + path.currentLanguage + '"]'; })
        );
  
        // Add query string selector for pagers, exposed filters.
        selectors = selectors.map(function (current) { return current + querySelector; });
  
        // Query the DOM.
        var activeLinks = context.querySelectorAll(selectors.join(','));
        var il = activeLinks.length;
        for (var i = 0; i < il; i++) {
          activeLinks[i].classList.add('is-active');
        }
      },
      detach: function (context, settings, trigger) {
        if (trigger === 'unload') {
          var activeLinks = context.querySelectorAll('[data-drupal-link-system-path].is-active');
          var il = activeLinks.length;
          for (var i = 0; i < il; i++) {
            activeLinks[i].classList.remove('is-active');
          }
        }
      }
    };
  
  })(Drupal, drupalSettings);
  ;
  /**
   * @file
   * Responsive table functionality.
   */
  
  (function ($, Drupal, window) {
  
    'use strict';
  
    /**
     * Attach the tableResponsive function to {@link Drupal.behaviors}.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches tableResponsive functionality.
     */
    Drupal.behaviors.tableResponsive = {
      attach: function (context, settings) {
        var $tables = $(context).find('table.responsive-enabled').once('tableresponsive');
        if ($tables.length) {
          var il = $tables.length;
          for (var i = 0; i < il; i++) {
            TableResponsive.tables.push(new TableResponsive($tables[i]));
          }
        }
      }
    };
  
    /**
     * The TableResponsive object optimizes table presentation for screen size.
     *
     * A responsive table hides columns at small screen sizes, leaving the most
     * important columns visible to the end user. Users should not be prevented
     * from accessing all columns, however. This class adds a toggle to a table
     * with hidden columns that exposes the columns. Exposing the columns will
     * likely break layouts, but it provides the user with a means to access
     * data, which is a guiding principle of responsive design.
     *
     * @constructor Drupal.TableResponsive
     *
     * @param {HTMLElement} table
     *   The table element to initialize the responsive table on.
     */
    function TableResponsive(table) {
      this.table = table;
      this.$table = $(table);
      this.showText = Drupal.t('Show all columns');
      this.hideText = Drupal.t('Hide lower priority columns');
      // Store a reference to the header elements of the table so that the DOM is
      // traversed only once to find them.
      this.$headers = this.$table.find('th');
      // Add a link before the table for users to show or hide weight columns.
      this.$link = $('<button type="button" class="link tableresponsive-toggle"></button>')
        .attr('title', Drupal.t('Show table cells that were hidden to make the table fit within a small screen.'))
        .on('click', $.proxy(this, 'eventhandlerToggleColumns'));
  
      this.$table.before($('<div class="tableresponsive-toggle-columns"></div>').append(this.$link));
  
      // Attach a resize handler to the window.
      $(window)
        .on('resize.tableresponsive', $.proxy(this, 'eventhandlerEvaluateColumnVisibility'))
        .trigger('resize.tableresponsive');
    }
  
    /**
     * Extend the TableResponsive function with a list of managed tables.
     */
    $.extend(TableResponsive, /** @lends Drupal.TableResponsive */{
  
      /**
       * Store all created instances.
       *
       * @type {Array.<Drupal.TableResponsive>}
       */
      tables: []
    });
  
    /**
     * Associates an action link with the table that will show hidden columns.
     *
     * Columns are assumed to be hidden if their header has the class priority-low
     * or priority-medium.
     */
    $.extend(TableResponsive.prototype, /** @lends Drupal.TableResponsive# */{
  
      /**
       * @param {jQuery.Event} e
       *   The event triggered.
       */
      eventhandlerEvaluateColumnVisibility: function (e) {
        var pegged = parseInt(this.$link.data('pegged'), 10);
        var hiddenLength = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden').length;
        // If the table has hidden columns, associate an action link with the
        // table to show the columns.
        if (hiddenLength > 0) {
          this.$link.show().text(this.showText);
        }
        // When the toggle is pegged, its presence is maintained because the user
        // has interacted with it. This is necessary to keep the link visible if
        // the user adjusts screen size and changes the visibility of columns.
        if (!pegged && hiddenLength === 0) {
          this.$link.hide().text(this.hideText);
        }
      },
  
      /**
       * Toggle the visibility of columns based on their priority.
       *
       * Columns are classed with either 'priority-low' or 'priority-medium'.
       *
       * @param {jQuery.Event} e
       *   The event triggered.
       */
      eventhandlerToggleColumns: function (e) {
        e.preventDefault();
        var self = this;
        var $hiddenHeaders = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden');
        this.$revealedCells = this.$revealedCells || $();
        // Reveal hidden columns.
        if ($hiddenHeaders.length > 0) {
          $hiddenHeaders.each(function (index, element) {
            var $header = $(this);
            var position = $header.prevAll('th').length;
            self.$table.find('tbody tr').each(function () {
              var $cells = $(this).find('td').eq(position);
              $cells.show();
              // Keep track of the revealed cells, so they can be hidden later.
              self.$revealedCells = $().add(self.$revealedCells).add($cells);
            });
            $header.show();
            // Keep track of the revealed headers, so they can be hidden later.
            self.$revealedCells = $().add(self.$revealedCells).add($header);
          });
          this.$link.text(this.hideText).data('pegged', 1);
        }
        // Hide revealed columns.
        else {
          this.$revealedCells.hide();
          // Strip the 'display:none' declaration from the style attributes of
          // the table cells that .hide() added.
          this.$revealedCells.each(function (index, element) {
            var $cell = $(this);
            var properties = $cell.attr('style').split(';');
            var newProps = [];
            // The hide method adds display none to the element. The element
            // should be returned to the same state it was in before the columns
            // were revealed, so it is necessary to remove the display none value
            // from the style attribute.
            var match = /^display\s*\:\s*none$/;
            for (var i = 0; i < properties.length; i++) {
              var prop = properties[i];
              prop.trim();
              // Find the display:none property and remove it.
              var isDisplayNone = match.exec(prop);
              if (isDisplayNone) {
                continue;
              }
              newProps.push(prop);
            }
            // Return the rest of the style attribute values to the element.
            $cell.attr('style', newProps.join(';'));
          });
          this.$link.text(this.showText).data('pegged', 0);
          // Refresh the toggle link.
          $(window).trigger('resize.tableresponsive');
        }
      }
    });
  
    // Make the TableResponsive object available in the Drupal namespace.
    Drupal.TableResponsive = TableResponsive;
  
  })(jQuery, Drupal, window);
  ;
  /*! jquery.cookie v1.4.1 | MIT */
  !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}});;
  /**
   * @file
   * Dropbutton feature.
   */
  
  (function ($, Drupal) {
  
    'use strict';
  
    /**
     * Process elements with the .dropbutton class on page load.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches dropButton behaviors.
     */
    Drupal.behaviors.dropButton = {
      attach: function (context, settings) {
        var $dropbuttons = $(context).find('.dropbutton-wrapper').once('dropbutton');
        if ($dropbuttons.length) {
          // Adds the delegated handler that will toggle dropdowns on click.
          var $body = $('body').once('dropbutton-click');
          if ($body.length) {
            $body.on('click', '.dropbutton-toggle', dropbuttonClickHandler);
          }
          // Initialize all buttons.
          var il = $dropbuttons.length;
          for (var i = 0; i < il; i++) {
            DropButton.dropbuttons.push(new DropButton($dropbuttons[i], settings.dropbutton));
          }
        }
      }
    };
  
    /**
     * Delegated callback for opening and closing dropbutton secondary actions.
     *
     * @function Drupal.DropButton~dropbuttonClickHandler
     *
     * @param {jQuery.Event} e
     *   The event triggered.
     */
    function dropbuttonClickHandler(e) {
      e.preventDefault();
      $(e.target).closest('.dropbutton-wrapper').toggleClass('open');
    }
  
    /**
     * A DropButton presents an HTML list as a button with a primary action.
     *
     * All secondary actions beyond the first in the list are presented in a
     * dropdown list accessible through a toggle arrow associated with the button.
     *
     * @constructor Drupal.DropButton
     *
     * @param {HTMLElement} dropbutton
     *   A DOM element.
     * @param {object} settings
     *   A list of options including:
     * @param {string} settings.title
     *   The text inside the toggle link element. This text is hidden
     *   from visual UAs.
     */
    function DropButton(dropbutton, settings) {
      // Merge defaults with settings.
      var options = $.extend({title: Drupal.t('List additional actions')}, settings);
      var $dropbutton = $(dropbutton);
  
      /**
       * @type {jQuery}
       */
      this.$dropbutton = $dropbutton;
  
      /**
       * @type {jQuery}
       */
      this.$list = $dropbutton.find('.dropbutton');
  
      /**
       * Find actions and mark them.
       *
       * @type {jQuery}
       */
      this.$actions = this.$list.find('li').addClass('dropbutton-action');
  
      // Add the special dropdown only if there are hidden actions.
      if (this.$actions.length > 1) {
        // Identify the first element of the collection.
        var $primary = this.$actions.slice(0, 1);
        // Identify the secondary actions.
        var $secondary = this.$actions.slice(1);
        $secondary.addClass('secondary-action');
        // Add toggle link.
        $primary.after(Drupal.theme('dropbuttonToggle', options));
        // Bind mouse events.
        this.$dropbutton
          .addClass('dropbutton-multiple')
          .on({
  
            /**
             * Adds a timeout to close the dropdown on mouseleave.
             *
             * @ignore
             */
            'mouseleave.dropbutton': $.proxy(this.hoverOut, this),
  
            /**
             * Clears timeout when mouseout of the dropdown.
             *
             * @ignore
             */
            'mouseenter.dropbutton': $.proxy(this.hoverIn, this),
  
            /**
             * Similar to mouseleave/mouseenter, but for keyboard navigation.
             *
             * @ignore
             */
            'focusout.dropbutton': $.proxy(this.focusOut, this),
  
            /**
             * @ignore
             */
            'focusin.dropbutton': $.proxy(this.focusIn, this)
          });
      }
      else {
        this.$dropbutton.addClass('dropbutton-single');
      }
    }
  
    /**
     * Extend the DropButton constructor.
     */
    $.extend(DropButton, /** @lends Drupal.DropButton */{
      /**
       * Store all processed DropButtons.
       *
       * @type {Array.<Drupal.DropButton>}
       */
      dropbuttons: []
    });
  
    /**
     * Extend the DropButton prototype.
     */
    $.extend(DropButton.prototype, /** @lends Drupal.DropButton# */{
  
      /**
       * Toggle the dropbutton open and closed.
       *
       * @param {bool} [show]
       *   Force the dropbutton to open by passing true or to close by
       *   passing false.
       */
      toggle: function (show) {
        var isBool = typeof show === 'boolean';
        show = isBool ? show : !this.$dropbutton.hasClass('open');
        this.$dropbutton.toggleClass('open', show);
      },
  
      /**
       * @method
       */
      hoverIn: function () {
        // Clear any previous timer we were using.
        if (this.timerID) {
          window.clearTimeout(this.timerID);
        }
      },
  
      /**
       * @method
       */
      hoverOut: function () {
        // Wait half a second before closing.
        this.timerID = window.setTimeout($.proxy(this, 'close'), 500);
      },
  
      /**
       * @method
       */
      open: function () {
        this.toggle(true);
      },
  
      /**
       * @method
       */
      close: function () {
        this.toggle(false);
      },
  
      /**
       * @param {jQuery.Event} e
       *   The event triggered.
       */
      focusOut: function (e) {
        this.hoverOut.call(this, e);
      },
  
      /**
       * @param {jQuery.Event} e
       *   The event triggered.
       */
      focusIn: function (e) {
        this.hoverIn.call(this, e);
      }
    });
  
    $.extend(Drupal.theme, /** @lends Drupal.theme */{
  
      /**
       * A toggle is an interactive element often bound to a click handler.
       *
       * @param {object} options
       *   Options object.
       * @param {string} [options.title]
       *   The HTML anchor title attribute and text for the inner span element.
       *
       * @return {string}
       *   A string representing a DOM fragment.
       */
      dropbuttonToggle: function (options) {
        return '<li class="dropbutton-toggle"><button type="button"><span class="dropbutton-arrow"><span class="visually-hidden">' + options.title + '</span></span></button></li>';
      }
    });
  
    // Expose constructor in the public space.
    Drupal.DropButton = DropButton;
  
  })(jQuery, Drupal);
  ;
  window.matchMedia||(window.matchMedia=function(){"use strict";var e=window.styleMedia||window.media;if(!e){var t=document.createElement("style"),i=document.getElementsByTagName("script")[0],n=null;t.type="text/css";t.id="matchmediajs-test";i.parentNode.insertBefore(t,i);n="getComputedStyle"in window&&window.getComputedStyle(t,null)||t.currentStyle;e={matchMedium:function(e){var i="@media "+e+"{ #matchmediajs-test { width: 1px; } }";if(t.styleSheet){t.styleSheet.cssText=i}else{t.textContent=i}return n.width==="1px"}}}return function(t){return{matches:e.matchMedium(t||"all"),media:t||"all"}}}());
  ;
  /**
   * @file
   * Adapted from underscore.js with the addition Drupal namespace.
   */
  
  /**
   * Limits the invocations of a function in a given time frame.
   *
   * The debounce function wrapper should be used sparingly. One clear use case
   * is limiting the invocation of a callback attached to the window resize event.
   *
   * Before using the debounce function wrapper, consider first whether the
   * callback could be attached to an event that fires less frequently or if the
   * function can be written in such a way that it is only invoked under specific
   * conditions.
   *
   * @param {function} func
   *   The function to be invoked.
   * @param {number} wait
   *   The time period within which the callback function should only be
   *   invoked once. For example if the wait period is 250ms, then the callback
   *   will only be called at most 4 times per second.
   * @param {bool} immediate
   *   Whether we wait at the beginning or end to execute the function.
   *
   * @return {function}
   *   The debounced function.
   */
  Drupal.debounce = function (func, wait, immediate) {
  
    'use strict';
  
    var timeout;
    var result;
    return function () {
      var context = this;
      var args = arguments;
      var later = function () {
        timeout = null;
        if (!immediate) {
          result = func.apply(context, args);
        }
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) {
        result = func.apply(context, args);
      }
      return result;
    };
  };
  ;
  /**
   * @file
   * Responsive navigation tabs.
   *
   * This also supports collapsible navigable is the 'is-collapsible' class is
   * added to the main element, and a target element is included.
   */
  (function ($, Drupal) {
  
    'use strict';
  
    function init(i, tab) {
      var $tab = $(tab);
      var $target = $tab.find('[data-drupal-nav-tabs-target]');
      var isCollapsible = $tab.hasClass('is-collapsible');
  
      function openMenu(e) {
        $target.toggleClass('is-open');
      }
  
      function handleResize(e) {
        $tab.addClass('is-horizontal');
        var $tabs = $tab.find('.tabs');
        var isHorizontal = $tabs.outerHeight() <= $tabs.find('.tabs__tab').outerHeight();
        $tab.toggleClass('is-horizontal', isHorizontal);
        if (isCollapsible) {
          $tab.toggleClass('is-collapse-enabled', !isHorizontal);
        }
        if (isHorizontal) {
          $target.removeClass('is-open');
        }
      }
  
      $tab.addClass('position-container is-horizontal-enabled');
  
      $tab.on('click.tabs', '[data-drupal-nav-tabs-trigger]', openMenu);
      $(window).on('resize.tabs', Drupal.debounce(handleResize, 150)).trigger('resize.tabs');
    }
  
    /**
     * Initialise the tabs JS.
     */
    Drupal.behaviors.navTabs = {
      attach: function (context, settings) {
        var $tabs = $(context).find('[data-drupal-nav-tabs]');
        if ($tabs.length) {
          var notSmartPhone = window.matchMedia('(min-width: 300px)');
          if (notSmartPhone.matches) {
            $tabs.once('nav-tabs').each(init);
          }
        }
      }
    };
  
  })(jQuery, Drupal);
  ;
  /**
   * @file
   * Progress bar.
   */
  
  (function ($, Drupal) {
  
    'use strict';
  
    /**
     * Theme function for the progress bar.
     *
     * @param {string} id
     *   The id for the progress bar.
     *
     * @return {string}
     *   The HTML for the progress bar.
     */
    Drupal.theme.progressBar = function (id) {
      return '<div id="' + id + '" class="progress" aria-live="polite">' +
        '<div class="progress__label">&nbsp;</div>' +
        '<div class="progress__track"><div class="progress__bar"></div></div>' +
        '<div class="progress__percentage"></div>' +
        '<div class="progress__description">&nbsp;</div>' +
        '</div>';
    };
  
    /**
     * A progressbar object. Initialized with the given id. Must be inserted into
     * the DOM afterwards through progressBar.element.
     *
     * Method is the function which will perform the HTTP request to get the
     * progress bar state. Either "GET" or "POST".
     *
     * @example
     * pb = new Drupal.ProgressBar('myProgressBar');
     * some_element.appendChild(pb.element);
     *
     * @constructor
     *
     * @param {string} id
     *   The id for the progressbar.
     * @param {function} updateCallback
     *   Callback to run on update.
     * @param {string} method
     *   HTTP method to use.
     * @param {function} errorCallback
     *   Callback to call on error.
     */
    Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) {
      this.id = id;
      this.method = method || 'GET';
      this.updateCallback = updateCallback;
      this.errorCallback = errorCallback;
  
      // The WAI-ARIA setting aria-live="polite" will announce changes after
      // users
      // have completed their current activity and not interrupt the screen
      // reader.
      this.element = $(Drupal.theme('progressBar', id));
    };
  
    $.extend(Drupal.ProgressBar.prototype, /** @lends Drupal.ProgressBar# */{
  
      /**
       * Set the percentage and status message for the progressbar.
       *
       * @param {number} percentage
       *   The progress percentage.
       * @param {string} message
       *   The message to show the user.
       * @param {string} label
       *   The text for the progressbar label.
       */
      setProgress: function (percentage, message, label) {
        if (percentage >= 0 && percentage <= 100) {
          $(this.element).find('div.progress__bar').css('width', percentage + '%');
          $(this.element).find('div.progress__percentage').html(percentage + '%');
        }
        $('div.progress__description', this.element).html(message);
        $('div.progress__label', this.element).html(label);
        if (this.updateCallback) {
          this.updateCallback(percentage, message, this);
        }
      },
  
      /**
       * Start monitoring progress via Ajax.
       *
       * @param {string} uri
       *   The URI to use for monitoring.
       * @param {number} delay
       *   The delay for calling the monitoring URI.
       */
      startMonitoring: function (uri, delay) {
        this.delay = delay;
        this.uri = uri;
        this.sendPing();
      },
  
      /**
       * Stop monitoring progress via Ajax.
       */
      stopMonitoring: function () {
        clearTimeout(this.timer);
        // This allows monitoring to be stopped from within the callback.
        this.uri = null;
      },
  
      /**
       * Request progress data from server.
       */
      sendPing: function () {
        if (this.timer) {
          clearTimeout(this.timer);
        }
        if (this.uri) {
          var pb = this;
          // When doing a post request, you need non-null data. Otherwise a
          // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
          var uri = this.uri;
          if (uri.indexOf('?') === -1) {
            uri += '?';
          }
          else {
            uri += '&';
          }
          uri += '_format=json';
          $.ajax({
            type: this.method,
            url: uri,
            data: '',
            dataType: 'json',
            success: function (progress) {
              // Display errors.
              if (progress.status === 0) {
                pb.displayError(progress.data);
                return;
              }
              // Update display.
              pb.setProgress(progress.percentage, progress.message, progress.label);
              // Schedule next timer.
              pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay);
            },
            error: function (xmlhttp) {
              var e = new Drupal.AjaxError(xmlhttp, pb.uri);
              pb.displayError('<pre>' + e.message + '</pre>');
            }
          });
        }
      },
  
      /**
       * Display errors on the page.
       *
       * @param {string} string
       *   The error message to show the user.
       */
      displayError: function (string) {
        var error = $('<div class="messages messages--error"></div>').html(string);
        $(this.element).before(error).hide();
  
        if (this.errorCallback) {
          this.errorCallback(this);
        }
      }
    });
  
  })(jQuery, Drupal);
  ;
  /**
   * @file
   * Provides Ajax page updating via jQuery $.ajax.
   *
   * Ajax is a method of making a request via JavaScript while viewing an HTML
   * page. The request returns an array of commands encoded in JSON, which is
   * then executed to make any changes that are necessary to the page.
   *
   * Drupal uses this file to enhance form elements with `#ajax['url']` and
   * `#ajax['wrapper']` properties. If set, this file will automatically be
   * included to provide Ajax capabilities.
   */
  
  (function ($, window, Drupal, drupalSettings) {
  
    'use strict';
  
    /**
     * Attaches the Ajax behavior to each Ajax form element.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Initialize all {@link Drupal.Ajax} objects declared in
     *   `drupalSettings.ajax` or initialize {@link Drupal.Ajax} objects from
     *   DOM elements having the `use-ajax-submit` or `use-ajax` css class.
     * @prop {Drupal~behaviorDetach} detach
     *   During `unload` remove all {@link Drupal.Ajax} objects related to
     *   the removed content.
     */
    Drupal.behaviors.AJAX = {
      attach: function (context, settings) {
  
        function loadAjaxBehavior(base) {
          var element_settings = settings.ajax[base];
          if (typeof element_settings.selector === 'undefined') {
            element_settings.selector = '#' + base;
          }
          $(element_settings.selector).once('drupal-ajax').each(function () {
            element_settings.element = this;
            element_settings.base = base;
            Drupal.ajax(element_settings);
          });
        }
  
        // Load all Ajax behaviors specified in the settings.
        for (var base in settings.ajax) {
          if (settings.ajax.hasOwnProperty(base)) {
            loadAjaxBehavior(base);
          }
        }
  
        // Bind Ajax behaviors to all items showing the class.
        $('.use-ajax').once('ajax').each(function () {
          var element_settings = {};
          // Clicked links look better with the throbber than the progress bar.
          element_settings.progress = {type: 'throbber'};
  
          // For anchor tags, these will go to the target of the anchor rather
          // than the usual location.
          var href = $(this).attr('href');
          if (href) {
            element_settings.url = href;
            element_settings.event = 'click';
          }
          element_settings.dialogType = $(this).data('dialog-type');
          element_settings.dialog = $(this).data('dialog-options');
          element_settings.base = $(this).attr('id');
          element_settings.element = this;
          Drupal.ajax(element_settings);
        });
  
        // This class means to submit the form to the action using Ajax.
        $('.use-ajax-submit').once('ajax').each(function () {
          var element_settings = {};
  
          // Ajax submits specified in this manner automatically submit to the
          // normal form action.
          element_settings.url = $(this.form).attr('action');
          // Form submit button clicks need to tell the form what was clicked so
          // it gets passed in the POST request.
          element_settings.setClick = true;
          // Form buttons use the 'click' event rather than mousedown.
          element_settings.event = 'click';
          // Clicked form buttons look better with the throbber than the progress
          // bar.
          element_settings.progress = {type: 'throbber'};
          element_settings.base = $(this).attr('id');
          element_settings.element = this;
  
          Drupal.ajax(element_settings);
        });
      },
  
      detach: function (context, settings, trigger) {
        if (trigger === 'unload') {
          Drupal.ajax.expired().forEach(function (instance) {
            // Set this to null and allow garbage collection to reclaim
            // the memory.
            Drupal.ajax.instances[instance.instanceIndex] = null;
          });
        }
      }
    };
  
    /**
     * Extends Error to provide handling for Errors in Ajax.
     *
     * @constructor
     *
     * @augments Error
     *
     * @param {XMLHttpRequest} xmlhttp
     *   XMLHttpRequest object used for the failed request.
     * @param {string} uri
     *   The URI where the error occurred.
     * @param {string} customMessage
     *   The custom message.
     */
    Drupal.AjaxError = function (xmlhttp, uri, customMessage) {
  
      var statusCode;
      var statusText;
      var pathText;
      var responseText;
      var readyStateText;
      if (xmlhttp.status) {
        statusCode = '\n' + Drupal.t('An AJAX HTTP error occurred.') + '\n' + Drupal.t('HTTP Result Code: !status', {'!status': xmlhttp.status});
      }
      else {
        statusCode = '\n' + Drupal.t('An AJAX HTTP request terminated abnormally.');
      }
      statusCode += '\n' + Drupal.t('Debugging information follows.');
      pathText = '\n' + Drupal.t('Path: !uri', {'!uri': uri});
      statusText = '';
      // In some cases, when statusCode === 0, xmlhttp.statusText may not be
      // defined. Unfortunately, testing for it with typeof, etc, doesn't seem to
      // catch that and the test causes an exception. So we need to catch the
      // exception here.
      try {
        statusText = '\n' + Drupal.t('StatusText: !statusText', {'!statusText': $.trim(xmlhttp.statusText)});
      }
      catch (e) {
        // Empty.
      }
  
      responseText = '';
      // Again, we don't have a way to know for sure whether accessing
      // xmlhttp.responseText is going to throw an exception. So we'll catch it.
      try {
        responseText = '\n' + Drupal.t('ResponseText: !responseText', {'!responseText': $.trim(xmlhttp.responseText)});
      }
      catch (e) {
        // Empty.
      }
  
      // Make the responseText more readable by stripping HTML tags and newlines.
      responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, '');
      responseText = responseText.replace(/[\n]+\s+/g, '\n');
  
      // We don't need readyState except for status == 0.
      readyStateText = xmlhttp.status === 0 ? ('\n' + Drupal.t('ReadyState: !readyState', {'!readyState': xmlhttp.readyState})) : '';
  
      customMessage = customMessage ? ('\n' + Drupal.t('CustomMessage: !customMessage', {'!customMessage': customMessage})) : '';
  
      /**
       * Formatted and translated error message.
       *
       * @type {string}
       */
      this.message = statusCode + pathText + statusText + customMessage + responseText + readyStateText;
  
      /**
       * Used by some browsers to display a more accurate stack trace.
       *
       * @type {string}
       */
      this.name = 'AjaxError';
    };
  
    Drupal.AjaxError.prototype = new Error();
    Drupal.AjaxError.prototype.constructor = Drupal.AjaxError;
  
    /**
     * Provides Ajax page updating via jQuery $.ajax.
     *
     * This function is designed to improve developer experience by wrapping the
     * initialization of {@link Drupal.Ajax} objects and storing all created
     * objects in the {@link Drupal.ajax.instances} array.
     *
     * @example
     * Drupal.behaviors.myCustomAJAXStuff = {
     *   attach: function (context, settings) {
     *
     *     var ajaxSettings = {
     *       url: 'my/url/path',
     *       // If the old version of Drupal.ajax() needs to be used those
     *       // properties can be added
     *       base: 'myBase',
     *       element: $(context).find('.someElement')
     *     };
     *
     *     var myAjaxObject = Drupal.ajax(ajaxSettings);
     *
     *     // Declare a new Ajax command specifically for this Ajax object.
     *     myAjaxObject.commands.insert = function (ajax, response, status) {
     *       $('#my-wrapper').append(response.data);
     *       alert('New content was appended to #my-wrapper');
     *     };
     *
     *     // This command will remove this Ajax object from the page.
     *     myAjaxObject.commands.destroyObject = function (ajax, response, status) {
     *       Drupal.ajax.instances[this.instanceIndex] = null;
     *     };
     *
     *     // Programmatically trigger the Ajax request.
     *     myAjaxObject.execute();
     *   }
     * };
     *
     * @param {object} settings
     *   The settings object passed to {@link Drupal.Ajax} constructor.
     * @param {string} [settings.base]
     *   Base is passed to {@link Drupal.Ajax} constructor as the 'base'
     *   parameter.
     * @param {HTMLElement} [settings.element]
     *   Element parameter of {@link Drupal.Ajax} constructor, element on which
     *   event listeners will be bound.
     *
     * @return {Drupal.Ajax}
     *   The created Ajax object.
     *
     * @see Drupal.AjaxCommands
     */
    Drupal.ajax = function (settings) {
      if (arguments.length !== 1) {
        throw new Error('Drupal.ajax() function must be called with one configuration object only');
      }
      // Map those config keys to variables for the old Drupal.ajax function.
      var base = settings.base || false;
      var element = settings.element || false;
      delete settings.base;
      delete settings.element;
  
      // By default do not display progress for ajax calls without an element.
      if (!settings.progress && !element) {
        settings.progress = false;
      }
  
      var ajax = new Drupal.Ajax(base, element, settings);
      ajax.instanceIndex = Drupal.ajax.instances.length;
      Drupal.ajax.instances.push(ajax);
  
      return ajax;
    };
  
    /**
     * Contains all created Ajax objects.
     *
     * @type {Array.<Drupal.Ajax|null>}
     */
    Drupal.ajax.instances = [];
  
    /**
     * List all objects where the associated element is not in the DOM
     *
     * This method ignores {@link Drupal.Ajax} objects not bound to DOM elements
     * when created with {@link Drupal.ajax}.
     *
     * @return {Array.<Drupal.Ajax>}
     *   The list of expired {@link Drupal.Ajax} objects.
     */
    Drupal.ajax.expired = function () {
      return Drupal.ajax.instances.filter(function (instance) {
        return instance && instance.element !== false && !document.body.contains(instance.element);
      });
    };
  
    /**
     * Settings for an Ajax object.
     *
     * @typedef {object} Drupal.Ajax~element_settings
     *
     * @prop {string} url
     *   Target of the Ajax request.
     * @prop {?string} [event]
     *   Event bound to settings.element which will trigger the Ajax request.
     * @prop {bool} [keypress=true]
     *   Triggers a request on keypress events.
     * @prop {?string} selector
     *   jQuery selector targeting the element to bind events to or used with
     *   {@link Drupal.AjaxCommands}.
     * @prop {string} [effect='none']
     *   Name of the jQuery method to use for displaying new Ajax content.
     * @prop {string|number} [speed='none']
     *   Speed with which to apply the effect.
     * @prop {string} [method]
     *   Name of the jQuery method used to insert new content in the targeted
     *   element.
     * @prop {object} [progress]
     *   Settings for the display of a user-friendly loader.
     * @prop {string} [progress.type='throbber']
     *   Type of progress element, core provides `'bar'`, `'throbber'` and
     *   `'fullscreen'`.
     * @prop {string} [progress.message=Drupal.t('Please wait...')]
     *   Custom message to be used with the bar indicator.
     * @prop {object} [submit]
     *   Extra data to be sent with the Ajax request.
     * @prop {bool} [submit.js=true]
     *   Allows the PHP side to know this comes from an Ajax request.
     * @prop {object} [dialog]
     *   Options for {@link Drupal.dialog}.
     * @prop {string} [dialogType]
     *   One of `'modal'` or `'dialog'`.
     * @prop {string} [prevent]
     *   List of events on which to stop default action and stop propagation.
     */
  
    /**
     * Ajax constructor.
     *
     * The Ajax request returns an array of commands encoded in JSON, which is
     * then executed to make any changes that are necessary to the page.
     *
     * Drupal uses this file to enhance form elements with `#ajax['url']` and
     * `#ajax['wrapper']` properties. If set, this file will automatically be
     * included to provide Ajax capabilities.
     *
     * @constructor
     *
     * @param {string} [base]
     *   Base parameter of {@link Drupal.Ajax} constructor
     * @param {HTMLElement} [element]
     *   Element parameter of {@link Drupal.Ajax} constructor, element on which
     *   event listeners will be bound.
     * @param {Drupal.Ajax~element_settings} element_settings
     *   Settings for this Ajax object.
     */
    Drupal.Ajax = function (base, element, element_settings) {
      var defaults = {
        event: element ? 'mousedown' : null,
        keypress: true,
        selector: base ? '#' + base : null,
        effect: 'none',
        speed: 'none',
        method: 'replaceWith',
        progress: {
          type: 'throbber',
          message: Drupal.t('Please wait...')
        },
        submit: {
          js: true
        }
      };
  
      $.extend(this, defaults, element_settings);
  
      /**
       * @type {Drupal.AjaxCommands}
       */
      this.commands = new Drupal.AjaxCommands();
  
      /**
       * @type {bool|number}
       */
      this.instanceIndex = false;
  
      // @todo Remove this after refactoring the PHP code to:
      //   - Call this 'selector'.
      //   - Include the '#' for ID-based selectors.
      //   - Support non-ID-based selectors.
      if (this.wrapper) {
  
        /**
         * @type {string}
         */
        this.wrapper = '#' + this.wrapper;
      }
  
      /**
       * @type {HTMLElement}
       */
      this.element = element;
  
      /**
       * @type {Drupal.Ajax~element_settings}
       */
      this.element_settings = element_settings;
  
      // If there isn't a form, jQuery.ajax() will be used instead, allowing us to
      // bind Ajax to links as well.
      if (this.element && this.element.form) {
  
        /**
         * @type {jQuery}
         */
        this.$form = $(this.element.form);
      }
  
      // If no Ajax callback URL was given, use the link href or form action.
      if (!this.url) {
        var $element = $(this.element);
        if ($element.is('a')) {
          this.url = $element.attr('href');
        }
        else if (this.element && element.form) {
          this.url = this.$form.attr('action');
        }
      }
  
      // Replacing 'nojs' with 'ajax' in the URL allows for an easy method to let
      // the server detect when it needs to degrade gracefully.
      // There are four scenarios to check for:
      // 1. /nojs/
      // 2. /nojs$ - The end of a URL string.
      // 3. /nojs? - Followed by a query (e.g. path/nojs?destination=foobar).
      // 4. /nojs# - Followed by a fragment (e.g.: path/nojs#myfragment).
      var originalUrl = this.url;
  
      /**
       * Processed Ajax URL.
       *
       * @type {string}
       */
      this.url = this.url.replace(/\/nojs(\/|$|\?|#)/g, '/ajax$1');
      // If the 'nojs' version of the URL is trusted, also trust the 'ajax'
      // version.
      if (drupalSettings.ajaxTrustedUrl[originalUrl]) {
        drupalSettings.ajaxTrustedUrl[this.url] = true;
      }
  
      // Set the options for the ajaxSubmit function.
      // The 'this' variable will not persist inside of the options object.
      var ajax = this;
  
      /**
       * Options for the jQuery.ajax function.
       *
       * @name Drupal.Ajax#options
       *
       * @type {object}
       *
       * @prop {string} url
       *   Ajax URL to be called.
       * @prop {object} data
       *   Ajax payload.
       * @prop {function} beforeSerialize
       *   Implement jQuery beforeSerialize function to call
       *   {@link Drupal.Ajax#beforeSerialize}.
       * @prop {function} beforeSubmit
       *   Implement jQuery beforeSubmit function to call
       *   {@link Drupal.Ajax#beforeSubmit}.
       * @prop {function} beforeSend
       *   Implement jQuery beforeSend function to call
       *   {@link Drupal.Ajax#beforeSend}.
       * @prop {function} success
       *   Implement jQuery success function to call
       *   {@link Drupal.Ajax#success}.
       * @prop {function} complete
       *   Implement jQuery success function to clean up ajax state and trigger an
       *   error if needed.
       * @prop {string} dataType='json'
       *   Type of the response expected.
       * @prop {string} type='POST'
       *   HTTP method to use for the Ajax request.
       */
      ajax.options = {
        url: ajax.url,
        data: ajax.submit,
        beforeSerialize: function (element_settings, options) {
          return ajax.beforeSerialize(element_settings, options);
        },
        beforeSubmit: function (form_values, element_settings, options) {
          ajax.ajaxing = true;
          return ajax.beforeSubmit(form_values, element_settings, options);
        },
        beforeSend: function (xmlhttprequest, options) {
          ajax.ajaxing = true;
          return ajax.beforeSend(xmlhttprequest, options);
        },
        success: function (response, status, xmlhttprequest) {
          // Sanity check for browser support (object expected).
          // When using iFrame uploads, responses must be returned as a string.
          if (typeof response === 'string') {
            response = $.parseJSON(response);
          }
  
          // Prior to invoking the response's commands, verify that they can be
          // trusted by checking for a response header. See
          // \Drupal\Core\EventSubscriber\AjaxResponseSubscriber for details.
          // - Empty responses are harmless so can bypass verification. This
          //   avoids an alert message for server-generated no-op responses that
          //   skip Ajax rendering.
          // - Ajax objects with trusted URLs (e.g., ones defined server-side via
          //   #ajax) can bypass header verification. This is especially useful
          //   for Ajax with multipart forms. Because IFRAME transport is used,
          //   the response headers cannot be accessed for verification.
          if (response !== null && !drupalSettings.ajaxTrustedUrl[ajax.url]) {
            if (xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token') !== '1') {
              var customMessage = Drupal.t('The response failed verification so will not be processed.');
              return ajax.error(xmlhttprequest, ajax.url, customMessage);
            }
          }
  
          return ajax.success(response, status);
        },
        complete: function (xmlhttprequest, status) {
          ajax.ajaxing = false;
          if (status === 'error' || status === 'parsererror') {
            return ajax.error(xmlhttprequest, ajax.url);
          }
        },
        dataType: 'json',
        type: 'POST'
      };
  
      if (element_settings.dialog) {
        ajax.options.data.dialogOptions = element_settings.dialog;
      }
  
      // Ensure that we have a valid URL by adding ? when no query parameter is
      // yet available, otherwise append using &.
      if (ajax.options.url.indexOf('?') === -1) {
        ajax.options.url += '?';
      }
      else {
        ajax.options.url += '&';
      }
      ajax.options.url += Drupal.ajax.WRAPPER_FORMAT + '=drupal_' + (element_settings.dialogType || 'ajax');
  
      // Bind the ajaxSubmit function to the element event.
      $(ajax.element).on(element_settings.event, function (event) {
        if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) {
          throw new Error(Drupal.t('The callback URL is not local and not trusted: !url', {'!url': ajax.url}));
        }
        return ajax.eventResponse(this, event);
      });
  
      // If necessary, enable keyboard submission so that Ajax behaviors
      // can be triggered through keyboard input as well as e.g. a mousedown
      // action.
      if (element_settings.keypress) {
        $(ajax.element).on('keypress', function (event) {
          return ajax.keypressResponse(this, event);
        });
      }
  
      // If necessary, prevent the browser default action of an additional event.
      // For example, prevent the browser default action of a click, even if the
      // Ajax behavior binds to mousedown.
      if (element_settings.prevent) {
        $(ajax.element).on(element_settings.prevent, false);
      }
    };
  
    /**
     * URL query attribute to indicate the wrapper used to render a request.
     *
     * The wrapper format determines how the HTML is wrapped, for example in a
     * modal dialog.
     *
     * @const {string}
     *
     * @default
     */
    Drupal.ajax.WRAPPER_FORMAT = '_wrapper_format';
  
    /**
     * Request parameter to indicate that a request is a Drupal Ajax request.
     *
     * @const {string}
     *
     * @default
     */
    Drupal.Ajax.AJAX_REQUEST_PARAMETER = '_drupal_ajax';
  
    /**
     * Execute the ajax request.
     *
     * Allows developers to execute an Ajax request manually without specifying
     * an event to respond to.
     *
     * @return {object}
     *   Returns the jQuery.Deferred object underlying the Ajax request. If
     *   pre-serialization fails, the Deferred will be returned in the rejected
     *   state.
     */
    Drupal.Ajax.prototype.execute = function () {
      // Do not perform another ajax command if one is already in progress.
      if (this.ajaxing) {
        return;
      }
  
      try {
        this.beforeSerialize(this.element, this.options);
        // Return the jqXHR so that external code can hook into the Deferred API.
        return $.ajax(this.options);
      }
      catch (e) {
        // Unset the ajax.ajaxing flag here because it won't be unset during
        // the complete response.
        this.ajaxing = false;
        window.alert('An error occurred while attempting to process ' + this.options.url + ': ' + e.message);
        // For consistency, return a rejected Deferred (i.e., jqXHR's superclass)
        // so that calling code can take appropriate action.
        return $.Deferred().reject();
      }
    };
  
    /**
     * Handle a key press.
     *
     * The Ajax object will, if instructed, bind to a key press response. This
     * will test to see if the key press is valid to trigger this event and
     * if it is, trigger it for us and prevent other keypresses from triggering.
     * In this case we're handling RETURN and SPACEBAR keypresses (event codes 13
     * and 32. RETURN is often used to submit a form when in a textfield, and
     * SPACE is often used to activate an element without submitting.
     *
     * @param {HTMLElement} element
     *   Element the event was triggered on.
     * @param {jQuery.Event} event
     *   Triggered event.
     */
    Drupal.Ajax.prototype.keypressResponse = function (element, event) {
      // Create a synonym for this to reduce code confusion.
      var ajax = this;
  
      // Detect enter key and space bar and allow the standard response for them,
      // except for form elements of type 'text', 'tel', 'number' and 'textarea',
      // where the spacebar activation causes inappropriate activation if
      // #ajax['keypress'] is TRUE. On a text-type widget a space should always
      // be a space.
      if (event.which === 13 || (event.which === 32 && element.type !== 'text' &&
        element.type !== 'textarea' && element.type !== 'tel' && element.type !== 'number')) {
        event.preventDefault();
        event.stopPropagation();
        $(ajax.element_settings.element).trigger(ajax.element_settings.event);
      }
    };
  
    /**
     * Handle an event that triggers an Ajax response.
     *
     * When an event that triggers an Ajax response happens, this method will
     * perform the actual Ajax call. It is bound to the event using
     * bind() in the constructor, and it uses the options specified on the
     * Ajax object.
     *
     * @param {HTMLElement} element
     *   Element the event was triggered on.
     * @param {jQuery.Event} event
     *   Triggered event.
     */
    Drupal.Ajax.prototype.eventResponse = function (element, event) {
      event.preventDefault();
      event.stopPropagation();
  
      // Create a synonym for this to reduce code confusion.
      var ajax = this;
  
      // Do not perform another Ajax command if one is already in progress.
      if (ajax.ajaxing) {
        return;
      }
  
      try {
        if (ajax.$form) {
          // If setClick is set, we must set this to ensure that the button's
          // value is passed.
          if (ajax.setClick) {
            // Mark the clicked button. 'form.clk' is a special variable for
            // ajaxSubmit that tells the system which element got clicked to
            // trigger the submit. Without it there would be no 'op' or
            // equivalent.
            element.form.clk = element;
          }
  
          ajax.$form.ajaxSubmit(ajax.options);
        }
        else {
          ajax.beforeSerialize(ajax.element, ajax.options);
          $.ajax(ajax.options);
        }
      }
      catch (e) {
        // Unset the ajax.ajaxing flag here because it won't be unset during
        // the complete response.
        ajax.ajaxing = false;
        window.alert('An error occurred while attempting to process ' + ajax.options.url + ': ' + e.message);
      }
    };
  
    /**
     * Handler for the form serialization.
     *
     * Runs before the beforeSend() handler (see below), and unlike that one, runs
     * before field data is collected.
     *
     * @param {object} [element]
     *   Ajax object's `element_settings`.
     * @param {object} options
     *   jQuery.ajax options.
     */
    Drupal.Ajax.prototype.beforeSerialize = function (element, options) {
      // Allow detaching behaviors to update field values before collecting them.
      // This is only needed when field values are added to the POST data, so only
      // when there is a form such that this.$form.ajaxSubmit() is used instead of
      // $.ajax(). When there is no form and $.ajax() is used, beforeSerialize()
      // isn't called, but don't rely on that: explicitly check this.$form.
      if (this.$form) {
        var settings = this.settings || drupalSettings;
        Drupal.detachBehaviors(this.$form.get(0), settings, 'serialize');
      }
  
      // Inform Drupal that this is an AJAX request.
      options.data[Drupal.Ajax.AJAX_REQUEST_PARAMETER] = 1;
  
      // Allow Drupal to return new JavaScript and CSS files to load without
      // returning the ones already loaded.
      // @see \Drupal\Core\Theme\AjaxBasePageNegotiator
      // @see \Drupal\Core\Asset\LibraryDependencyResolverInterface::getMinimalRepresentativeSubset()
      // @see system_js_settings_alter()
      var pageState = drupalSettings.ajaxPageState;
      options.data['ajax_page_state[theme]'] = pageState.theme;
      options.data['ajax_page_state[theme_token]'] = pageState.theme_token;
      options.data['ajax_page_state[libraries]'] = pageState.libraries;
    };
  
    /**
     * Modify form values prior to form submission.
     *
     * @param {Array.<object>} form_values
     *   Processed form values.
     * @param {jQuery} element
     *   The form node as a jQuery object.
     * @param {object} options
     *   jQuery.ajax options.
     */
    Drupal.Ajax.prototype.beforeSubmit = function (form_values, element, options) {
      // This function is left empty to make it simple to override for modules
      // that wish to add functionality here.
    };
  
    /**
     * Prepare the Ajax request before it is sent.
     *
     * @param {XMLHttpRequest} xmlhttprequest
     *   Native Ajax object.
     * @param {object} options
     *   jQuery.ajax options.
     */
    Drupal.Ajax.prototype.beforeSend = function (xmlhttprequest, options) {
      // For forms without file inputs, the jQuery Form plugin serializes the
      // form values, and then calls jQuery's $.ajax() function, which invokes
      // this handler. In this circumstance, options.extraData is never used. For
      // forms with file inputs, the jQuery Form plugin uses the browser's normal
      // form submission mechanism, but captures the response in a hidden IFRAME.
      // In this circumstance, it calls this handler first, and then appends
      // hidden fields to the form to submit the values in options.extraData.
      // There is no simple way to know which submission mechanism will be used,
      // so we add to extraData regardless, and allow it to be ignored in the
      // former case.
      if (this.$form) {
        options.extraData = options.extraData || {};
  
        // Let the server know when the IFRAME submission mechanism is used. The
        // server can use this information to wrap the JSON response in a
        // TEXTAREA, as per http://jquery.malsup.com/form/#file-upload.
        options.extraData.ajax_iframe_upload = '1';
  
        // The triggering element is about to be disabled (see below), but if it
        // contains a value (e.g., a checkbox, textfield, select, etc.), ensure
        // that value is included in the submission. As per above, submissions
        // that use $.ajax() are already serialized prior to the element being
        // disabled, so this is only needed for IFRAME submissions.
        var v = $.fieldValue(this.element);
        if (v !== null) {
          options.extraData[this.element.name] = v;
        }
      }
  
      // Disable the element that received the change to prevent user interface
      // interaction while the Ajax request is in progress. ajax.ajaxing prevents
      // the element from triggering a new request, but does not prevent the user
      // from changing its value.
      $(this.element).prop('disabled', true);
  
      if (!this.progress || !this.progress.type) {
        return;
      }
  
      // Insert progress indicator.
      var progressIndicatorMethod = 'setProgressIndicator' + this.progress.type.slice(0, 1).toUpperCase() + this.progress.type.slice(1).toLowerCase();
      if (progressIndicatorMethod in this && typeof this[progressIndicatorMethod] === 'function') {
        this[progressIndicatorMethod].call(this);
      }
    };
  
    /**
     * Sets the progress bar progress indicator.
     */
    Drupal.Ajax.prototype.setProgressIndicatorBar = function () {
      var progressBar = new Drupal.ProgressBar('ajax-progress-' + this.element.id, $.noop, this.progress.method, $.noop);
      if (this.progress.message) {
        progressBar.setProgress(-1, this.progress.message);
      }
      if (this.progress.url) {
        progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500);
      }
      this.progress.element = $(progressBar.element).addClass('ajax-progress ajax-progress-bar');
      this.progress.object = progressBar;
      $(this.element).after(this.progress.element);
    };
  
    /**
     * Sets the throbber progress indicator.
     */
    Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () {
      this.progress.element = $('<div class="ajax-progress ajax-progress-throbber"><div class="throbber">&nbsp;</div></div>');
      if (this.progress.message) {
        this.progress.element.find('.throbber').after('<div class="message">' + this.progress.message + '</div>');
      }
      $(this.element).after(this.progress.element);
    };
  
    /**
     * Sets the fullscreen progress indicator.
     */
    Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () {
      this.progress.element = $('<div class="ajax-progress ajax-progress-fullscreen">&nbsp;</div>');
      $('body').after(this.progress.element);
    };
  
    /**
     * Handler for the form redirection completion.
     *
     * @param {Array.<Drupal.AjaxCommands~commandDefinition>} response
     *   Drupal Ajax response.
     * @param {number} status
     *   XMLHttpRequest status.
     */
    Drupal.Ajax.prototype.success = function (response, status) {
      // Remove the progress element.
      if (this.progress.element) {
        $(this.progress.element).remove();
      }
      if (this.progress.object) {
        this.progress.object.stopMonitoring();
      }
      $(this.element).prop('disabled', false);
  
      // Save element's ancestors tree so if the element is removed from the dom
      // we can try to refocus one of its parents. Using addBack reverse the
      // result array, meaning that index 0 is the highest parent in the hierarchy
      // in this situation it is usually a <form> element.
      var elementParents = $(this.element).parents('[data-drupal-selector]').addBack().toArray();
  
      // Track if any command is altering the focus so we can avoid changing the
      // focus set by the Ajax command.
      var focusChanged = false;
      for (var i in response) {
        if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) {
          this.commands[response[i].command](this, response[i], status);
          if (response[i].command === 'invoke' && response[i].method === 'focus') {
            focusChanged = true;
          }
        }
      }
  
      // If the focus hasn't be changed by the ajax commands, try to refocus the
      // triggering element or one of its parents if that element does not exist
      // anymore.
      if (!focusChanged && this.element && !$(this.element).data('disable-refocus')) {
        var target = false;
  
        for (var n = elementParents.length - 1; !target && n > 0; n--) {
          target = document.querySelector('[data-drupal-selector="' + elementParents[n].getAttribute('data-drupal-selector') + '"]');
        }
  
        if (target) {
          $(target).trigger('focus');
        }
      }
  
      // Reattach behaviors, if they were detached in beforeSerialize(). The
      // attachBehaviors() called on the new content from processing the response
      // commands is not sufficient, because behaviors from the entire form need
      // to be reattached.
      if (this.$form) {
        var settings = this.settings || drupalSettings;
        Drupal.attachBehaviors(this.$form.get(0), settings);
      }
  
      // Remove any response-specific settings so they don't get used on the next
      // call by mistake.
      this.settings = null;
    };
  
    /**
     * Build an effect object to apply an effect when adding new HTML.
     *
     * @param {object} response
     *   Drupal Ajax response.
     * @param {string} [response.effect]
     *   Override the default value of {@link Drupal.Ajax#element_settings}.
     * @param {string|number} [response.speed]
     *   Override the default value of {@link Drupal.Ajax#element_settings}.
     *
     * @return {object}
     *   Returns an object with `showEffect`, `hideEffect` and `showSpeed`
     *   properties.
     */
    Drupal.Ajax.prototype.getEffect = function (response) {
      var type = response.effect || this.effect;
      var speed = response.speed || this.speed;
  
      var effect = {};
      if (type === 'none') {
        effect.showEffect = 'show';
        effect.hideEffect = 'hide';
        effect.showSpeed = '';
      }
      else if (type === 'fade') {
        effect.showEffect = 'fadeIn';
        effect.hideEffect = 'fadeOut';
        effect.showSpeed = speed;
      }
      else {
        effect.showEffect = type + 'Toggle';
        effect.hideEffect = type + 'Toggle';
        effect.showSpeed = speed;
      }
  
      return effect;
    };
  
    /**
     * Handler for the form redirection error.
     *
     * @param {object} xmlhttprequest
     *   Native XMLHttpRequest object.
     * @param {string} uri
     *   Ajax Request URI.
     * @param {string} [customMessage]
     *   Extra message to print with the Ajax error.
     */
    Drupal.Ajax.prototype.error = function (xmlhttprequest, uri, customMessage) {
      // Remove the progress element.
      if (this.progress.element) {
        $(this.progress.element).remove();
      }
      if (this.progress.object) {
        this.progress.object.stopMonitoring();
      }
      // Undo hide.
      $(this.wrapper).show();
      // Re-enable the element.
      $(this.element).prop('disabled', false);
      // Reattach behaviors, if they were detached in beforeSerialize().
      if (this.$form) {
        var settings = this.settings || drupalSettings;
        Drupal.attachBehaviors(this.$form.get(0), settings);
      }
      throw new Drupal.AjaxError(xmlhttprequest, uri, customMessage);
    };
  
    /**
     * @typedef {object} Drupal.AjaxCommands~commandDefinition
     *
     * @prop {string} command
     * @prop {string} [method]
     * @prop {string} [selector]
     * @prop {string} [data]
     * @prop {object} [settings]
     * @prop {bool} [asterisk]
     * @prop {string} [text]
     * @prop {string} [title]
     * @prop {string} [url]
     * @prop {object} [argument]
     * @prop {string} [name]
     * @prop {string} [value]
     * @prop {string} [old]
     * @prop {string} [new]
     * @prop {bool} [merge]
     * @prop {Array} [args]
     *
     * @see Drupal.AjaxCommands
     */
  
    /**
     * Provide a series of commands that the client will perform.
     *
     * @constructor
     */
    Drupal.AjaxCommands = function () {};
    Drupal.AjaxCommands.prototype = {
  
      /**
       * Command to insert new content into the DOM.
       *
       * @param {Drupal.Ajax} ajax
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.data
       *   The data to use with the jQuery method.
       * @param {string} [response.method]
       *   The jQuery DOM manipulation method to be used.
       * @param {string} [response.selector]
       *   A optional jQuery selector string.
       * @param {object} [response.settings]
       *   An optional array of settings that will be used.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      insert: function (ajax, response, status) {
        // Get information from the response. If it is not there, default to
        // our presets.
        var $wrapper = response.selector ? $(response.selector) : $(ajax.wrapper);
        var method = response.method || ajax.method;
        var effect = ajax.getEffect(response);
        var settings;
  
        // We don't know what response.data contains: it might be a string of text
        // without HTML, so don't rely on jQuery correctly interpreting
        // $(response.data) as new HTML rather than a CSS selector. Also, if
        // response.data contains top-level text nodes, they get lost with either
        // $(response.data) or $('<div></div>').replaceWith(response.data).
        var $new_content_wrapped = $('<div></div>').html(response.data);
        var $new_content = $new_content_wrapped.contents();
  
        // For legacy reasons, the effects processing code assumes that
        // $new_content consists of a single top-level element. Also, it has not
        // been sufficiently tested whether attachBehaviors() can be successfully
        // called with a context object that includes top-level text nodes.
        // However, to give developers full control of the HTML appearing in the
        // page, and to enable Ajax content to be inserted in places where <div>
        // elements are not allowed (e.g., within <table>, <tr>, and <span>
        // parents), we check if the new content satisfies the requirement
        // of a single top-level element, and only use the container <div> created
        // above when it doesn't. For more information, please see
        // https://www.drupal.org/node/736066.
        if ($new_content.length !== 1 || $new_content.get(0).nodeType !== 1) {
          $new_content = $new_content_wrapped;
        }
  
        // If removing content from the wrapper, detach behaviors first.
        switch (method) {
          case 'html':
          case 'replaceWith':
          case 'replaceAll':
          case 'empty':
          case 'remove':
            settings = response.settings || ajax.settings || drupalSettings;
            Drupal.detachBehaviors($wrapper.get(0), settings);
        }
  
        // Add the new content to the page.
        $wrapper[method]($new_content);
  
        // Immediately hide the new content if we're using any effects.
        if (effect.showEffect !== 'show') {
          $new_content.hide();
        }
  
        // Determine which effect to use and what content will receive the
        // effect, then show the new content.
        if ($new_content.find('.ajax-new-content').length > 0) {
          $new_content.find('.ajax-new-content').hide();
          $new_content.show();
          $new_content.find('.ajax-new-content')[effect.showEffect](effect.showSpeed);
        }
        else if (effect.showEffect !== 'show') {
          $new_content[effect.showEffect](effect.showSpeed);
        }
  
        // Attach all JavaScript behaviors to the new content, if it was
        // successfully added to the page, this if statement allows
        // `#ajax['wrapper']` to be optional.
        if ($new_content.parents('html').length > 0) {
          // Apply any settings from the returned JSON if available.
          settings = response.settings || ajax.settings || drupalSettings;
          Drupal.attachBehaviors($new_content.get(0), settings);
        }
      },
  
      /**
       * Command to remove a chunk from the page.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.selector
       *   A jQuery selector string.
       * @param {object} [response.settings]
       *   An optional array of settings that will be used.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      remove: function (ajax, response, status) {
        var settings = response.settings || ajax.settings || drupalSettings;
        $(response.selector).each(function () {
          Drupal.detachBehaviors(this, settings);
        })
          .remove();
      },
  
      /**
       * Command to mark a chunk changed.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The JSON response object from the Ajax request.
       * @param {string} response.selector
       *   A jQuery selector string.
       * @param {bool} [response.asterisk]
       *   An optional CSS selector. If specified, an asterisk will be
       *   appended to the HTML inside the provided selector.
       * @param {number} [status]
       *   The request status.
       */
      changed: function (ajax, response, status) {
        var $element = $(response.selector);
        if (!$element.hasClass('ajax-changed')) {
          $element.addClass('ajax-changed');
          if (response.asterisk) {
            $element.find(response.asterisk).append(' <abbr class="ajax-changed" title="' + Drupal.t('Changed') + '">*</abbr> ');
          }
        }
      },
  
      /**
       * Command to provide an alert.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The JSON response from the Ajax request.
       * @param {string} response.text
       *   The text that will be displayed in an alert dialog.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      alert: function (ajax, response, status) {
        window.alert(response.text, response.title);
      },
  
      /**
       * Command to set the window.location, redirecting the browser.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.url
       *   The URL to redirect to.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      redirect: function (ajax, response, status) {
        window.location = response.url;
      },
  
      /**
       * Command to provide the jQuery css() function.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.selector
       *   A jQuery selector string.
       * @param {object} response.argument
       *   An array of key/value pairs to set in the CSS for the selector.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      css: function (ajax, response, status) {
        $(response.selector).css(response.argument);
      },
  
      /**
       * Command to set the settings used for other commands in this response.
       *
       * This method will also remove expired `drupalSettings.ajax` settings.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {bool} response.merge
       *   Determines whether the additional settings should be merged to the
       *   global settings.
       * @param {object} response.settings
       *   Contains additional settings to add to the global settings.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      settings: function (ajax, response, status) {
        var ajaxSettings = drupalSettings.ajax;
  
        // Clean up drupalSettings.ajax.
        if (ajaxSettings) {
          Drupal.ajax.expired().forEach(function (instance) {
            // If the Ajax object has been created through drupalSettings.ajax
            // it will have a selector. When there is no selector the object
            // has been initialized with a special class name picked up by the
            // Ajax behavior.
  
            if (instance.selector) {
              var selector = instance.selector.replace('#', '');
              if (selector in ajaxSettings) {
                delete ajaxSettings[selector];
              }
            }
          });
        }
  
        if (response.merge) {
          $.extend(true, drupalSettings, response.settings);
        }
        else {
          ajax.settings = response.settings;
        }
      },
  
      /**
       * Command to attach data using jQuery's data API.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.name
       *   The name or key (in the key value pair) of the data attached to this
       *   selector.
       * @param {string} response.selector
       *   A jQuery selector string.
       * @param {string|object} response.value
       *   The value of to be attached.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      data: function (ajax, response, status) {
        $(response.selector).data(response.name, response.value);
      },
  
      /**
       * Command to apply a jQuery method.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {Array} response.args
       *   An array of arguments to the jQuery method, if any.
       * @param {string} response.method
       *   The jQuery method to invoke.
       * @param {string} response.selector
       *   A jQuery selector string.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      invoke: function (ajax, response, status) {
        var $element = $(response.selector);
        $element[response.method].apply($element, response.args);
      },
  
      /**
       * Command to restripe a table.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.selector
       *   A jQuery selector string.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      restripe: function (ajax, response, status) {
        // :even and :odd are reversed because jQuery counts from 0 and
        // we count from 1, so we're out of sync.
        // Match immediate children of the parent element to allow nesting.
        $(response.selector).find('> tbody > tr:visible, > tr:visible')
          .removeClass('odd even')
          .filter(':even').addClass('odd').end()
          .filter(':odd').addClass('even');
      },
  
      /**
       * Command to update a form's build ID.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.old
       *   The old form build ID.
       * @param {string} response.new
       *   The new form build ID.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      update_build_id: function (ajax, response, status) {
        $('input[name="form_build_id"][value="' + response.old + '"]').val(response.new);
      },
  
      /**
       * Command to add css.
       *
       * Uses the proprietary addImport method if available as browsers which
       * support that method ignore @import statements in dynamically added
       * stylesheets.
       *
       * @param {Drupal.Ajax} [ajax]
       *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
       * @param {object} response
       *   The response from the Ajax request.
       * @param {string} response.data
       *   A string that contains the styles to be added.
       * @param {number} [status]
       *   The XMLHttpRequest status.
       */
      add_css: function (ajax, response, status) {
        // Add the styles in the normal way.
        $('head').prepend(response.data);
        // Add imports in the styles using the addImport method if available.
        var match;
        var importMatch = /^@import url\("(.*)"\);$/igm;
        if (document.styleSheets[0].addImport && importMatch.test(response.data)) {
          importMatch.lastIndex = 0;
          do {
            match = importMatch.exec(response.data);
            document.styleSheets[0].addImport(match[1]);
          } while (match);
        }
      }
    };
  
  })(jQuery, window, Drupal, drupalSettings);
  ;
  /**
   * @file
   * Adds an HTML element and method to trigger audio UAs to read system messages.
   *
   * Use {@link Drupal.announce} to indicate to screen reader users that an
   * element on the page has changed state. For instance, if clicking a link
   * loads 10 more items into a list, one might announce the change like this.
   *
   * @example
   * $('#search-list')
   *   .on('itemInsert', function (event, data) {
   *     // Insert the new items.
   *     $(data.container.el).append(data.items.el);
   *     // Announce the change to the page contents.
   *     Drupal.announce(Drupal.t('@count items added to @container',
   *       {'@count': data.items.length, '@container': data.container.title}
   *     ));
   *   });
   */
  
  (function (Drupal, debounce) {
  
    'use strict';
  
    var liveElement;
    var announcements = [];
  
    /**
     * Builds a div element with the aria-live attribute and add it to the DOM.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the behavior for drupalAnnouce.
     */
    Drupal.behaviors.drupalAnnounce = {
      attach: function (context) {
        // Create only one aria-live element.
        if (!liveElement) {
          liveElement = document.createElement('div');
          liveElement.id = 'drupal-live-announce';
          liveElement.className = 'visually-hidden';
          liveElement.setAttribute('aria-live', 'polite');
          liveElement.setAttribute('aria-busy', 'false');
          document.body.appendChild(liveElement);
        }
      }
    };
  
    /**
     * Concatenates announcements to a single string; appends to the live region.
     */
    function announce() {
      var text = [];
      var priority = 'polite';
      var announcement;
  
      // Create an array of announcement strings to be joined and appended to the
      // aria live region.
      var il = announcements.length;
      for (var i = 0; i < il; i++) {
        announcement = announcements.pop();
        text.unshift(announcement.text);
        // If any of the announcements has a priority of assertive then the group
        // of joined announcements will have this priority.
        if (announcement.priority === 'assertive') {
          priority = 'assertive';
        }
      }
  
      if (text.length) {
        // Clear the liveElement so that repeated strings will be read.
        liveElement.innerHTML = '';
        // Set the busy state to true until the node changes are complete.
        liveElement.setAttribute('aria-busy', 'true');
        // Set the priority to assertive, or default to polite.
        liveElement.setAttribute('aria-live', priority);
        // Print the text to the live region. Text should be run through
        // Drupal.t() before being passed to Drupal.announce().
        liveElement.innerHTML = text.join('\n');
        // The live text area is updated. Allow the AT to announce the text.
        liveElement.setAttribute('aria-busy', 'false');
      }
    }
  
    /**
     * Triggers audio UAs to read the supplied text.
     *
     * The aria-live region will only read the text that currently populates its
     * text node. Replacing text quickly in rapid calls to announce results in
     * only the text from the most recent call to {@link Drupal.announce} being
     * read. By wrapping the call to announce in a debounce function, we allow for
     * time for multiple calls to {@link Drupal.announce} to queue up their
     * messages. These messages are then joined and append to the aria-live region
     * as one text node.
     *
     * @param {string} text
     *   A string to be read by the UA.
     * @param {string} [priority='polite']
     *   A string to indicate the priority of the message. Can be either
     *   'polite' or 'assertive'.
     *
     * @return {function}
     *   The return of the call to debounce.
     *
     * @see http://www.w3.org/WAI/PF/aria-practices/#liveprops
     */
    Drupal.announce = function (text, priority) {
      // Save the text and priority into a closure variable. Multiple simultaneous
      // announcements will be concatenated and read in sequence.
      announcements.push({
        text: text,
        priority: priority
      });
      // Immediately invoke the function that debounce returns. 200 ms is right at
      // the cusp where humans notice a pause, so we will wait
      // at most this much time before the set of queued announcements is read.
      return (debounce(announce, 200)());
    };
  }(Drupal, Drupal.debounce));
  ;
  (function(){if(window.matchMedia&&window.matchMedia("all").addListener){return false}var e=window.matchMedia,i=e("only all").matches,n=false,t=0,a=[],r=function(i){clearTimeout(t);t=setTimeout(function(){for(var i=0,n=a.length;i<n;i++){var t=a[i].mql,r=a[i].listeners||[],o=e(t.media).matches;if(o!==t.matches){t.matches=o;for(var s=0,l=r.length;s<l;s++){r[s].call(window,t)}}}},30)};window.matchMedia=function(t){var o=e(t),s=[],l=0;o.addListener=function(e){if(!i){return}if(!n){n=true;window.addEventListener("resize",r,true)}if(l===0){l=a.push({mql:o,listeners:s})}s.push(e)};o.removeListener=function(e){for(var i=0,n=s.length;i<n;i++){if(s[i]===e){s.splice(i,1)}}};return o}})();
  ;
  /**
   * @file
   * Manages elements that can offset the size of the viewport.
   *
   * Measures and reports viewport offset dimensions from elements like the
   * toolbar that can potentially displace the positioning of other elements.
   */
  
  /**
   * @typedef {object} Drupal~displaceOffset
   *
   * @prop {number} top
   * @prop {number} left
   * @prop {number} right
   * @prop {number} bottom
   */
  
  /**
   * Triggers when layout of the page changes.
   *
   * This is used to position fixed element on the page during page resize and
   * Toolbar toggling.
   *
   * @event drupalViewportOffsetChange
   */
  
  (function ($, Drupal, debounce) {
  
    'use strict';
  
    /**
     * @name Drupal.displace.offsets
     *
     * @type {Drupal~displaceOffset}
     */
    var offsets = {
      top: 0,
      right: 0,
      bottom: 0,
      left: 0
    };
  
    /**
     * Registers a resize handler on the window.
     *
     * @type {Drupal~behavior}
     */
    Drupal.behaviors.drupalDisplace = {
      attach: function () {
        // Mark this behavior as processed on the first pass.
        if (this.displaceProcessed) {
          return;
        }
        this.displaceProcessed = true;
  
        $(window).on('resize.drupalDisplace', debounce(displace, 200));
      }
    };
  
    /**
     * Informs listeners of the current offset dimensions.
     *
     * @function Drupal.displace
     *
     * @prop {Drupal~displaceOffset} offsets
     *
     * @param {bool} [broadcast]
     *   When true or undefined, causes the recalculated offsets values to be
     *   broadcast to listeners.
     *
     * @return {Drupal~displaceOffset}
     *   An object whose keys are the for sides an element -- top, right, bottom
     *   and left. The value of each key is the viewport displacement distance for
     *   that edge.
     *
     * @fires event:drupalViewportOffsetChange
     */
    function displace(broadcast) {
      offsets = Drupal.displace.offsets = calculateOffsets();
      if (typeof broadcast === 'undefined' || broadcast) {
        $(document).trigger('drupalViewportOffsetChange', offsets);
      }
      return offsets;
    }
  
    /**
     * Determines the viewport offsets.
     *
     * @return {Drupal~displaceOffset}
     *   An object whose keys are the for sides an element -- top, right, bottom
     *   and left. The value of each key is the viewport displacement distance for
     *   that edge.
     */
    function calculateOffsets() {
      return {
        top: calculateOffset('top'),
        right: calculateOffset('right'),
        bottom: calculateOffset('bottom'),
        left: calculateOffset('left')
      };
    }
  
    /**
     * Gets a specific edge's offset.
     *
     * Any element with the attribute data-offset-{edge} e.g. data-offset-top will
     * be considered in the viewport offset calculations. If the attribute has a
     * numeric value, that value will be used. If no value is provided, one will
     * be calculated using the element's dimensions and placement.
     *
     * @function Drupal.displace.calculateOffset
     *
     * @param {string} edge
     *   The name of the edge to calculate. Can be 'top', 'right',
     *   'bottom' or 'left'.
     *
     * @return {number}
     *   The viewport displacement distance for the requested edge.
     */
    function calculateOffset(edge) {
      var edgeOffset = 0;
      var displacingElements = document.querySelectorAll('[data-offset-' + edge + ']');
      var n = displacingElements.length;
      for (var i = 0; i < n; i++) {
        var el = displacingElements[i];
        // If the element is not visible, do consider its dimensions.
        if (el.style.display === 'none') {
          continue;
        }
        // If the offset data attribute contains a displacing value, use it.
        var displacement = parseInt(el.getAttribute('data-offset-' + edge), 10);
        // If the element's offset data attribute exits
        // but is not a valid number then get the displacement
        // dimensions directly from the element.
        if (isNaN(displacement)) {
          displacement = getRawOffset(el, edge);
        }
        // If the displacement value is larger than the current value for this
        // edge, use the displacement value.
        edgeOffset = Math.max(edgeOffset, displacement);
      }
  
      return edgeOffset;
    }
  
    /**
     * Calculates displacement for element based on its dimensions and placement.
     *
     * @param {HTMLElement} el
     *   The jQuery element whose dimensions and placement will be measured.
     *
     * @param {string} edge
     *   The name of the edge of the viewport that the element is associated
     *   with.
     *
     * @return {number}
     *   The viewport displacement distance for the requested edge.
     */
    function getRawOffset(el, edge) {
      var $el = $(el);
      var documentElement = document.documentElement;
      var displacement = 0;
      var horizontal = (edge === 'left' || edge === 'right');
      // Get the offset of the element itself.
      var placement = $el.offset()[horizontal ? 'left' : 'top'];
      // Subtract scroll distance from placement to get the distance
      // to the edge of the viewport.
      placement -= window['scroll' + (horizontal ? 'X' : 'Y')] || document.documentElement['scroll' + (horizontal ? 'Left' : 'Top')] || 0;
      // Find the displacement value according to the edge.
      switch (edge) {
        // Left and top elements displace as a sum of their own offset value
        // plus their size.
        case 'top':
          // Total displacement is the sum of the elements placement and size.
          displacement = placement + $el.outerHeight();
          break;
  
        case 'left':
          // Total displacement is the sum of the elements placement and size.
          displacement = placement + $el.outerWidth();
          break;
  
        // Right and bottom elements displace according to their left and
        // top offset. Their size isn't important.
        case 'bottom':
          displacement = documentElement.clientHeight - placement;
          break;
  
        case 'right':
          displacement = documentElement.clientWidth - placement;
          break;
  
        default:
          displacement = 0;
      }
      return displacement;
    }
  
    /**
     * Assign the displace function to a property of the Drupal global object.
     *
     * @ignore
     */
    Drupal.displace = displace;
    $.extend(Drupal.displace, {
  
      /**
       * Expose offsets to other scripts to avoid having to recalculate offsets.
       *
       * @ignore
       */
      offsets: offsets,
  
      /**
       * Expose method to compute a single edge offsets.
       *
       * @ignore
       */
      calculateOffset: calculateOffset
    });
  
  })(jQuery, Drupal, Drupal.debounce);
  ;
  /**
   * @file
   * Builds a nested accordion widget.
   *
   * Invoke on an HTML list element with the jQuery plugin pattern.
   *
   * @example
   * $('.toolbar-menu').drupalToolbarMenu();
   */
  
  (function ($, Drupal, drupalSettings) {
  
    'use strict';
  
    /**
     * Store the open menu tray.
     */
    var activeItem = Drupal.url(drupalSettings.path.currentPath);
  
    $.fn.drupalToolbarMenu = function () {
  
      var ui = {
        handleOpen: Drupal.t('Extend'),
        handleClose: Drupal.t('Collapse')
      };
  
      /**
       * Handle clicks from the disclosure button on an item with sub-items.
       *
       * @param {Object} event
       *   A jQuery Event object.
       */
      function toggleClickHandler(event) {
        var $toggle = $(event.target);
        var $item = $toggle.closest('li');
        // Toggle the list item.
        toggleList($item);
        // Close open sibling menus.
        var $openItems = $item.siblings().filter('.open');
        toggleList($openItems, false);
      }
  
      /**
       * Handle clicks from a menu item link.
       *
       * @param {Object} event
       *   A jQuery Event object.
       */
      function linkClickHandler(event) {
        // If the toolbar is positioned fixed (and therefore hiding content
        // underneath), then users expect clicks in the administration menu tray
        // to take them to that destination but for the menu tray to be closed
        // after clicking: otherwise the toolbar itself is obstructing the view
        // of the destination they chose.
        if (!Drupal.toolbar.models.toolbarModel.get('isFixed')) {
          Drupal.toolbar.models.toolbarModel.set('activeTab', null);
        }
        // Stopping propagation to make sure that once a toolbar-box is clicked
        // (the whitespace part), the page is not redirected anymore.
        event.stopPropagation();
      }
  
      /**
       * Toggle the open/close state of a list is a menu.
       *
       * @param {jQuery} $item
       *   The li item to be toggled.
       *
       * @param {Boolean} switcher
       *   A flag that forces toggleClass to add or a remove a class, rather than
       *   simply toggling its presence.
       */
      function toggleList($item, switcher) {
        var $toggle = $item.children('.toolbar-box').children('.toolbar-handle');
        switcher = (typeof switcher !== 'undefined') ? switcher : !$item.hasClass('open');
        // Toggle the item open state.
        $item.toggleClass('open', switcher);
        // Twist the toggle.
        $toggle.toggleClass('open', switcher);
        // Adjust the toggle text.
        $toggle
          .find('.action')
          // Expand Structure, Collapse Structure.
          .text((switcher) ? ui.handleClose : ui.handleOpen);
      }
  
      /**
       * Add markup to the menu elements.
       *
       * Items with sub-elements have a list toggle attached to them. Menu item
       * links and the corresponding list toggle are wrapped with in a div
       * classed with .toolbar-box. The .toolbar-box div provides a positioning
       * context for the item list toggle.
       *
       * @param {jQuery} $menu
       *   The root of the menu to be initialized.
       */
      function initItems($menu) {
        var options = {
          class: 'toolbar-icon toolbar-handle',
          action: ui.handleOpen,
          text: ''
        };
        // Initialize items and their links.
        $menu.find('li > a').wrap('<div class="toolbar-box">');
        // Add a handle to each list item if it has a menu.
        $menu.find('li').each(function (index, element) {
          var $item = $(element);
          if ($item.children('ul.toolbar-menu').length) {
            var $box = $item.children('.toolbar-box');
            options.text = Drupal.t('@label', {'@label': $box.find('a').text()});
            $item.children('.toolbar-box')
              .append(Drupal.theme('toolbarMenuItemToggle', options));
          }
        });
      }
  
      /**
       * Adds a level class to each list based on its depth in the menu.
       *
       * This function is called recursively on each sub level of lists elements
       * until the depth of the menu is exhausted.
       *
       * @param {jQuery} $lists
       *   A jQuery object of ul elements.
       *
       * @param {number} level
       *   The current level number to be assigned to the list elements.
       */
      function markListLevels($lists, level) {
        level = (!level) ? 1 : level;
        var $lis = $lists.children('li').addClass('level-' + level);
        $lists = $lis.children('ul');
        if ($lists.length) {
          markListLevels($lists, level + 1);
        }
      }
  
      /**
       * On page load, open the active menu item.
       *
       * Marks the trail of the active link in the menu back to the root of the
       * menu with .menu-item--active-trail.
       *
       * @param {jQuery} $menu
       *   The root of the menu.
       */
      function openActiveItem($menu) {
        var pathItem = $menu.find('a[href="' + location.pathname + '"]');
        if (pathItem.length && !activeItem) {
          activeItem = location.pathname;
        }
        if (activeItem) {
          var $activeItem = $menu.find('a[href="' + activeItem + '"]').addClass('menu-item--active');
          var $activeTrail = $activeItem.parentsUntil('.root', 'li').addClass('menu-item--active-trail');
          toggleList($activeTrail, true);
        }
      }
  
      // Return the jQuery object.
      return this.each(function (selector) {
        var $menu = $(this).once('toolbar-menu');
        if ($menu.length) {
          // Bind event handlers.
          $menu
            .on('click.toolbar', '.toolbar-box', toggleClickHandler)
            .on('click.toolbar', '.toolbar-box a', linkClickHandler);
  
          $menu.addClass('root');
          initItems($menu);
          markListLevels($menu);
          // Restore previous and active states.
          openActiveItem($menu);
        }
      });
    };
  
    /**
     * A toggle is an interactive element often bound to a click handler.
     *
     * @param {object} options
     *   Options for the button.
     * @param {string} options.class
     *   Class to set on the button.
     * @param {string} options.action
     *   Action for the button.
     * @param {string} options.text
     *   Used as label for the button.
     *
     * @return {string}
     *   A string representing a DOM fragment.
     */
    Drupal.theme.toolbarMenuItemToggle = function (options) {
      return '<button class="' + options['class'] + '"><span class="action">' + options.action + '</span><span class="label">' + options.text + '</span></button>';
    };
  
  }(jQuery, Drupal, drupalSettings));
  ;
  /**
   * @file
   * Defines the behavior of the Drupal administration toolbar.
   */
  
  (function ($, Drupal, drupalSettings) {
  
    'use strict';
  
    // Merge run-time settings with the defaults.
    var options = $.extend(
      {
        breakpoints: {
          'toolbar.narrow': '',
          'toolbar.standard': '',
          'toolbar.wide': ''
        }
      },
      drupalSettings.toolbar,
      // Merge strings on top of drupalSettings so that they are not mutable.
      {
        strings: {
          horizontal: Drupal.t('Horizontal orientation'),
          vertical: Drupal.t('Vertical orientation')
        }
      }
    );
  
    /**
     * Registers tabs with the toolbar.
     *
     * The Drupal toolbar allows modules to register top-level tabs. These may
     * point directly to a resource or toggle the visibility of a tray.
     *
     * Modules register tabs with hook_toolbar().
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the toolbar rendering functionality to the toolbar element.
     */
    Drupal.behaviors.toolbar = {
      attach: function (context) {
        // Verify that the user agent understands media queries. Complex admin
        // toolbar layouts require media query support.
        if (!window.matchMedia('only screen').matches) {
          return;
        }
        // Process the administrative toolbar.
        $(context).find('#toolbar-administration').once('toolbar').each(function () {
  
          // Establish the toolbar models and views.
          var model = Drupal.toolbar.models.toolbarModel = new Drupal.toolbar.ToolbarModel({
            locked: JSON.parse(localStorage.getItem('Drupal.toolbar.trayVerticalLocked')) || false,
            activeTab: document.getElementById(JSON.parse(localStorage.getItem('Drupal.toolbar.activeTabID')))
          });
          Drupal.toolbar.views.toolbarVisualView = new Drupal.toolbar.ToolbarVisualView({
            el: this,
            model: model,
            strings: options.strings
          });
          Drupal.toolbar.views.toolbarAuralView = new Drupal.toolbar.ToolbarAuralView({
            el: this,
            model: model,
            strings: options.strings
          });
          Drupal.toolbar.views.bodyVisualView = new Drupal.toolbar.BodyVisualView({
            el: this,
            model: model
          });
  
          // Render collapsible menus.
          var menuModel = Drupal.toolbar.models.menuModel = new Drupal.toolbar.MenuModel();
          Drupal.toolbar.views.menuVisualView = new Drupal.toolbar.MenuVisualView({
            el: $(this).find('.toolbar-menu-administration').get(0),
            model: menuModel,
            strings: options.strings
          });
  
          // Handle the resolution of Drupal.toolbar.setSubtrees.
          // This is handled with a deferred so that the function may be invoked
          // asynchronously.
          Drupal.toolbar.setSubtrees.done(function (subtrees) {
            menuModel.set('subtrees', subtrees);
            var theme = drupalSettings.ajaxPageState.theme;
            localStorage.setItem('Drupal.toolbar.subtrees.' + theme, JSON.stringify(subtrees));
            // Indicate on the toolbarModel that subtrees are now loaded.
            model.set('areSubtreesLoaded', true);
          });
  
          // Attach a listener to the configured media query breakpoints.
          for (var label in options.breakpoints) {
            if (options.breakpoints.hasOwnProperty(label)) {
              var mq = options.breakpoints[label];
              var mql = Drupal.toolbar.mql[label] = window.matchMedia(mq);
              // Curry the model and the label of the media query breakpoint to
              // the mediaQueryChangeHandler function.
              mql.addListener(Drupal.toolbar.mediaQueryChangeHandler.bind(null, model, label));
              // Fire the mediaQueryChangeHandler for each configured breakpoint
              // so that they process once.
              Drupal.toolbar.mediaQueryChangeHandler.call(null, model, label, mql);
            }
          }
  
          // Trigger an initial attempt to load menu subitems. This first attempt
          // is made after the media query handlers have had an opportunity to
          // process. The toolbar starts in the vertical orientation by default,
          // unless the viewport is wide enough to accommodate a horizontal
          // orientation. Thus we give the Toolbar a chance to determine if it
          // should be set to horizontal orientation before attempting to load
          // menu subtrees.
          Drupal.toolbar.views.toolbarVisualView.loadSubtrees();
  
          $(document)
            // Update the model when the viewport offset changes.
            .on('drupalViewportOffsetChange.toolbar', function (event, offsets) {
              model.set('offsets', offsets);
            });
  
          // Broadcast model changes to other modules.
          model
            .on('change:orientation', function (model, orientation) {
              $(document).trigger('drupalToolbarOrientationChange', orientation);
            })
            .on('change:activeTab', function (model, tab) {
              $(document).trigger('drupalToolbarTabChange', tab);
            })
            .on('change:activeTray', function (model, tray) {
              $(document).trigger('drupalToolbarTrayChange', tray);
            });
  
          // If the toolbar's orientation is horizontal and no active tab is
          // defined then show the tray of the first toolbar tab by default (but
          // not the first 'Home' toolbar tab).
          if (Drupal.toolbar.models.toolbarModel.get('orientation') === 'horizontal' && Drupal.toolbar.models.toolbarModel.get('activeTab') === null) {
            Drupal.toolbar.models.toolbarModel.set({
              activeTab: $('.toolbar-bar .toolbar-tab:not(.home-toolbar-tab) a').get(0)
            });
          }
        });
      }
    };
  
    /**
     * Toolbar methods of Backbone objects.
     *
     * @namespace
     */
    Drupal.toolbar = {
  
      /**
       * A hash of View instances.
       *
       * @type {object.<string, Backbone.View>}
       */
      views: {},
  
      /**
       * A hash of Model instances.
       *
       * @type {object.<string, Backbone.Model>}
       */
      models: {},
  
      /**
       * A hash of MediaQueryList objects tracked by the toolbar.
       *
       * @type {object.<string, object>}
       */
      mql: {},
  
      /**
       * Accepts a list of subtree menu elements.
       *
       * A deferred object that is resolved by an inlined JavaScript callback.
       *
       * @type {jQuery.Deferred}
       *
       * @see toolbar_subtrees_jsonp().
       */
      setSubtrees: new $.Deferred(),
  
      /**
       * Respond to configured narrow media query changes.
       *
       * @param {Drupal.toolbar.ToolbarModel} model
       *   A toolbar model
       * @param {string} label
       *   Media query label.
       * @param {object} mql
       *   A MediaQueryList object.
       */
      mediaQueryChangeHandler: function (model, label, mql) {
        switch (label) {
          case 'toolbar.narrow':
            model.set({
              isOriented: mql.matches,
              isTrayToggleVisible: false
            });
            // If the toolbar doesn't have an explicit orientation yet, or if the
            // narrow media query doesn't match then set the orientation to
            // vertical.
            if (!mql.matches || !model.get('orientation')) {
              model.set({orientation: 'vertical'}, {validate: true});
            }
            break;
  
          case 'toolbar.standard':
            model.set({
              isFixed: mql.matches
            });
            break;
  
          case 'toolbar.wide':
            model.set({
              orientation: ((mql.matches) ? 'horizontal' : 'vertical')
            }, {validate: true});
            // The tray orientation toggle visibility does not need to be
            // validated.
            model.set({
              isTrayToggleVisible: mql.matches
            });
            break;
  
          default:
            break;
        }
      }
    };
  
    /**
     * A toggle is an interactive element often bound to a click handler.
     *
     * @return {string}
     *   A string representing a DOM fragment.
     */
    Drupal.theme.toolbarOrientationToggle = function () {
      return '<div class="toolbar-toggle-orientation"><div class="toolbar-lining">' +
        '<button class="toolbar-icon" type="button"></button>' +
        '</div></div>';
    };
  
    /**
     * Ajax command to set the toolbar subtrees.
     *
     * @param {Drupal.Ajax} ajax
     *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
     * @param {object} response
     *   JSON response from the Ajax request.
     * @param {number} [status]
     *   XMLHttpRequest status.
     */
    Drupal.AjaxCommands.prototype.setToolbarSubtrees = function (ajax, response, status) {
      Drupal.toolbar.setSubtrees.resolve(response.subtrees);
    };
  
  }(jQuery, Drupal, drupalSettings));
  ;
  /**
   * @file
   * A Backbone Model for collapsible menus.
   */
  
  (function (Backbone, Drupal) {
  
    'use strict';
  
    /**
     * Backbone Model for collapsible menus.
     *
     * @constructor
     *
     * @augments Backbone.Model
     */
    Drupal.toolbar.MenuModel = Backbone.Model.extend(/** @lends Drupal.toolbar.MenuModel# */{
  
      /**
       * @type {object}
       *
       * @prop {object} subtrees
       */
      defaults: /** @lends Drupal.toolbar.MenuModel# */{
  
        /**
         * @type {object}
         */
        subtrees: {}
      }
    });
  
  }(Backbone, Drupal));
  ;
  /**
   * @file
   * A Backbone Model for the toolbar.
   */
  
  (function (Backbone, Drupal) {
  
    'use strict';
  
    /**
     * Backbone model for the toolbar.
     *
     * @constructor
     *
     * @augments Backbone.Model
     */
    Drupal.toolbar.ToolbarModel = Backbone.Model.extend(/** @lends Drupal.toolbar.ToolbarModel# */{
  
      /**
       * @type {object}
       *
       * @prop activeTab
       * @prop activeTray
       * @prop isOriented
       * @prop isFixed
       * @prop areSubtreesLoaded
       * @prop isViewportOverflowConstrained
       * @prop orientation
       * @prop locked
       * @prop isTrayToggleVisible
       * @prop height
       * @prop offsets
       */
      defaults: /** @lends Drupal.toolbar.ToolbarModel# */{
  
        /**
         * The active toolbar tab. All other tabs should be inactive under
         * normal circumstances. It will remain active across page loads. The
         * active item is stored as an ID selector e.g. '#toolbar-item--1'.
         *
         * @type {string}
         */
        activeTab: null,
  
        /**
         * Represents whether a tray is open or not. Stored as an ID selector e.g.
         * '#toolbar-item--1-tray'.
         *
         * @type {string}
         */
        activeTray: null,
  
        /**
         * Indicates whether the toolbar is displayed in an oriented fashion,
         * either horizontal or vertical.
         *
         * @type {bool}
         */
        isOriented: false,
  
        /**
         * Indicates whether the toolbar is positioned absolute (false) or fixed
         * (true).
         *
         * @type {bool}
         */
        isFixed: false,
  
        /**
         * Menu subtrees are loaded through an AJAX request only when the Toolbar
         * is set to a vertical orientation.
         *
         * @type {bool}
         */
        areSubtreesLoaded: false,
  
        /**
         * If the viewport overflow becomes constrained, isFixed must be true so
         * that elements in the trays aren't lost off-screen and impossible to
         * get to.
         *
         * @type {bool}
         */
        isViewportOverflowConstrained: false,
  
        /**
         * The orientation of the active tray.
         *
         * @type {string}
         */
        orientation: 'vertical',
  
        /**
         * A tray is locked if a user toggled it to vertical. Otherwise a tray
         * will switch between vertical and horizontal orientation based on the
         * configured breakpoints. The locked state will be maintained across page
         * loads.
         *
         * @type {bool}
         */
        locked: false,
  
        /**
         * Indicates whether the tray orientation toggle is visible.
         *
         * @type {bool}
         */
        isTrayToggleVisible: false,
  
        /**
         * The height of the toolbar.
         *
         * @type {number}
         */
        height: null,
  
        /**
         * The current viewport offsets determined by {@link Drupal.displace}. The
         * offsets suggest how a module might position is components relative to
         * the viewport.
         *
         * @type {object}
         *
         * @prop {number} top
         * @prop {number} right
         * @prop {number} bottom
         * @prop {number} left
         */
        offsets: {
          top: 0,
          right: 0,
          bottom: 0,
          left: 0
        }
      },
  
      /**
       * @inheritdoc
       *
       * @param {object} attributes
       *   Attributes for the toolbar.
       * @param {object} options
       *   Options for the toolbar.
       *
       * @return {string|undefined}
       *   Returns an error message if validation failed.
       */
      validate: function (attributes, options) {
        // Prevent the orientation being set to horizontal if it is locked, unless
        // override has not been passed as an option.
        if (attributes.orientation === 'horizontal' && this.get('locked') && !options.override) {
          return Drupal.t('The toolbar cannot be set to a horizontal orientation when it is locked.');
        }
      }
    });
  
  }(Backbone, Drupal));
  ;
  /**
   * @file
   * A Backbone view for the body element.
   */
  
  (function ($, Drupal, Backbone) {
  
    'use strict';
  
    Drupal.toolbar.BodyVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.BodyVisualView# */{
  
      /**
       * Adjusts the body element with the toolbar position and dimension changes.
       *
       * @constructs
       *
       * @augments Backbone.View
       */
      initialize: function () {
        this.listenTo(this.model, 'change:orientation change:offsets change:activeTray change:isOriented change:isFixed change:isViewportOverflowConstrained', this.render);
      },
  
      /**
       * @inheritdoc
       */
      render: function () {
        var $body = $('body');
        var orientation = this.model.get('orientation');
        var isOriented = this.model.get('isOriented');
        var isViewportOverflowConstrained = this.model.get('isViewportOverflowConstrained');
  
        $body
          // We are using JavaScript to control media-query handling for two
          // reasons: (1) Using JavaScript let's us leverage the breakpoint
          // configurations and (2) the CSS is really complex if we try to hide
          // some styling from browsers that don't understand CSS media queries.
          // If we drive the CSS from classes added through JavaScript,
          // then the CSS becomes simpler and more robust.
          .toggleClass('toolbar-vertical', (orientation === 'vertical'))
          .toggleClass('toolbar-horizontal', (isOriented && orientation === 'horizontal'))
          // When the toolbar is fixed, it will not scroll with page scrolling.
          .toggleClass('toolbar-fixed', (isViewportOverflowConstrained || this.model.get('isFixed')))
          // Toggle the toolbar-tray-open class on the body element. The class is
          // applied when a toolbar tray is active. Padding might be applied to
          // the body element to prevent the tray from overlapping content.
          .toggleClass('toolbar-tray-open', !!this.model.get('activeTray'))
          // Apply padding to the top of the body to offset the placement of the
          // toolbar bar element.
          .css('padding-top', this.model.get('offsets').top);
      }
    });
  
  }(jQuery, Drupal, Backbone));
  ;
  /**
   * @file
   * A Backbone view for the collapsible menus.
   */
  
  (function ($, Backbone, Drupal) {
  
    'use strict';
  
    Drupal.toolbar.MenuVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.MenuVisualView# */{
  
      /**
       * Backbone View for collapsible menus.
       *
       * @constructs
       *
       * @augments Backbone.View
       */
      initialize: function () {
        this.listenTo(this.model, 'change:subtrees', this.render);
      },
  
      /**
       * @inheritdoc
       */
      render: function () {
        var subtrees = this.model.get('subtrees');
        // Add subtrees.
        for (var id in subtrees) {
          if (subtrees.hasOwnProperty(id)) {
            this.$el
              .find('#toolbar-link-' + id)
              .once('toolbar-subtrees')
              .after(subtrees[id]);
          }
        }
        // Render the main menu as a nested, collapsible accordion.
        if ('drupalToolbarMenu' in $.fn) {
          this.$el
            .children('.toolbar-menu')
            .drupalToolbarMenu();
        }
      }
    });
  
  }(jQuery, Backbone, Drupal));
  ;
  /**
   * @file
   * A Backbone view for the aural feedback of the toolbar.
   */
  
  (function (Backbone, Drupal) {
  
    'use strict';
  
    Drupal.toolbar.ToolbarAuralView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarAuralView# */{
  
      /**
       * Backbone view for the aural feedback of the toolbar.
       *
       * @constructs
       *
       * @augments Backbone.View
       *
       * @param {object} options
       *   Options for the view.
       * @param {object} options.strings
       *   Various strings to use in the view.
       */
      initialize: function (options) {
        this.strings = options.strings;
  
        this.listenTo(this.model, 'change:orientation', this.onOrientationChange);
        this.listenTo(this.model, 'change:activeTray', this.onActiveTrayChange);
      },
  
      /**
       * Announces an orientation change.
       *
       * @param {Drupal.toolbar.ToolbarModel} model
       *   The toolbar model in question.
       * @param {string} orientation
       *   The new value of the orientation attribute in the model.
       */
      onOrientationChange: function (model, orientation) {
        Drupal.announce(Drupal.t('Tray orientation changed to @orientation.', {
          '@orientation': orientation
        }));
      },
  
      /**
       * Announces a changed active tray.
       *
       * @param {Drupal.toolbar.ToolbarModel} model
       *   The toolbar model in question.
       * @param {HTMLElement} tray
       *   The new value of the tray attribute in the model.
       */
      onActiveTrayChange: function (model, tray) {
        var relevantTray = (tray === null) ? model.previous('activeTray') : tray;
        var action = (tray === null) ? Drupal.t('closed') : Drupal.t('opened');
        var trayNameElement = relevantTray.querySelector('.toolbar-tray-name');
        var text;
        if (trayNameElement !== null) {
          text = Drupal.t('Tray "@tray" @action.', {
            '@tray': trayNameElement.textContent, '@action': action
          });
        }
        else {
          text = Drupal.t('Tray @action.', {'@action': action});
        }
        Drupal.announce(text);
      }
    });
  
  }(Backbone, Drupal));
  ;
  /**
   * @file
   * A Backbone view for the toolbar element. Listens to mouse & touch.
   */
  
  (function ($, Drupal, drupalSettings, Backbone) {
  
    'use strict';
  
    Drupal.toolbar.ToolbarVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarVisualView# */{
  
      /**
       * Event map for the `ToolbarVisualView`.
       *
       * @return {object}
       *   A map of events.
       */
      events: function () {
        // Prevents delay and simulated mouse events.
        var touchEndToClick = function (event) {
          event.preventDefault();
          event.target.click();
        };
  
        return {
          'click .toolbar-bar .toolbar-tab .trigger': 'onTabClick',
          'click .toolbar-toggle-orientation button': 'onOrientationToggleClick',
          'touchend .toolbar-bar .toolbar-tab .trigger': touchEndToClick,
          'touchend .toolbar-toggle-orientation button': touchEndToClick
        };
      },
  
      /**
       * Backbone view for the toolbar element. Listens to mouse & touch.
       *
       * @constructs
       *
       * @augments Backbone.View
       *
       * @param {object} options
       *   Options for the view object.
       * @param {object} options.strings
       *   Various strings to use in the view.
       */
      initialize: function (options) {
        this.strings = options.strings;
  
        this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented change:isTrayToggleVisible', this.render);
        this.listenTo(this.model, 'change:mqMatches', this.onMediaQueryChange);
        this.listenTo(this.model, 'change:offsets', this.adjustPlacement);
  
        // Add the tray orientation toggles.
        this.$el
          .find('.toolbar-tray .toolbar-lining')
          .append(Drupal.theme('toolbarOrientationToggle'));
  
        // Trigger an activeTab change so that listening scripts can respond on
        // page load. This will call render.
        this.model.trigger('change:activeTab');
      },
  
      /**
       * @inheritdoc
       *
       * @return {Drupal.toolbar.ToolbarVisualView}
       *   The `ToolbarVisualView` instance.
       */
      render: function () {
        this.updateTabs();
        this.updateTrayOrientation();
        this.updateBarAttributes();
        // Load the subtrees if the orientation of the toolbar is changed to
        // vertical. This condition responds to the case that the toolbar switches
        // from horizontal to vertical orientation. The toolbar starts in a
        // vertical orientation by default and then switches to horizontal during
        // initialization if the media query conditions are met. Simply checking
        // that the orientation is vertical here would result in the subtrees
        // always being loaded, even when the toolbar initialization ultimately
        // results in a horizontal orientation.
        //
        // @see Drupal.behaviors.toolbar.attach() where admin menu subtrees
        // loading is invoked during initialization after media query conditions
        // have been processed.
        if (this.model.changed.orientation === 'vertical' || this.model.changed.activeTab) {
          this.loadSubtrees();
        }
        // Trigger a recalculation of viewport displacing elements. Use setTimeout
        // to ensure this recalculation happens after changes to visual elements
        // have processed.
        window.setTimeout(function () {
          Drupal.displace(true);
        }, 0);
        return this;
      },
  
      /**
       * Responds to a toolbar tab click.
       *
       * @param {jQuery.Event} event
       *   The event triggered.
       */
      onTabClick: function (event) {
        // If this tab has a tray associated with it, it is considered an
        // activatable tab.
        if (event.target.hasAttribute('data-toolbar-tray')) {
          var activeTab = this.model.get('activeTab');
          var clickedTab = event.target;
  
          // Set the event target as the active item if it is not already.
          this.model.set('activeTab', (!activeTab || clickedTab !== activeTab) ? clickedTab : null);
  
          event.preventDefault();
          event.stopPropagation();
        }
      },
  
      /**
       * Toggles the orientation of a toolbar tray.
       *
       * @param {jQuery.Event} event
       *   The event triggered.
       */
      onOrientationToggleClick: function (event) {
        var orientation = this.model.get('orientation');
        // Determine the toggle-to orientation.
        var antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical';
        var locked = antiOrientation === 'vertical';
        // Remember the locked state.
        if (locked) {
          localStorage.setItem('Drupal.toolbar.trayVerticalLocked', 'true');
        }
        else {
          localStorage.removeItem('Drupal.toolbar.trayVerticalLocked');
        }
        // Update the model.
        this.model.set({
          locked: locked,
          orientation: antiOrientation
        }, {
          validate: true,
          override: true
        });
  
        event.preventDefault();
        event.stopPropagation();
      },
  
      /**
       * Updates the display of the tabs: toggles a tab and the associated tray.
       */
      updateTabs: function () {
        var $tab = $(this.model.get('activeTab'));
        // Deactivate the previous tab.
        $(this.model.previous('activeTab'))
          .removeClass('is-active')
          .prop('aria-pressed', false);
        // Deactivate the previous tray.
        $(this.model.previous('activeTray'))
          .removeClass('is-active');
  
        // Activate the selected tab.
        if ($tab.length > 0) {
          $tab
            .addClass('is-active')
            // Mark the tab as pressed.
            .prop('aria-pressed', true);
          var name = $tab.attr('data-toolbar-tray');
          // Store the active tab name or remove the setting.
          var id = $tab.get(0).id;
          if (id) {
            localStorage.setItem('Drupal.toolbar.activeTabID', JSON.stringify(id));
          }
          // Activate the associated tray.
          var $tray = this.$el.find('[data-toolbar-tray="' + name + '"].toolbar-tray');
          if ($tray.length) {
            $tray.addClass('is-active');
            this.model.set('activeTray', $tray.get(0));
          }
          else {
            // There is no active tray.
            this.model.set('activeTray', null);
          }
        }
        else {
          // There is no active tray.
          this.model.set('activeTray', null);
          localStorage.removeItem('Drupal.toolbar.activeTabID');
        }
      },
  
      /**
       * Update the attributes of the toolbar bar element.
       */
      updateBarAttributes: function () {
        var isOriented = this.model.get('isOriented');
        if (isOriented) {
          this.$el.find('.toolbar-bar').attr('data-offset-top', '');
        }
        else {
          this.$el.find('.toolbar-bar').removeAttr('data-offset-top');
        }
        // Toggle between a basic vertical view and a more sophisticated
        // horizontal and vertical display of the toolbar bar and trays.
        this.$el.toggleClass('toolbar-oriented', isOriented);
      },
  
      /**
       * Updates the orientation of the active tray if necessary.
       */
      updateTrayOrientation: function () {
        var orientation = this.model.get('orientation');
        // The antiOrientation is used to render the view of action buttons like
        // the tray orientation toggle.
        var antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical';
        // Update the orientation of the trays.
        var $trays = this.$el.find('.toolbar-tray')
          .removeClass('toolbar-tray-horizontal toolbar-tray-vertical')
          .addClass('toolbar-tray-' + orientation);
  
        // Update the tray orientation toggle button.
        var iconClass = 'toolbar-icon-toggle-' + orientation;
        var iconAntiClass = 'toolbar-icon-toggle-' + antiOrientation;
        var $orientationToggle = this.$el.find('.toolbar-toggle-orientation')
          .toggle(this.model.get('isTrayToggleVisible'));
        $orientationToggle.find('button')
          .val(antiOrientation)
          .attr('title', this.strings[antiOrientation])
          .text(this.strings[antiOrientation])
          .removeClass(iconClass)
          .addClass(iconAntiClass);
  
        // Update data offset attributes for the trays.
        var dir = document.documentElement.dir;
        var edge = (dir === 'rtl') ? 'right' : 'left';
        // Remove data-offset attributes from the trays so they can be refreshed.
        $trays.removeAttr('data-offset-left data-offset-right data-offset-top');
        // If an active vertical tray exists, mark it as an offset element.
        $trays.filter('.toolbar-tray-vertical.is-active').attr('data-offset-' + edge, '');
        // If an active horizontal tray exists, mark it as an offset element.
        $trays.filter('.toolbar-tray-horizontal.is-active').attr('data-offset-top', '');
      },
  
      /**
       * Sets the tops of the trays so that they align with the bottom of the bar.
       */
      adjustPlacement: function () {
        var $trays = this.$el.find('.toolbar-tray');
        if (!this.model.get('isOriented')) {
          $trays.css('margin-top', 0);
          $trays.removeClass('toolbar-tray-horizontal').addClass('toolbar-tray-vertical');
        }
        else {
          // The toolbar container is invisible. Its placement is used to
          // determine the container for the trays.
          $trays.css('margin-top', this.$el.find('.toolbar-bar').outerHeight());
        }
      },
  
      /**
       * Calls the endpoint URI that builds an AJAX command with the rendered
       * subtrees.
       *
       * The rendered admin menu subtrees HTML is cached on the client in
       * localStorage until the cache of the admin menu subtrees on the server-
       * side is invalidated. The subtreesHash is stored in localStorage as well
       * and compared to the subtreesHash in drupalSettings to determine when the
       * admin menu subtrees cache has been invalidated.
       */
      loadSubtrees: function () {
        var $activeTab = $(this.model.get('activeTab'));
        var orientation = this.model.get('orientation');
        // Only load and render the admin menu subtrees if:
        //   (1) They have not been loaded yet.
        //   (2) The active tab is the administration menu tab, indicated by the
        //       presence of the data-drupal-subtrees attribute.
        //   (3) The orientation of the tray is vertical.
        if (!this.model.get('areSubtreesLoaded') && typeof $activeTab.data('drupal-subtrees') !== 'undefined' && orientation === 'vertical') {
          var subtreesHash = drupalSettings.toolbar.subtreesHash;
          var theme = drupalSettings.ajaxPageState.theme;
          var endpoint = Drupal.url('toolbar/subtrees/' + subtreesHash);
          var cachedSubtreesHash = localStorage.getItem('Drupal.toolbar.subtreesHash.' + theme);
          var cachedSubtrees = JSON.parse(localStorage.getItem('Drupal.toolbar.subtrees.' + theme));
          var isVertical = this.model.get('orientation') === 'vertical';
          // If we have the subtrees in localStorage and the subtree hash has not
          // changed, then use the cached data.
          if (isVertical && subtreesHash === cachedSubtreesHash && cachedSubtrees) {
            Drupal.toolbar.setSubtrees.resolve(cachedSubtrees);
          }
          // Only make the call to get the subtrees if the orientation of the
          // toolbar is vertical.
          else if (isVertical) {
            // Remove the cached menu information.
            localStorage.removeItem('Drupal.toolbar.subtreesHash.' + theme);
            localStorage.removeItem('Drupal.toolbar.subtrees.' + theme);
            // The AJAX response's command will trigger the resolve method of the
            // Drupal.toolbar.setSubtrees Promise.
            Drupal.ajax({url: endpoint}).execute();
            // Cache the hash for the subtrees locally.
            localStorage.setItem('Drupal.toolbar.subtreesHash.' + theme, subtreesHash);
          }
        }
      }
    });
  
  }(jQuery, Drupal, drupalSettings, Backbone));
  ;
  /* jQuery Foundation Joyride Plugin 2.1 | Copyright 2012, ZURB | www.opensource.org/licenses/mit-license.php */
  (function(e,t,n){"use strict";var r={version:"2.0.3",tipLocation:"bottom",nubPosition:"auto",scroll:!0,scrollSpeed:300,timer:0,autoStart:!1,startTimerOnClick:!0,startOffset:0,nextButton:!0,tipAnimation:"fade",pauseAfter:[],tipAnimationFadeSpeed:300,cookieMonster:!1,cookieName:"joyride",cookieDomain:!1,cookiePath:!1,localStorage:!1,localStorageKey:"joyride",tipContainer:"body",modal:!1,expose:!1,postExposeCallback:e.noop,preRideCallback:e.noop,postRideCallback:e.noop,preStepCallback:e.noop,postStepCallback:e.noop,template:{link:'<a href="#close" class="joyride-close-tip">X</a>',timer:'<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>',tip:'<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>',wrapper:'<div class="joyride-content-wrapper" role="dialog"></div>',button:'<a href="#" class="joyride-next-tip"></a>',modal:'<div class="joyride-modal-bg"></div>',expose:'<div class="joyride-expose-wrapper"></div>',exposeCover:'<div class="joyride-expose-cover"></div>'}},i=i||!1,s={},o={init:function(n){return this.each(function(){e.isEmptyObject(s)?(s=e.extend(!0,r,n),s.document=t.document,s.$document=e(s.document),s.$window=e(t),s.$content_el=e(this),s.$body=e(s.tipContainer),s.body_offset=e(s.tipContainer).position(),s.$tip_content=e("> li",s.$content_el),s.paused=!1,s.attempts=0,s.tipLocationPatterns={top:["bottom"],bottom:[],left:["right","top","bottom"],right:["left","top","bottom"]},o.jquery_check(),e.isFunction(e.cookie)||(s.cookieMonster=!1),(!s.cookieMonster||!e.cookie(s.cookieName))&&(!s.localStorage||!o.support_localstorage()||!localStorage.getItem(s.localStorageKey))&&(s.$tip_content.each(function(t){o.create({$li:e(this),index:t})}),s.autoStart&&(!s.startTimerOnClick&&s.timer>0?(o.show("init"),o.startTimer()):o.show("init"))),s.$document.on("click.joyride",".joyride-next-tip, .joyride-modal-bg",function(e){e.preventDefault(),s.$li.next().length<1?o.end():s.timer>0?(clearTimeout(s.automate),o.hide(),o.show(),o.startTimer()):(o.hide(),o.show())}),s.$document.on("click.joyride",".joyride-close-tip",function(e){e.preventDefault(),o.end()}),s.$window.bind("resize.joyride",function(t){if(s.$li){if(s.exposed&&s.exposed.length>0){var n=e(s.exposed);n.each(function(){var t=e(this);o.un_expose(t),o.expose(t)})}o.is_phone()?o.pos_phone():o.pos_default()}})):o.restart()})},resume:function(){o.set_li(),o.show()},nextTip:function(){s.$li.next().length<1?o.end():s.timer>0?(clearTimeout(s.automate),o.hide(),o.show(),o.startTimer()):(o.hide(),o.show())},tip_template:function(t){var n,r,i;return t.tip_class=t.tip_class||"",n=e(s.template.tip).addClass(t.tip_class),r=e.trim(e(t.li).html())+o.button_text(t.button_text)+s.template.link+o.timer_instance(t.index),i=e(s.template.wrapper),t.li.attr("data-aria-labelledby")&&i.attr("aria-labelledby",t.li.attr("data-aria-labelledby")),t.li.attr("data-aria-describedby")&&i.attr("aria-describedby",t.li.attr("data-aria-describedby")),n.append(i),n.first().attr("data-index",t.index),e(".joyride-content-wrapper",n).append(r),n[0]},timer_instance:function(t){var n;return t===0&&s.startTimerOnClick&&s.timer>0||s.timer===0?n="":n=o.outerHTML(e(s.template.timer)[0]),n},button_text:function(t){return s.nextButton?(t=e.trim(t)||"Next",t=o.outerHTML(e(s.template.button).append(t)[0])):t="",t},create:function(t){var n=t.$li.attr("data-button")||t.$li.attr("data-text"),r=t.$li.attr("class"),i=e(o.tip_template({tip_class:r,index:t.index,button_text:n,li:t.$li}));e(s.tipContainer).append(i)},show:function(t){var r={},i,u=[],a=0,f,l=null;if(s.$li===n||e.inArray(s.$li.index(),s.pauseAfter)===-1){s.paused?s.paused=!1:o.set_li(t),s.attempts=0;if(s.$li.length&&s.$target.length>0){t&&(s.preRideCallback(s.$li.index(),s.$next_tip),s.modal&&o.show_modal()),s.preStepCallback(s.$li.index(),s.$next_tip),u=(s.$li.data("options")||":").split(";"),a=u.length;for(i=a-1;i>=0;i--)f=u[i].split(":"),f.length===2&&(r[e.trim(f[0])]=e.trim(f[1]));s.tipSettings=e.extend({},s,r),s.tipSettings.tipLocationPattern=s.tipLocationPatterns[s.tipSettings.tipLocation],s.modal&&s.expose&&o.expose(),!/body/i.test(s.$target.selector)&&s.scroll&&o.scroll_to(),o.is_phone()?o.pos_phone(!0):o.pos_default(!0),l=e(".joyride-timer-indicator",s.$next_tip),/pop/i.test(s.tipAnimation)?(l.outerWidth(0),s.timer>0?(s.$next_tip.show(),l.animate({width:e(".joyride-timer-indicator-wrap",s.$next_tip).outerWidth()},s.timer)):s.$next_tip.show()):/fade/i.test(s.tipAnimation)&&(l.outerWidth(0),s.timer>0?(s.$next_tip.fadeIn(s.tipAnimationFadeSpeed),s.$next_tip.show(),l.animate({width:e(".joyride-timer-indicator-wrap",s.$next_tip).outerWidth()},s.timer)):s.$next_tip.fadeIn(s.tipAnimationFadeSpeed)),s.$current_tip=s.$next_tip,e(".joyride-next-tip",s.$current_tip).focus(),o.tabbable(s.$current_tip)}else s.$li&&s.$target.length<1?o.show():o.end()}else s.paused=!0},is_phone:function(){return i?i.mq("only screen and (max-width: 767px)"):s.$window.width()<767?!0:!1},support_localstorage:function(){return i?i.localstorage:!!t.localStorage},hide:function(){s.modal&&s.expose&&o.un_expose(),s.modal||e(".joyride-modal-bg").hide(),s.$current_tip.hide(),s.postStepCallback(s.$li.index(),s.$current_tip)},set_li:function(e){e?(s.$li=s.$tip_content.eq(s.startOffset),o.set_next_tip(),s.$current_tip=s.$next_tip):(s.$li=s.$li.next(),o.set_next_tip()),o.set_target()},set_next_tip:function(){s.$next_tip=e(".joyride-tip-guide[data-index="+s.$li.index()+"]")},set_target:function(){var t=s.$li.attr("data-class"),n=s.$li.attr("data-id"),r=function(){return n?e(s.document.getElementById(n)):t?e("."+t).filter(":visible").first():e("body")};s.$target=r()},scroll_to:function(){var t,n;t=s.$window.height()/2,n=Math.ceil(s.$target.offset().top-t+s.$next_tip.outerHeight()),e("html, body").stop().animate({scrollTop:n},s.scrollSpeed)},paused:function(){return e.inArray(s.$li.index()+1,s.pauseAfter)===-1?!0:!1},destroy:function(){e.isEmptyObject(s)||s.$document.off(".joyride"),e(t).off(".joyride"),e(".joyride-close-tip, .joyride-next-tip, .joyride-modal-bg").off(".joyride"),e(".joyride-tip-guide, .joyride-modal-bg").remove(),clearTimeout(s.automate),s={}},restart:function(){s.autoStart?(o.hide(),s.$li=n,o.show("init")):(!s.startTimerOnClick&&s.timer>0?(o.show("init"),o.startTimer()):o.show("init"),s.autoStart=!0)},pos_default:function(t){var n=Math.ceil(s.$window.height()/2),r=s.$next_tip.offset(),i=e(".joyride-nub",s.$next_tip),u=Math.ceil(i.outerWidth()/2),a=Math.ceil(i.outerHeight()/2),f=t||!1;f&&(s.$next_tip.css("visibility","hidden"),s.$next_tip.show());if(!/body/i.test(s.$target.selector)){var l=s.tipSettings.tipAdjustmentY?parseInt(s.tipSettings.tipAdjustmentY):0,c=s.tipSettings.tipAdjustmentX?parseInt(s.tipSettings.tipAdjustmentX):0;o.bottom()?(s.$next_tip.css({top:s.$target.offset().top+a+s.$target.outerHeight()+l,left:s.$target.offset().left+c}),/right/i.test(s.tipSettings.nubPosition)&&s.$next_tip.css("left",s.$target.offset().left-s.$next_tip.outerWidth()+s.$target.outerWidth()),o.nub_position(i,s.tipSettings.nubPosition,"top")):o.top()?(s.$next_tip.css({top:s.$target.offset().top-s.$next_tip.outerHeight()-a+l,left:s.$target.offset().left+c}),o.nub_position(i,s.tipSettings.nubPosition,"bottom")):o.right()?(s.$next_tip.css({top:s.$target.offset().top+l,left:s.$target.outerWidth()+s.$target.offset().left+u+c}),o.nub_position(i,s.tipSettings.nubPosition,"left")):o.left()&&(s.$next_tip.css({top:s.$target.offset().top+l,left:s.$target.offset().left-s.$next_tip.outerWidth()-u+c}),o.nub_position(i,s.tipSettings.nubPosition,"right")),!o.visible(o.corners(s.$next_tip))&&s.attempts<s.tipSettings.tipLocationPattern.length&&(i.removeClass("bottom").removeClass("top").removeClass("right").removeClass("left"),s.tipSettings.tipLocation=s.tipSettings.tipLocationPattern[s.attempts],s.attempts++,o.pos_default(!0))}else s.$li.length&&o.pos_modal(i);f&&(s.$next_tip.hide(),s.$next_tip.css("visibility","visible"))},pos_phone:function(t){var n=s.$next_tip.outerHeight(),r=s.$next_tip.offset(),i=s.$target.outerHeight(),u=e(".joyride-nub",s.$next_tip),a=Math.ceil(u.outerHeight()/2),f=t||!1;u.removeClass("bottom").removeClass("top").removeClass("right").removeClass("left"),f&&(s.$next_tip.css("visibility","hidden"),s.$next_tip.show()),/body/i.test(s.$target.selector)?s.$li.length&&o.pos_modal(u):o.top()?(s.$next_tip.offset({top:s.$target.offset().top-n-a}),u.addClass("bottom")):(s.$next_tip.offset({top:s.$target.offset().top+i+a}),u.addClass("top")),f&&(s.$next_tip.hide(),s.$next_tip.css("visibility","visible"))},pos_modal:function(e){o.center(),e.hide(),o.show_modal()},show_modal:function(){e(".joyride-modal-bg").length<1&&e("body").append(s.template.modal).show(),/pop/i.test(s.tipAnimation)?e(".joyride-modal-bg").show():e(".joyride-modal-bg").fadeIn(s.tipAnimationFadeSpeed)},expose:function(){var n,r,i,u,a="expose-"+Math.floor(Math.random()*1e4);if(arguments.length>0&&arguments[0]instanceof e)i=arguments[0];else{if(!s.$target||!!/body/i.test(s.$target.selector))return!1;i=s.$target}if(i.length<1)return t.console&&console.error("element not valid",i),!1;n=e(s.template.expose),s.$body.append(n),n.css({top:i.offset().top,left:i.offset().left,width:i.outerWidth(!0),height:i.outerHeight(!0)}),r=e(s.template.exposeCover),u={zIndex:i.css("z-index"),position:i.css("position")},i.css("z-index",n.css("z-index")*1+1),u.position=="static"&&i.css("position","relative"),i.data("expose-css",u),r.css({top:i.offset().top,left:i.offset().left,width:i.outerWidth(!0),height:i.outerHeight(!0)}),s.$body.append(r),n.addClass(a),r.addClass(a),s.tipSettings.exposeClass&&(n.addClass(s.tipSettings.exposeClass),r.addClass(s.tipSettings.exposeClass)),i.data("expose",a),s.postExposeCallback(s.$li.index(),s.$next_tip,i),o.add_exposed(i)},un_expose:function(){var n,r,i,u,a=!1;if(arguments.length>0&&arguments[0]instanceof e)r=arguments[0];else{if(!s.$target||!!/body/i.test(s.$target.selector))return!1;r=s.$target}if(r.length<1)return t.console&&console.error("element not valid",r),!1;n=r.data("expose"),i=e("."+n),arguments.length>1&&(a=arguments[1]),a===!0?e(".joyride-expose-wrapper,.joyride-expose-cover").remove():i.remove(),u=r.data("expose-css"),u.zIndex=="auto"?r.css("z-index",""):r.css("z-index",u.zIndex),u.position!=r.css("position")&&(u.position=="static"?r.css("position",""):r.css("position",u.position)),r.removeData("expose"),r.removeData("expose-z-index"),o.remove_exposed(r)},add_exposed:function(t){s.exposed=s.exposed||[],t instanceof e?s.exposed.push(t[0]):typeof t=="string"&&s.exposed.push(t)},remove_exposed:function(t){var n;t instanceof e?n=t[0]:typeof t=="string"&&(n=t),s.exposed=s.exposed||[];for(var r=0;r<s.exposed.length;r++)if(s.exposed[r]==n){s.exposed.splice(r,1);return}},center:function(){var e=s.$window;return s.$next_tip.css({top:(e.height()-s.$next_tip.outerHeight())/2+e.scrollTop(),left:(e.width()-s.$next_tip.outerWidth())/2+e.scrollLeft()}),!0},bottom:function(){return/bottom/i.test(s.tipSettings.tipLocation)},top:function(){return/top/i.test(s.tipSettings.tipLocation)},right:function(){return/right/i.test(s.tipSettings.tipLocation)},left:function(){return/left/i.test(s.tipSettings.tipLocation)},corners:function(e){var t=s.$window,n=t.height()/2,r=Math.ceil(s.$target.offset().top-n+s.$next_tip.outerHeight()),i=t.width()+t.scrollLeft(),o=t.height()+r,u=t.height()+t.scrollTop(),a=t.scrollTop();return r<a&&(r<0?a=0:a=r),o>u&&(u=o),[e.offset().top<a,i<e.offset().left+e.outerWidth(),u<e.offset().top+e.outerHeight(),t.scrollLeft()>e.offset().left]},visible:function(e){var t=e.length;while(t--)if(e[t])return!1;return!0},nub_position:function(e,t,n){t==="auto"?e.addClass(n):e.addClass(t)},startTimer:function(){s.$li.length?s.automate=setTimeout(function(){o.hide(),o.show(),o.startTimer()},s.timer):clearTimeout(s.automate)},end:function(){s.cookieMonster&&e.cookie(s.cookieName,"ridden",{expires:365,domain:s.cookieDomain,path:s.cookiePath}),s.localStorage&&localStorage.setItem(s.localStorageKey,!0),s.timer>0&&clearTimeout(s.automate),s.modal&&s.expose&&o.un_expose(),s.$current_tip&&s.$current_tip.hide(),s.$li&&(s.postStepCallback(s.$li.index(),s.$current_tip),s.postRideCallback(s.$li.index(),s.$current_tip)),e(".joyride-modal-bg").hide()},jquery_check:function(){return e.isFunction(e.fn.on)?!0:(e.fn.on=function(e,t,n){return this.delegate(t,e,n)},e.fn.off=function(e,t,n){return this.undelegate(t,e,n)},!1)},outerHTML:function(e){return e.outerHTML||(new XMLSerializer).serializeToString(e)},version:function(){return s.version},tabbable:function(t){e(t).on("keydown",function(n){if(!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===27){n.preventDefault(),o.end();return}if(n.keyCode!==9)return;var r=e(t).find(":tabbable"),i=r.filter(":first"),s=r.filter(":last");n.target===s[0]&&!n.shiftKey?(i.focus(1),n.preventDefault()):n.target===i[0]&&n.shiftKey&&(s.focus(1),n.preventDefault())})}};e.fn.joyride=function(t){if(o[t])return o[t].apply(this,Array.prototype.slice.call(arguments,1));if(typeof t=="object"||!t)return o.init.apply(this,arguments);e.error("Method "+t+" does not exist on jQuery.joyride")}})(jQuery,this);
  ;
  /**
   * @file
   * Attaches behaviors for the Tour module's toolbar tab.
   */
  
  (function ($, Backbone, Drupal, document) {
  
    'use strict';
  
    var queryString = decodeURI(window.location.search);
  
    /**
     * Attaches the tour's toolbar tab behavior.
     *
     * It uses the query string for:
     * - tour: When ?tour=1 is present, the tour will start automatically after
     *   the page has loaded.
     * - tips: Pass ?tips=class in the url to filter the available tips to the
     *   subset which match the given class.
     *
     * @example
     * http://example.com/foo?tour=1&tips=bar
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attach tour functionality on `tour` events.
     */
    Drupal.behaviors.tour = {
      attach: function (context) {
        $('body').once('tour').each(function () {
          var model = new Drupal.tour.models.StateModel();
          new Drupal.tour.views.ToggleTourView({
            el: $(context).find('#toolbar-tab-tour'),
            model: model
          });
  
          model
            // Allow other scripts to respond to tour events.
            .on('change:isActive', function (model, isActive) {
              $(document).trigger((isActive) ? 'drupalTourStarted' : 'drupalTourStopped');
            })
            // Initialization: check whether a tour is available on the current
            // page.
            .set('tour', $(context).find('ol#tour'));
  
          // Start the tour immediately if toggled via query string.
          if (/tour=?/i.test(queryString)) {
            model.set('isActive', true);
          }
        });
      }
    };
  
    /**
     * @namespace
     */
    Drupal.tour = Drupal.tour || {
  
      /**
       * @namespace Drupal.tour.models
       */
      models: {},
  
      /**
       * @namespace Drupal.tour.views
       */
      views: {}
    };
  
    /**
     * Backbone Model for tours.
     *
     * @constructor
     *
     * @augments Backbone.Model
     */
    Drupal.tour.models.StateModel = Backbone.Model.extend(/** @lends Drupal.tour.models.StateModel# */{
  
      /**
       * @type {object}
       */
      defaults: /** @lends Drupal.tour.models.StateModel# */{
  
        /**
         * Indicates whether the Drupal root window has a tour.
         *
         * @type {Array}
         */
        tour: [],
  
        /**
         * Indicates whether the tour is currently running.
         *
         * @type {bool}
         */
        isActive: false,
  
        /**
         * Indicates which tour is the active one (necessary to cleanly stop).
         *
         * @type {Array}
         */
        activeTour: []
      }
    });
  
    Drupal.tour.views.ToggleTourView = Backbone.View.extend(/** @lends Drupal.tour.views.ToggleTourView# */{
  
      /**
       * @type {object}
       */
      events: {click: 'onClick'},
  
      /**
       * Handles edit mode toggle interactions.
       *
       * @constructs
       *
       * @augments Backbone.View
       */
      initialize: function () {
        this.listenTo(this.model, 'change:tour change:isActive', this.render);
        this.listenTo(this.model, 'change:isActive', this.toggleTour);
      },
  
      /**
       * @inheritdoc
       *
       * @return {Drupal.tour.views.ToggleTourView}
       *   The `ToggleTourView` view.
       */
      render: function () {
        // Render the visibility.
        this.$el.toggleClass('hidden', this._getTour().length === 0);
        // Render the state.
        var isActive = this.model.get('isActive');
        this.$el.find('button')
          .toggleClass('is-active', isActive)
          .prop('aria-pressed', isActive);
        return this;
      },
  
      /**
       * Model change handler; starts or stops the tour.
       */
      toggleTour: function () {
        if (this.model.get('isActive')) {
          var $tour = this._getTour();
          this._removeIrrelevantTourItems($tour, this._getDocument());
          var that = this;
          if ($tour.find('li').length) {
            $tour.joyride({
              autoStart: true,
              postRideCallback: function () { that.model.set('isActive', false); },
              // HTML segments for tip layout.
              template: {
                link: '<a href=\"#close\" class=\"joyride-close-tip\">&times;</a>',
                button: '<a href=\"#\" class=\"button button--primary joyride-next-tip\"></a>'
              }
            });
            this.model.set({isActive: true, activeTour: $tour});
          }
        }
        else {
          this.model.get('activeTour').joyride('destroy');
          this.model.set({isActive: false, activeTour: []});
        }
      },
  
      /**
       * Toolbar tab click event handler; toggles isActive.
       *
       * @param {jQuery.Event} event
       *   The click event.
       */
      onClick: function (event) {
        this.model.set('isActive', !this.model.get('isActive'));
        event.preventDefault();
        event.stopPropagation();
      },
  
      /**
       * Gets the tour.
       *
       * @return {jQuery}
       *   A jQuery element pointing to a `<ol>` containing tour items.
       */
      _getTour: function () {
        return this.model.get('tour');
      },
  
      /**
       * Gets the relevant document as a jQuery element.
       *
       * @return {jQuery}
       *   A jQuery element pointing to the document within which a tour would be
       *   started given the current state.
       */
      _getDocument: function () {
        return $(document);
      },
  
      /**
       * Removes tour items for elements that don't have matching page elements.
       *
       * Or that are explicitly filtered out via the 'tips' query string.
       *
       * @example
       * <caption>This will filter out tips that do not have a matching
       * page element or don't have the "bar" class.</caption>
       * http://example.com/foo?tips=bar
       *
       * @param {jQuery} $tour
       *   A jQuery element pointing to a `<ol>` containing tour items.
       * @param {jQuery} $document
       *   A jQuery element pointing to the document within which the elements
       *   should be sought.
       *
       * @see Drupal.tour.views.ToggleTourView#_getDocument
       */
      _removeIrrelevantTourItems: function ($tour, $document) {
        var removals = false;
        var tips = /tips=([^&]+)/.exec(queryString);
        $tour
          .find('li')
          .each(function () {
            var $this = $(this);
            var itemId = $this.attr('data-id');
            var itemClass = $this.attr('data-class');
            // If the query parameter 'tips' is set, remove all tips that don't
            // have the matching class.
            if (tips && !$(this).hasClass(tips[1])) {
              removals = true;
              $this.remove();
              return;
            }
            // Remove tip from the DOM if there is no corresponding page element.
            if ((!itemId && !itemClass) ||
              (itemId && $document.find('#' + itemId).length) ||
              (itemClass && $document.find('.' + itemClass).length)) {
              return;
            }
            removals = true;
            $this.remove();
          });
  
        // If there were removals, we'll have to do some clean-up.
        if (removals) {
          var total = $tour.find('li').length;
          if (!total) {
            this.model.set({tour: []});
          }
  
          $tour
            .find('li')
            // Rebuild the progress data.
            .each(function (index) {
              var progress = Drupal.t('!tour_item of !total', {'!tour_item': index + 1, '!total': total});
              $(this).find('.tour-progress').text(progress);
            })
            // Update the last item to have "End tour" as the button.
            .eq(-1)
            .attr('data-text', Drupal.t('End tour'));
        }
      }
  
    });
  
  })(jQuery, Backbone, Drupal, document);
  ;
  /**
   * @file
   * Manages page tabbing modifications made by modules.
   */
  
  /**
   * Allow modules to respond to the constrain event.
   *
   * @event drupalTabbingConstrained
   */
  
  /**
   * Allow modules to respond to the tabbingContext release event.
   *
   * @event drupalTabbingContextReleased
   */
  
  /**
   * Allow modules to respond to the constrain event.
   *
   * @event drupalTabbingContextActivated
   */
  
  /**
   * Allow modules to respond to the constrain event.
   *
   * @event drupalTabbingContextDeactivated
   */
  
  (function ($, Drupal) {
  
    'use strict';
  
    /**
     * Provides an API for managing page tabbing order modifications.
     *
     * @constructor Drupal~TabbingManager
     */
    function TabbingManager() {
  
      /**
       * Tabbing sets are stored as a stack. The active set is at the top of the
       * stack. We use a JavaScript array as if it were a stack; we consider the
       * first element to be the bottom and the last element to be the top. This
       * allows us to use JavaScript's built-in Array.push() and Array.pop()
       * methods.
       *
       * @type {Array.<Drupal~TabbingContext>}
       */
      this.stack = [];
    }
  
    /**
     * Add public methods to the TabbingManager class.
     */
    $.extend(TabbingManager.prototype, /** @lends Drupal~TabbingManager# */{
  
      /**
       * Constrain tabbing to the specified set of elements only.
       *
       * Makes elements outside of the specified set of elements unreachable via
       * the tab key.
       *
       * @param {jQuery} elements
       *   The set of elements to which tabbing should be constrained. Can also
       *   be a jQuery-compatible selector string.
       *
       * @return {Drupal~TabbingContext}
       *   The TabbingContext instance.
       *
       * @fires event:drupalTabbingConstrained
       */
      constrain: function (elements) {
        // Deactivate all tabbingContexts to prepare for the new constraint. A
        // tabbingContext instance will only be reactivated if the stack is
        // unwound to it in the _unwindStack() method.
        var il = this.stack.length;
        for (var i = 0; i < il; i++) {
          this.stack[i].deactivate();
        }
  
        // The "active tabbing set" are the elements tabbing should be constrained
        // to.
        var $elements = $(elements).find(':tabbable').addBack(':tabbable');
  
        var tabbingContext = new TabbingContext({
          // The level is the current height of the stack before this new
          // tabbingContext is pushed on top of the stack.
          level: this.stack.length,
          $tabbableElements: $elements
        });
  
        this.stack.push(tabbingContext);
  
        // Activates the tabbingContext; this will manipulate the DOM to constrain
        // tabbing.
        tabbingContext.activate();
  
        // Allow modules to respond to the constrain event.
        $(document).trigger('drupalTabbingConstrained', tabbingContext);
  
        return tabbingContext;
      },
  
      /**
       * Restores a former tabbingContext when an active one is released.
       *
       * The TabbingManager stack of tabbingContext instances will be unwound
       * from the top-most released tabbingContext down to the first non-released
       * tabbingContext instance. This non-released instance is then activated.
       */
      release: function () {
        // Unwind as far as possible: find the topmost non-released
        // tabbingContext.
        var toActivate = this.stack.length - 1;
        while (toActivate >= 0 && this.stack[toActivate].released) {
          toActivate--;
        }
  
        // Delete all tabbingContexts after the to be activated one. They have
        // already been deactivated, so their effect on the DOM has been reversed.
        this.stack.splice(toActivate + 1);
  
        // Get topmost tabbingContext, if one exists, and activate it.
        if (toActivate >= 0) {
          this.stack[toActivate].activate();
        }
      },
  
      /**
       * Makes all elements outside of the tabbingContext's set untabbable.
       *
       * Elements made untabbable have their original tabindex and autofocus
       * values stored so that they might be restored later when this
       * tabbingContext is deactivated.
       *
       * @param {Drupal~TabbingContext} tabbingContext
       *   The TabbingContext instance that has been activated.
       */
      activate: function (tabbingContext) {
        var $set = tabbingContext.$tabbableElements;
        var level = tabbingContext.level;
        // Determine which elements are reachable via tabbing by default.
        var $disabledSet = $(':tabbable')
          // Exclude elements of the active tabbing set.
          .not($set);
        // Set the disabled set on the tabbingContext.
        tabbingContext.$disabledElements = $disabledSet;
        // Record the tabindex for each element, so we can restore it later.
        var il = $disabledSet.length;
        for (var i = 0; i < il; i++) {
          this.recordTabindex($disabledSet.eq(i), level);
        }
        // Make all tabbable elements outside of the active tabbing set
        // unreachable.
        $disabledSet
          .prop('tabindex', -1)
          .prop('autofocus', false);
  
        // Set focus on an element in the tabbingContext's set of tabbable
        // elements. First, check if there is an element with an autofocus
        // attribute. Select the last one from the DOM order.
        var $hasFocus = $set.filter('[autofocus]').eq(-1);
        // If no element in the tabbable set has an autofocus attribute, select
        // the first element in the set.
        if ($hasFocus.length === 0) {
          $hasFocus = $set.eq(0);
        }
        $hasFocus.trigger('focus');
      },
  
      /**
       * Restores that tabbable state of a tabbingContext's disabled elements.
       *
       * Elements that were made untabbable have their original tabindex and
       * autofocus values restored.
       *
       * @param {Drupal~TabbingContext} tabbingContext
       *   The TabbingContext instance that has been deactivated.
       */
      deactivate: function (tabbingContext) {
        var $set = tabbingContext.$disabledElements;
        var level = tabbingContext.level;
        var il = $set.length;
        for (var i = 0; i < il; i++) {
          this.restoreTabindex($set.eq(i), level);
        }
      },
  
      /**
       * Records the tabindex and autofocus values of an untabbable element.
       *
       * @param {jQuery} $el
       *   The set of elements that have been disabled.
       * @param {number} level
       *   The stack level for which the tabindex attribute should be recorded.
       */
      recordTabindex: function ($el, level) {
        var tabInfo = $el.data('drupalOriginalTabIndices') || {};
        tabInfo[level] = {
          tabindex: $el[0].getAttribute('tabindex'),
          autofocus: $el[0].hasAttribute('autofocus')
        };
        $el.data('drupalOriginalTabIndices', tabInfo);
      },
  
      /**
       * Restores the tabindex and autofocus values of a reactivated element.
       *
       * @param {jQuery} $el
       *   The element that is being reactivated.
       * @param {number} level
       *   The stack level for which the tabindex attribute should be restored.
       */
      restoreTabindex: function ($el, level) {
        var tabInfo = $el.data('drupalOriginalTabIndices');
        if (tabInfo && tabInfo[level]) {
          var data = tabInfo[level];
          if (data.tabindex) {
            $el[0].setAttribute('tabindex', data.tabindex);
          }
          // If the element did not have a tabindex at this stack level then
          // remove it.
          else {
            $el[0].removeAttribute('tabindex');
          }
          if (data.autofocus) {
            $el[0].setAttribute('autofocus', 'autofocus');
          }
  
          // Clean up $.data.
          if (level === 0) {
            // Remove all data.
            $el.removeData('drupalOriginalTabIndices');
          }
          else {
            // Remove the data for this stack level and higher.
            var levelToDelete = level;
            while (tabInfo.hasOwnProperty(levelToDelete)) {
              delete tabInfo[levelToDelete];
              levelToDelete++;
            }
            $el.data('drupalOriginalTabIndices', tabInfo);
          }
        }
      }
    });
  
    /**
     * Stores a set of tabbable elements.
     *
     * This constraint can be removed with the release() method.
     *
     * @constructor Drupal~TabbingContext
     *
     * @param {object} options
     *   A set of initiating values
     * @param {number} options.level
     *   The level in the TabbingManager's stack of this tabbingContext.
     * @param {jQuery} options.$tabbableElements
     *   The DOM elements that should be reachable via the tab key when this
     *   tabbingContext is active.
     * @param {jQuery} options.$disabledElements
     *   The DOM elements that should not be reachable via the tab key when this
     *   tabbingContext is active.
     * @param {bool} options.released
     *   A released tabbingContext can never be activated again. It will be
     *   cleaned up when the TabbingManager unwinds its stack.
     * @param {bool} options.active
     *   When true, the tabbable elements of this tabbingContext will be reachable
     *   via the tab key and the disabled elements will not. Only one
     *   tabbingContext can be active at a time.
     */
    function TabbingContext(options) {
  
      $.extend(this, /** @lends Drupal~TabbingContext# */{
  
        /**
         * @type {?number}
         */
        level: null,
  
        /**
         * @type {jQuery}
         */
        $tabbableElements: $(),
  
        /**
         * @type {jQuery}
         */
        $disabledElements: $(),
  
        /**
         * @type {bool}
         */
        released: false,
  
        /**
         * @type {bool}
         */
        active: false
      }, options);
    }
  
    /**
     * Add public methods to the TabbingContext class.
     */
    $.extend(TabbingContext.prototype, /** @lends Drupal~TabbingContext# */{
  
      /**
       * Releases this TabbingContext.
       *
       * Once a TabbingContext object is released, it can never be activated
       * again.
       *
       * @fires event:drupalTabbingContextReleased
       */
      release: function () {
        if (!this.released) {
          this.deactivate();
          this.released = true;
          Drupal.tabbingManager.release(this);
          // Allow modules to respond to the tabbingContext release event.
          $(document).trigger('drupalTabbingContextReleased', this);
        }
      },
  
      /**
       * Activates this TabbingContext.
       *
       * @fires event:drupalTabbingContextActivated
       */
      activate: function () {
        // A released TabbingContext object can never be activated again.
        if (!this.active && !this.released) {
          this.active = true;
          Drupal.tabbingManager.activate(this);
          // Allow modules to respond to the constrain event.
          $(document).trigger('drupalTabbingContextActivated', this);
        }
      },
  
      /**
       * Deactivates this TabbingContext.
       *
       * @fires event:drupalTabbingContextDeactivated
       */
      deactivate: function () {
        if (this.active) {
          this.active = false;
          Drupal.tabbingManager.deactivate(this);
          // Allow modules to respond to the constrain event.
          $(document).trigger('drupalTabbingContextDeactivated', this);
        }
      }
    });
  
    // Mark this behavior as processed on the first pass and return if it is
    // already processed.
    if (Drupal.tabbingManager) {
      return;
    }
  
    /**
     * @type {Drupal~TabbingManager}
     */
    Drupal.tabbingManager = new TabbingManager();
  
  }(jQuery, Drupal));
  ;
  /**
   * @file
   * Attaches behaviors for the Contextual module's edit toolbar tab.
   */
  
  (function ($, Drupal, Backbone) {
  
    'use strict';
  
    var strings = {
      tabbingReleased: Drupal.t('Tabbing is no longer constrained by the Contextual module.'),
      tabbingConstrained: Drupal.t('Tabbing is constrained to a set of @contextualsCount and the edit mode toggle.'),
      pressEsc: Drupal.t('Press the esc key to exit.')
    };
  
    /**
     * Initializes a contextual link: updates its DOM, sets up model and views.
     *
     * @param {HTMLElement} context
     *   A contextual links DOM element as rendered by the server.
     */
    function initContextualToolbar(context) {
      if (!Drupal.contextual || !Drupal.contextual.collection) {
        return;
      }
  
      var contextualToolbar = Drupal.contextualToolbar;
      var model = contextualToolbar.model = new contextualToolbar.StateModel({
        // Checks whether localStorage indicates we should start in edit mode
        // rather than view mode.
        // @see Drupal.contextualToolbar.VisualView.persist
        isViewing: localStorage.getItem('Drupal.contextualToolbar.isViewing') !== 'false'
      }, {
        contextualCollection: Drupal.contextual.collection
      });
  
      var viewOptions = {
        el: $('.toolbar .toolbar-bar .contextual-toolbar-tab'),
        model: model,
        strings: strings
      };
      new contextualToolbar.VisualView(viewOptions);
      new contextualToolbar.AuralView(viewOptions);
    }
  
    /**
     * Attaches contextual's edit toolbar tab behavior.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches contextual toolbar behavior on a contextualToolbar-init event.
     */
    Drupal.behaviors.contextualToolbar = {
      attach: function (context) {
        if ($('body').once('contextualToolbar-init').length) {
          initContextualToolbar(context);
        }
      }
    };
  
    /**
     * Namespace for the contextual toolbar.
     *
     * @namespace
     */
    Drupal.contextualToolbar = {
  
      /**
       * The {@link Drupal.contextualToolbar.StateModel} instance.
       *
       * @type {?Drupal.contextualToolbar.StateModel}
       */
      model: null
    };
  
  })(jQuery, Drupal, Backbone);
  ;
  /**
   * @file
   * A Backbone Model for the state of Contextual module's edit toolbar tab.
   */
  
  (function (Drupal, Backbone) {
  
    'use strict';
  
    Drupal.contextualToolbar.StateModel = Backbone.Model.extend(/** @lends Drupal.contextualToolbar.StateModel# */{
  
      /**
       * @type {object}
       *
       * @prop {bool} isViewing
       * @prop {bool} isVisible
       * @prop {number} contextualCount
       * @prop {Drupal~TabbingContext} tabbingContext
       */
      defaults: /** @lends Drupal.contextualToolbar.StateModel# */{
  
        /**
         * Indicates whether the toggle is currently in "view" or "edit" mode.
         *
         * @type {bool}
         */
        isViewing: true,
  
        /**
         * Indicates whether the toggle should be visible or hidden. Automatically
         * calculated, depends on contextualCount.
         *
         * @type {bool}
         */
        isVisible: false,
  
        /**
         * Tracks how many contextual links exist on the page.
         *
         * @type {number}
         */
        contextualCount: 0,
  
        /**
         * A TabbingContext object as returned by {@link Drupal~TabbingManager}:
         * the set of tabbable elements when edit mode is enabled.
         *
         * @type {?Drupal~TabbingContext}
         */
        tabbingContext: null
      },
  
      /**
       * Models the state of the edit mode toggle.
       *
       * @constructs
       *
       * @augments Backbone.Model
       *
       * @param {object} attrs
       *   Attributes for the backbone model.
       * @param {object} options
       *   An object with the following option:
       * @param {Backbone.collection} options.contextualCollection
       *   The collection of {@link Drupal.contextual.StateModel} models that
       *   represent the contextual links on the page.
       */
      initialize: function (attrs, options) {
        // Respond to new/removed contextual links.
        this.listenTo(options.contextualCollection, 'reset remove add', this.countContextualLinks);
        this.listenTo(options.contextualCollection, 'add', this.lockNewContextualLinks);
  
        // Automatically determine visibility.
        this.listenTo(this, 'change:contextualCount', this.updateVisibility);
  
        // Whenever edit mode is toggled, lock all contextual links.
        this.listenTo(this, 'change:isViewing', function (model, isViewing) {
          options.contextualCollection.each(function (contextualModel) {
            contextualModel.set('isLocked', !isViewing);
          });
        });
      },
  
      /**
       * Tracks the number of contextual link models in the collection.
       *
       * @param {Drupal.contextual.StateModel} contextualModel
       *   The contextual links model that was added or removed.
       * @param {Backbone.Collection} contextualCollection
       *    The collection of contextual link models.
       */
      countContextualLinks: function (contextualModel, contextualCollection) {
        this.set('contextualCount', contextualCollection.length);
      },
  
      /**
       * Lock newly added contextual links if edit mode is enabled.
       *
       * @param {Drupal.contextual.StateModel} contextualModel
       *   The contextual links model that was added.
       * @param {Backbone.Collection} [contextualCollection]
       *    The collection of contextual link models.
       */
      lockNewContextualLinks: function (contextualModel, contextualCollection) {
        if (!this.get('isViewing')) {
          contextualModel.set('isLocked', true);
        }
      },
  
      /**
       * Automatically updates visibility of the view/edit mode toggle.
       */
      updateVisibility: function () {
        this.set('isVisible', this.get('contextualCount') > 0);
      }
  
    });
  
  })(Drupal, Backbone);
  ;
  /**
   * @file
   * A Backbone View that provides the aural view of the edit mode toggle.
   */
  
  (function ($, Drupal, Backbone, _) {
  
    'use strict';
  
    Drupal.contextualToolbar.AuralView = Backbone.View.extend(/** @lends Drupal.contextualToolbar.AuralView# */{
  
      /**
       * Tracks whether the tabbing constraint announcement has been read once.
       *
       * @type {bool}
       */
      announcedOnce: false,
  
      /**
       * Renders the aural view of the edit mode toggle (screen reader support).
       *
       * @constructs
       *
       * @augments Backbone.View
       *
       * @param {object} options
       *   Options for the view.
       */
      initialize: function (options) {
        this.options = options;
  
        this.listenTo(this.model, 'change', this.render);
        this.listenTo(this.model, 'change:isViewing', this.manageTabbing);
  
        $(document).on('keyup', _.bind(this.onKeypress, this));
      },
  
      /**
       * @inheritdoc
       *
       * @return {Drupal.contextualToolbar.AuralView}
       *   The current contextual toolbar aural view.
       */
      render: function () {
        // Render the state.
        this.$el.find('button').attr('aria-pressed', !this.model.get('isViewing'));
  
        return this;
      },
  
      /**
       * Limits tabbing to the contextual links and edit mode toolbar tab.
       */
      manageTabbing: function () {
        var tabbingContext = this.model.get('tabbingContext');
        // Always release an existing tabbing context.
        if (tabbingContext) {
          tabbingContext.release();
          Drupal.announce(this.options.strings.tabbingReleased);
        }
        // Create a new tabbing context when edit mode is enabled.
        if (!this.model.get('isViewing')) {
          tabbingContext = Drupal.tabbingManager.constrain($('.contextual-toolbar-tab, .contextual'));
          this.model.set('tabbingContext', tabbingContext);
          this.announceTabbingConstraint();
          this.announcedOnce = true;
        }
      },
  
      /**
       * Announces the current tabbing constraint.
       */
      announceTabbingConstraint: function () {
        var strings = this.options.strings;
        Drupal.announce(Drupal.formatString(strings.tabbingConstrained, {
          '@contextualsCount': Drupal.formatPlural(Drupal.contextual.collection.length, '@count contextual link', '@count contextual links')
        }));
        Drupal.announce(strings.pressEsc);
      },
  
      /**
       * Responds to esc and tab key press events.
       *
       * @param {jQuery.Event} event
       *   The keypress event.
       */
      onKeypress: function (event) {
        // The first tab key press is tracked so that an annoucement about tabbing
        // constraints can be raised if edit mode is enabled when the page is
        // loaded.
        if (!this.announcedOnce && event.keyCode === 9 && !this.model.get('isViewing')) {
          this.announceTabbingConstraint();
          // Set announce to true so that this conditional block won't run again.
          this.announcedOnce = true;
        }
        // Respond to the ESC key. Exit out of edit mode.
        if (event.keyCode === 27) {
          this.model.set('isViewing', true);
        }
      }
  
    });
  
  })(jQuery, Drupal, Backbone, _);
  ;
  /**
   * @file
   * A Backbone View that provides the visual view of the edit mode toggle.
   */
  
  (function (Drupal, Backbone) {
  
    'use strict';
  
    Drupal.contextualToolbar.VisualView = Backbone.View.extend(/** @lends Drupal.contextualToolbar.VisualView# */{
  
      /**
       * Events for the Backbone view.
       *
       * @return {object}
       *   A mapping of events to be used in the view.
       */
      events: function () {
        // Prevents delay and simulated mouse events.
        var touchEndToClick = function (event) {
          event.preventDefault();
          event.target.click();
        };
  
        return {
          click: function () {
            this.model.set('isViewing', !this.model.get('isViewing'));
          },
          touchend: touchEndToClick
        };
      },
  
      /**
       * Renders the visual view of the edit mode toggle.
       *
       * Listens to mouse & touch and handles edit mode toggle interactions.
       *
       * @constructs
       *
       * @augments Backbone.View
       */
      initialize: function () {
        this.listenTo(this.model, 'change', this.render);
        this.listenTo(this.model, 'change:isViewing', this.persist);
      },
  
      /**
       * @inheritdoc
       *
       * @return {Drupal.contextualToolbar.VisualView}
       *   The current contextual toolbar visual view.
       */
      render: function () {
        // Render the visibility.
        this.$el.toggleClass('hidden', !this.model.get('isVisible'));
        // Render the state.
        this.$el.find('button').toggleClass('is-active', !this.model.get('isViewing'));
  
        return this;
      },
  
      /**
       * Model change handler; persists the isViewing value to localStorage.
       *
       * `isViewing === true` is the default, so only stores in localStorage when
       * it's not the default value (i.e. false).
       *
       * @param {Drupal.contextualToolbar.StateModel} model
       *   A {@link Drupal.contextualToolbar.StateModel} model.
       * @param {bool} isViewing
       *   The value of the isViewing attribute in the model.
       */
      persist: function (model, isViewing) {
        if (!isViewing) {
          localStorage.setItem('Drupal.contextualToolbar.isViewing', 'false');
        }
        else {
          localStorage.removeItem('Drupal.contextualToolbar.isViewing');
        }
      }
  
    });
  
  })(Drupal, Backbone);
  ;
  /**
   * @file
   * Replaces the home link in toolbar with a back to site link.
   */
  
  (function ($, Drupal, drupalSettings) {
  
    'use strict';
  
    var pathInfo = drupalSettings.path;
    var escapeAdminPath = sessionStorage.getItem('escapeAdminPath');
    var windowLocation = window.location;
  
    // Saves the last non-administrative page in the browser to be able to link
    // back to it when browsing administrative pages. If there is a destination
    // parameter there is not need to save the current path because the page is
    // loaded within an existing "workflow".
    if (!pathInfo.currentPathIsAdmin && !/destination=/.test(windowLocation.search)) {
      sessionStorage.setItem('escapeAdminPath', windowLocation);
    }
  
    /**
     * Replaces the "Home" link with "Back to site" link.
     *
     * Back to site link points to the last non-administrative page the user
     * visited within the same browser tab.
     *
     * @type {Drupal~behavior}
     *
     * @prop {Drupal~behaviorAttach} attach
     *   Attaches the replacement functionality to the toolbar-escape-admin element.
     */
    Drupal.behaviors.escapeAdmin = {
      attach: function () {
        var $toolbarEscape = $('[data-toolbar-escape-admin]').once('escapeAdmin');
        if ($toolbarEscape.length && pathInfo.currentPathIsAdmin) {
          if (escapeAdminPath !== null) {
            $toolbarEscape.attr('href', escapeAdminPath);
          }
          else {
            $toolbarEscape.text(Drupal.t('Home'));
          }
          $toolbarEscape.closest('.toolbar-tab').removeClass('hidden');
        }
      }
    };
  
  })(jQuery, Drupal, drupalSettings);
  ;
  