// source --> https://blue4u.com.br/wp-includes/js/jquery/jquery.min.js?ver=3.6.0 /*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ !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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),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("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(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 de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){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[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.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},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.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},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(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?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===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]||se.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]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(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(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);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\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.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,n){S.fn[n]=function(e,t){return 0 https://blue4u.com.br/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.3.2 /*! jQuery Migrate v3.3.2 | (c) OpenJS Foundation and other contributors | jquery.org/license */ "undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e,window)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery"),window):t(jQuery,window)}(function(s,n){"use strict";function e(e){return 0<=function(e,t){for(var r=/^(\d+)\.(\d+)\.(\d+)/,n=r.exec(e)||[],o=r.exec(t)||[],i=1;i<=3;i++){if(+o[i]<+n[i])return 1;if(+n[i]<+o[i])return-1}return 0}(s.fn.jquery,e)}s.migrateVersion="3.3.2",n.console&&n.console.log&&(s&&e("3.0.0")||n.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),s.migrateWarnings&&n.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),n.console.log("JQMIGRATE: Migrate is installed"+(s.migrateMute?"":" with logging active")+", version "+s.migrateVersion));var r={};function u(e){var t=n.console;s.migrateDeduplicateWarnings&&r[e]||(r[e]=!0,s.migrateWarnings.push(e),t&&t.warn&&!s.migrateMute&&(t.warn("JQMIGRATE: "+e),s.migrateTrace&&t.trace&&t.trace()))}function t(e,t,r,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){return u(n),r},set:function(e){u(n),r=e}})}function o(e,t,r,n){e[t]=function(){return u(n),r.apply(this,arguments)}}s.migrateDeduplicateWarnings=!0,s.migrateWarnings=[],void 0===s.migrateTrace&&(s.migrateTrace=!0),s.migrateReset=function(){r={},s.migrateWarnings.length=0},"BackCompat"===n.document.compatMode&&u("jQuery is not compatible with Quirks Mode");var i,a,c,d={},l=s.fn.init,p=s.find,f=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,y=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,m=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;for(i in s.fn.init=function(e){var t=Array.prototype.slice.call(arguments);return"string"==typeof e&&"#"===e&&(u("jQuery( '#' ) is not a valid selector"),t[0]=[]),l.apply(this,t)},s.fn.init.prototype=s.fn,s.find=function(t){var r=Array.prototype.slice.call(arguments);if("string"==typeof t&&f.test(t))try{n.document.querySelector(t)}catch(e){t=t.replace(y,function(e,t,r,n){return"["+t+r+'"'+n+'"]'});try{n.document.querySelector(t),u("Attribute selector with '#' must be quoted: "+r[0]),r[0]=t}catch(e){u("Attribute selector with '#' was not fixed: "+r[0])}}return p.apply(this,r)},p)Object.prototype.hasOwnProperty.call(p,i)&&(s.find[i]=p[i]);o(s.fn,"size",function(){return this.length},"jQuery.fn.size() is deprecated and removed; use the .length property"),o(s,"parseJSON",function(){return JSON.parse.apply(null,arguments)},"jQuery.parseJSON is deprecated; use JSON.parse"),o(s,"holdReady",s.holdReady,"jQuery.holdReady is deprecated"),o(s,"unique",s.uniqueSort,"jQuery.unique is deprecated; use jQuery.uniqueSort"),t(s.expr,"filters",s.expr.pseudos,"jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),t(s.expr,":",s.expr.pseudos,"jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"),e("3.1.1")&&o(s,"trim",function(e){return null==e?"":(e+"").replace(m,"")},"jQuery.trim is deprecated; use String.prototype.trim"),e("3.2.0")&&(o(s,"nodeName",function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},"jQuery.nodeName is deprecated"),o(s,"isArray",Array.isArray,"jQuery.isArray is deprecated; use Array.isArray")),e("3.3.0")&&(o(s,"isNumeric",function(e){var t=typeof e;return("number"==t||"string"==t)&&!isNaN(e-parseFloat(e))},"jQuery.isNumeric() is deprecated"),s.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){d["[object "+t+"]"]=t.toLowerCase()}),o(s,"type",function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?d[Object.prototype.toString.call(e)]||"object":typeof e},"jQuery.type is deprecated"),o(s,"isFunction",function(e){return"function"==typeof e},"jQuery.isFunction() is deprecated"),o(s,"isWindow",function(e){return null!=e&&e===e.window},"jQuery.isWindow() is deprecated")),s.ajax&&(a=s.ajax,c=/(=)\?(?=&|$)|\?\?/,s.ajax=function(){var e=a.apply(this,arguments);return e.promise&&(o(e,"success",e.done,"jQXHR.success is deprecated and removed"),o(e,"error",e.fail,"jQXHR.error is deprecated and removed"),o(e,"complete",e.always,"jQXHR.complete is deprecated and removed")),e},e("4.0.0")||s.ajaxPrefilter("+json",function(e){!1!==e.jsonp&&(c.test(e.url)||"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&c.test(e.data))&&u("JSON-to-JSONP auto-promotion is deprecated")}));var g=s.fn.removeAttr,h=s.fn.toggleClass,v=/\S+/g;function j(e){return e.replace(/-([a-z])/g,function(e,t){return t.toUpperCase()})}s.fn.removeAttr=function(e){var r=this;return s.each(e.match(v),function(e,t){s.expr.match.bool.test(t)&&(u("jQuery.fn.removeAttr no longer sets boolean properties: "+t),r.prop(t,!1))}),g.apply(this,arguments)};var Q,b=!(s.fn.toggleClass=function(t){return void 0!==t&&"boolean"!=typeof t?h.apply(this,arguments):(u("jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var e=this.getAttribute&&this.getAttribute("class")||"";e&&s.data(this,"__className__",e),this.setAttribute&&this.setAttribute("class",!e&&!1!==t&&s.data(this,"__className__")||"")}))}),w=/^[a-z]/,x=/^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;s.swap&&s.each(["height","width","reliableMarginRight"],function(e,t){var r=s.cssHooks[t]&&s.cssHooks[t].get;r&&(s.cssHooks[t].get=function(){var e;return b=!0,e=r.apply(this,arguments),b=!1,e})}),s.swap=function(e,t,r,n){var o,i,a={};for(i in b||u("jQuery.swap() is undocumented and deprecated"),t)a[i]=e.style[i],e.style[i]=t[i];for(i in o=r.apply(e,n||[]),t)e.style[i]=a[i];return o},e("3.4.0")&&"undefined"!=typeof Proxy&&(s.cssProps=new Proxy(s.cssProps||{},{set:function(){return u("JQMIGRATE: jQuery.cssProps is deprecated"),Reflect.set.apply(this,arguments)}})),s.cssNumber||(s.cssNumber={}),Q=s.fn.css,s.fn.css=function(e,t){var r,n,o=this;return e&&"object"==typeof e&&!Array.isArray(e)?(s.each(e,function(e,t){s.fn.css.call(o,e,t)}),this):("number"==typeof t&&(r=j(e),n=r,w.test(n)&&x.test(n[0].toUpperCase()+n.slice(1))||s.cssNumber[r]||u('Number-typed values are deprecated for jQuery.fn.css( "'+e+'", value )')),Q.apply(this,arguments))};var A,k,S,M,N=s.data;s.data=function(e,t,r){var n,o,i;if(t&&"object"==typeof t&&2===arguments.length){for(i in n=s.hasData(e)&&N.call(this,e),o={},t)i!==j(i)?(u("jQuery.data() always sets/gets camelCased names: "+i),n[i]=t[i]):o[i]=t[i];return N.call(this,e,o),t}return t&&"string"==typeof t&&t!==j(t)&&(n=s.hasData(e)&&N.call(this,e))&&t in n?(u("jQuery.data() always sets/gets camelCased names: "+t),2");t!==e&&T(e)!==T(t)&&u("HTML tags must be properly nested and closed: "+e)}var O=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,q=s.htmlPrefilter;s.UNSAFE_restoreLegacyHtmlPrefilter=function(){s.htmlPrefilter=function(e){return P(e),e.replace(O,"<$1>")}},s.htmlPrefilter=function(e){return P(e),q(e)};var D,_=s.fn.offset;s.fn.offset=function(){var e=this[0];return!e||e.nodeType&&e.getBoundingClientRect?_.apply(this,arguments):(u("jQuery.fn.offset() requires a valid DOM element"),arguments.length?this:void 0)},s.ajax&&(D=s.param,s.param=function(e,t){var r=s.ajaxSettings&&s.ajaxSettings.traditional;return void 0===t&&r&&(u("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),t=r),D.call(this,e,t)});var E,F,J=s.fn.andSelf||s.fn.addBack;return s.fn.andSelf=function(){return u("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),J.apply(this,arguments)},s.Deferred&&(E=s.Deferred,F=[["resolve","done",s.Callbacks("once memory"),s.Callbacks("once memory"),"resolved"],["reject","fail",s.Callbacks("once memory"),s.Callbacks("once memory"),"rejected"],["notify","progress",s.Callbacks("memory"),s.Callbacks("memory")]],s.Deferred=function(e){var i=E(),a=i.promise();return i.pipe=a.pipe=function(){var o=arguments;return u("deferred.pipe() is deprecated"),s.Deferred(function(n){s.each(F,function(e,t){var r="function"==typeof o[e]&&o[e];i[t[1]](function(){var e=r&&r.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[t[0]+"With"](this===a?n.promise():this,r?[e]:arguments)})}),o=null}).promise()},e&&e.call(i,i),i},s.Deferred.exceptionHook=E.exceptionHook),s}); // source --> https://blue4u.com.br/wp-content/plugins/smart-logo-showcase-lite/js/owl.carousel.js?ver=1.1.8 /** * Owl carousel * @version 2.0.0 * @author Bartosz Wojciechowski * @license The MIT License (MIT) * @todo Lazy Load Icon * @todo prevent animationend bubling * @todo itemsScaleUp * @todo Test Zepto * @todo stagePadding calculate wrong active classes */ ;(function($, window, document, undefined) { var drag, state, e; /** * Template for status information about drag and touch events. * @private */ drag = { start: 0, startX: 0, startY: 0, current: 0, currentX: 0, currentY: 0, offsetX: 0, offsetY: 0, distance: null, startTime: 0, endTime: 0, updatedX: 0, targetEl: null }; /** * Template for some status informations. * @private */ state = { isTouch: false, isScrolling: false, isSwiping: false, direction: false, inMotion: false }; /** * Event functions references. * @private */ e = { _onDragStart: null, _onDragMove: null, _onDragEnd: null, _transitionEnd: null, _resizer: null, _responsiveCall: null, _goToLoop: null, _checkVisibile: null }; /** * Creates a carousel. * @class The Owl Carousel. * @public * @param {HTMLElement|jQuery} element - The element to create the carousel for. * @param {Object} [options] - The options */ function Owl(element, options) { /** * Current settings for the carousel. * @public */ this.settings = null; /** * Current options set by the caller including defaults. * @public */ this.options = $.extend({}, Owl.Defaults, options); /** * Plugin element. * @public */ this.$element = $(element); /** * Caches informations about drag and touch events. */ this.drag = $.extend({}, drag); /** * Caches some status informations. * @protected */ this.state = $.extend({}, state); /** * @protected * @todo Must be documented */ this.e = $.extend({}, e); /** * References to the running plugins of this carousel. * @protected */ this._plugins = {}; /** * Currently suppressed events to prevent them from beeing retriggered. * @protected */ this._supress = {}; /** * Absolute current position. * @protected */ this._current = null; /** * Animation speed in milliseconds. * @protected */ this._speed = null; /** * Coordinates of all items in pixel. * @todo The name of this member is missleading. * @protected */ this._coordinates = []; /** * Current breakpoint. * @todo Real media queries would be nice. * @protected */ this._breakpoint = null; /** * Current width of the plugin element. */ this._width = null; /** * All real items. * @protected */ this._items = []; /** * All cloned items. * @protected */ this._clones = []; /** * Merge values of all items. * @todo Maybe this could be part of a plugin. * @protected */ this._mergers = []; /** * Invalidated parts within the update process. * @protected */ this._invalidated = {}; /** * Ordered list of workers for the update process. * @protected */ this._pipe = []; $.each(Owl.Plugins, $.proxy(function(key, plugin) { this._plugins[key[0].toLowerCase() + key.slice(1)] = new plugin(this); }, this)); $.each(Owl.Pipe, $.proxy(function(priority, worker) { this._pipe.push({ 'filter': worker.filter, 'run': $.proxy(worker.run, this) }); }, this)); this.setup(); this.initialize(); } /** * Default options for the carousel. * @public */ Owl.Defaults = { items: 3, loop: false, center: false, mouseDrag: true, touchDrag: true, pullDrag: true, freeDrag: false, margin: 0, stagePadding: 0, merge: false, mergeFit: true, autoWidth: false, startPosition: 0, rtl: false, smartSpeed: 250, fluidSpeed: false, dragEndSpeed: false, responsive: {}, responsiveRefreshRate: 200, responsiveBaseElement: window, responsiveClass: false, fallbackEasing: 'swing', info: false, nestedItemSelector: false, itemElement: 'div', stageElement: 'div', // Classes and Names themeClass: 'owl-theme', baseClass: 'owl-carousel', itemClass: 'owl-item', centerClass: 'center', activeClass: 'active' }; /** * Enumeration for width. * @public * @readonly * @enum {String} */ Owl.Width = { Default: 'default', Inner: 'inner', Outer: 'outer' }; /** * Contains all registered plugins. * @public */ Owl.Plugins = {}; /** * Update pipe. */ Owl.Pipe = [ { filter: [ 'width', 'items', 'settings' ], run: function(cache) { cache.current = this._items && this._items[this.relative(this._current)]; } }, { filter: [ 'items', 'settings' ], run: function() { var cached = this._clones, clones = this.$stage.children('.cloned'); if (clones.length !== cached.length || (!this.settings.loop && cached.length > 0)) { this.$stage.children('.cloned').remove(); this._clones = []; } } }, { filter: [ 'items', 'settings' ], run: function() { var i, n, clones = this._clones, items = this._items, delta = this.settings.loop ? clones.length - Math.max(this.settings.items * 2, 4) : 0; for (i = 0, n = Math.abs(delta / 2); i < n; i++) { if (delta > 0) { this.$stage.children().eq(items.length + clones.length - 1).remove(); clones.pop(); this.$stage.children().eq(0).remove(); clones.pop(); } else { clones.push(clones.length / 2); this.$stage.append(items[clones[clones.length - 1]].clone().addClass('cloned')); clones.push(items.length - 1 - (clones.length - 1) / 2); this.$stage.prepend(items[clones[clones.length - 1]].clone().addClass('cloned')); } } } }, { filter: [ 'width', 'items', 'settings' ], run: function() { var rtl = (this.settings.rtl ? 1 : -1), width = (this.width() / this.settings.items).toFixed(3), coordinate = 0, merge, i, n; this._coordinates = []; for (i = 0, n = this._clones.length + this._items.length; i < n; i++) { merge = this._mergers[this.relative(i)]; merge = (this.settings.mergeFit && Math.min(merge, this.settings.items)) || merge; coordinate += (this.settings.autoWidth ? this._items[this.relative(i)].width() + this.settings.margin : width * merge) * rtl; this._coordinates.push(coordinate); } } }, { filter: [ 'width', 'items', 'settings' ], run: function() { var i, n, width = (this.width() / this.settings.items).toFixed(3), css = { 'width': Math.abs(this._coordinates[this._coordinates.length - 1]) + this.settings.stagePadding * 2, 'padding-left': this.settings.stagePadding || '', 'padding-right': this.settings.stagePadding || '' }; this.$stage.css(css); css = { 'width': this.settings.autoWidth ? 'auto' : width - this.settings.margin }; css[this.settings.rtl ? 'margin-left' : 'margin-right'] = this.settings.margin; if (!this.settings.autoWidth && $.grep(this._mergers, function(v) { return v > 1 }).length > 0) { for (i = 0, n = this._coordinates.length; i < n; i++) { css.width = Math.abs(this._coordinates[i]) - Math.abs(this._coordinates[i - 1] || 0) - this.settings.margin; this.$stage.children().eq(i).css(css); } } else { this.$stage.children().css(css); } } }, { filter: [ 'width', 'items', 'settings' ], run: function(cache) { cache.current && this.reset(this.$stage.children().index(cache.current)); } }, { filter: [ 'position' ], run: function() { this.animate(this.coordinates(this._current)); } }, { filter: [ 'width', 'position', 'items', 'settings' ], run: function() { var rtl = this.settings.rtl ? 1 : -1, padding = this.settings.stagePadding * 2, begin = this.coordinates(this.current()) + padding, end = begin + this.width() * rtl, inner, outer, matches = [], i, n; for (i = 0, n = this._coordinates.length; i < n; i++) { inner = this._coordinates[i - 1] || 0; outer = Math.abs(this._coordinates[i]) + padding * rtl; if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { matches.push(i); } } this.$stage.children('.' + this.settings.activeClass).removeClass(this.settings.activeClass); this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass(this.settings.activeClass); if (this.settings.center) { this.$stage.children('.' + this.settings.centerClass).removeClass(this.settings.centerClass); this.$stage.children().eq(this.current()).addClass(this.settings.centerClass); } } } ]; /** * Initializes the carousel. * @protected */ Owl.prototype.initialize = function() { this.trigger('initialize'); this.$element .addClass(this.settings.baseClass) .addClass(this.settings.themeClass) .toggleClass('owl-rtl', this.settings.rtl); // check support this.browserSupport(); if (this.settings.autoWidth && this.state.imagesLoaded !== true) { var imgs, nestedSelector, width; imgs = this.$element.find('img'); nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; width = this.$element.children(nestedSelector).width(); if (imgs.length && width <= 0) { this.preloadAutoWidthImages(imgs); return false; } } this.$element.addClass('owl-loading'); // create stage this.$stage = $('<' + this.settings.stageElement + ' class="owl-stage"/>') .wrap('
'); // append stage this.$element.append(this.$stage.parent()); // append content this.replace(this.$element.children().not(this.$stage.parent())); // set view width this._width = this.$element.width(); // update view this.refresh(); this.$element.removeClass('owl-loading').addClass('owl-loaded'); // attach generic events this.eventsCall(); // attach generic events this.internalEvents(); // attach custom control events this.addTriggerableEvents(); this.trigger('initialized'); }; /** * Setups the current settings. * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? * @todo Support for media queries by using `matchMedia` would be nice. * @public */ Owl.prototype.setup = function() { var viewport = this.viewport(), overwrites = this.options.responsive, match = -1, settings = null; if (!overwrites) { settings = $.extend({}, this.options); } else { $.each(overwrites, function(breakpoint) { if (breakpoint <= viewport && breakpoint > match) { match = Number(breakpoint); } }); settings = $.extend({}, this.options, overwrites[match]); delete settings.responsive; // responsive class if (settings.responsiveClass) { this.$element.attr('class', function(i, c) { return c.replace(/\b owl-responsive-\S+/g, ''); }).addClass('owl-responsive-' + match); } } if (this.settings === null || this._breakpoint !== match) { this.trigger('change', { property: { name: 'settings', value: settings } }); this._breakpoint = match; this.settings = settings; this.invalidate('settings'); this.trigger('changed', { property: { name: 'settings', value: this.settings } }); } }; /** * Updates option logic if necessery. * @protected */ Owl.prototype.optionsLogic = function() { // Toggle Center class this.$element.toggleClass('owl-center', this.settings.center); // if items number is less than in body if (this.settings.loop && this._items.length < this.settings.items) { this.settings.loop = false; } if (this.settings.autoWidth) { this.settings.stagePadding = false; this.settings.merge = false; } }; /** * Prepares an item before add. * @todo Rename event parameter `content` to `item`. * @protected * @returns {jQuery|HTMLElement} - The item container. */ Owl.prototype.prepare = function(item) { var event = this.trigger('prepare', { content: item }); if (!event.data) { event.data = $('<' + this.settings.itemElement + '/>') .addClass(this.settings.itemClass).append(item) } this.trigger('prepared', { content: event.data }); return event.data; }; /** * Updates the view. * @public */ Owl.prototype.update = function() { var i = 0, n = this._pipe.length, filter = $.proxy(function(p) { return this[p] }, this._invalidated), cache = {}; while (i < n) { if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { this._pipe[i].run(cache); } i++; } this._invalidated = {}; }; /** * Gets the width of the view. * @public * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. * @returns {Number} - The width of the view in pixel. */ Owl.prototype.width = function(dimension) { dimension = dimension || Owl.Width.Default; switch (dimension) { case Owl.Width.Inner: case Owl.Width.Outer: return this._width; default: return this._width - this.settings.stagePadding * 2 + this.settings.margin; } }; /** * Refreshes the carousel primarily for adaptive purposes. * @public */ Owl.prototype.refresh = function() { if (this._items.length === 0) { return false; } var start = new Date().getTime(); this.trigger('refresh'); this.setup(); this.optionsLogic(); // hide and show methods helps here to set a proper widths, // this prevents scrollbar to be calculated in stage width this.$stage.addClass('owl-refresh'); this.update(); this.$stage.removeClass('owl-refresh'); this.state.orientation = window.orientation; this.watchVisibility(); this.trigger('refreshed'); }; /** * Save internal event references and add event based functions. * @protected */ Owl.prototype.eventsCall = function() { // Save events references this.e._onDragStart = $.proxy(function(e) { this.onDragStart(e); }, this); this.e._onDragMove = $.proxy(function(e) { this.onDragMove(e); }, this); this.e._onDragEnd = $.proxy(function(e) { this.onDragEnd(e); }, this); this.e._onResize = $.proxy(function(e) { this.onResize(e); }, this); this.e._transitionEnd = $.proxy(function(e) { this.transitionEnd(e); }, this); this.e._preventClick = $.proxy(function(e) { this.preventClick(e); }, this); }; /** * Checks window `resize` event. * @protected */ Owl.prototype.onThrottledResize = function() { window.clearTimeout(this.resizeTimer); this.resizeTimer = window.setTimeout(this.e._onResize, this.settings.responsiveRefreshRate); }; /** * Checks window `resize` event. * @protected */ Owl.prototype.onResize = function() { if (!this._items.length) { return false; } if (this._width === this.$element.width()) { return false; } if (this.trigger('resize').isDefaultPrevented()) { return false; } this._width = this.$element.width(); this.invalidate('width'); this.refresh(); this.trigger('resized'); }; /** * Checks for touch/mouse drag event type and add run event handlers. * @protected */ Owl.prototype.eventsRouter = function(event) { var type = event.type; if (type === "mousedown" || type === "touchstart") { this.onDragStart(event); } else if (type === "mousemove" || type === "touchmove") { this.onDragMove(event); } else if (type === "mouseup" || type === "touchend") { this.onDragEnd(event); } else if (type === "touchcancel") { this.onDragEnd(event); } }; /** * Checks for touch/mouse drag options and add necessery event handlers. * @protected */ Owl.prototype.internalEvents = function() { var isTouch = isTouchSupport(), isTouchIE = isTouchSupportIE(); if (this.settings.mouseDrag){ this.$stage.on('mousedown', $.proxy(function(event) { this.eventsRouter(event) }, this)); this.$stage.on('dragstart', function() { return false }); this.$stage.get(0).onselectstart = function() { return false }; } else { this.$element.addClass('owl-text-select-on'); } if (this.settings.touchDrag && !isTouchIE){ this.$stage.on('touchstart touchcancel', $.proxy(function(event) { this.eventsRouter(event) }, this)); } // catch transitionEnd event if (this.transitionEndVendor) { this.on(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd, false); } // responsive if (this.settings.responsive !== false) { this.on(window, 'resize', $.proxy(this.onThrottledResize, this)); } }; /** * Handles touchstart/mousedown event. * @protected * @param {Event} event - The event arguments. */ Owl.prototype.onDragStart = function(event) { var ev, isTouchEvent, pageX, pageY, animatedPos; ev = event.originalEvent || event || window.event; // prevent right click if (ev.which === 3 || this.state.isTouch) { return false; } if (ev.type === 'mousedown') { this.$stage.addClass('owl-grab'); } this.trigger('drag'); this.drag.startTime = new Date().getTime(); this.speed(0); this.state.isTouch = true; this.state.isScrolling = false; this.state.isSwiping = false; this.drag.distance = 0; pageX = getTouches(ev).x; pageY = getTouches(ev).y; // get stage position left this.drag.offsetX = this.$stage.position().left; this.drag.offsetY = this.$stage.position().top; if (this.settings.rtl) { this.drag.offsetX = this.$stage.position().left + this.$stage.width() - this.width() + this.settings.margin; } // catch position // ie to fix if (this.state.inMotion && this.support3d) { animatedPos = this.getTransformProperty(); this.drag.offsetX = animatedPos; this.animate(animatedPos); this.state.inMotion = true; } else if (this.state.inMotion && !this.support3d) { this.state.inMotion = false; return false; } this.drag.startX = pageX - this.drag.offsetX; this.drag.startY = pageY - this.drag.offsetY; this.drag.start = pageX - this.drag.startX; this.drag.targetEl = ev.target || ev.srcElement; this.drag.updatedX = this.drag.start; // to do/check // prevent links and images dragging; if (this.drag.targetEl.tagName === "IMG" || this.drag.targetEl.tagName === "A") { this.drag.targetEl.draggable = false; } $(document).on('mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents', $.proxy(function(event) {this.eventsRouter(event)},this)); }; /** * Handles the touchmove/mousemove events. * @todo Simplify * @protected * @param {Event} event - The event arguments. */ Owl.prototype.onDragMove = function(event) { var ev, isTouchEvent, pageX, pageY, minValue, maxValue, pull; if (!this.state.isTouch) { return; } if (this.state.isScrolling) { return; } ev = event.originalEvent || event || window.event; pageX = getTouches(ev).x; pageY = getTouches(ev).y; // Drag Direction this.drag.currentX = pageX - this.drag.startX; this.drag.currentY = pageY - this.drag.startY; this.drag.distance = this.drag.currentX - this.drag.offsetX; // Check move direction if (this.drag.distance < 0) { this.state.direction = this.settings.rtl ? 'right' : 'left'; } else if (this.drag.distance > 0) { this.state.direction = this.settings.rtl ? 'left' : 'right'; } // Loop if (this.settings.loop) { if (this.op(this.drag.currentX, '>', this.coordinates(this.minimum())) && this.state.direction === 'right') { this.drag.currentX -= (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length); } else if (this.op(this.drag.currentX, '<', this.coordinates(this.maximum())) && this.state.direction === 'left') { this.drag.currentX += (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length); } } else { // pull minValue = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); maxValue = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); pull = this.settings.pullDrag ? this.drag.distance / 5 : 0; this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull); } // Lock browser if swiping horizontal if ((this.drag.distance > 8 || this.drag.distance < -8)) { if (ev.preventDefault !== undefined) { ev.preventDefault(); } else { ev.returnValue = false; } this.state.isSwiping = true; } this.drag.updatedX = this.drag.currentX; // Lock Owl if scrolling if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) { this.state.isScrolling = true; this.drag.updatedX = this.drag.start; } this.animate(this.drag.updatedX); }; /** * Handles the touchend/mouseup events. * @protected */ Owl.prototype.onDragEnd = function(event) { var compareTimes, distanceAbs, closest; if (!this.state.isTouch) { return; } if (event.type === 'mouseup') { this.$stage.removeClass('owl-grab'); } this.trigger('dragged'); // prevent links and images dragging; this.drag.targetEl.removeAttribute("draggable"); // remove drag event listeners this.state.isTouch = false; this.state.isScrolling = false; this.state.isSwiping = false; // to check if (this.drag.distance === 0 && this.state.inMotion !== true) { this.state.inMotion = false; return false; } // prevent clicks while scrolling this.drag.endTime = new Date().getTime(); compareTimes = this.drag.endTime - this.drag.startTime; distanceAbs = Math.abs(this.drag.distance); // to test if (distanceAbs > 3 || compareTimes > 300) { this.removeClick(this.drag.targetEl); } closest = this.closest(this.drag.updatedX); this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); this.current(closest); this.invalidate('position'); this.update(); // if pullDrag is off then fire transitionEnd event manually when stick // to border if (!this.settings.pullDrag && this.drag.updatedX === this.coordinates(closest)) { this.transitionEnd(); } this.drag.distance = 0; $(document).off('.owl.dragEvents'); }; /** * Attaches `preventClick` to disable link while swipping. * @protected * @param {HTMLElement} [target] - The target of the `click` event. */ Owl.prototype.removeClick = function(target) { this.drag.targetEl = target; $(target).on('click.preventClick', this.e._preventClick); // to make sure click is removed: window.setTimeout(function() { $(target).off('click.preventClick'); }, 300); }; /** * Suppresses click event. * @protected * @param {Event} ev - The event arguments. */ Owl.prototype.preventClick = function(ev) { if (ev.preventDefault) { ev.preventDefault(); } else { ev.returnValue = false; } if (ev.stopPropagation) { ev.stopPropagation(); } $(ev.target).off('click.preventClick'); }; /** * Catches stage position while animate (only CSS3). * @protected * @returns */ Owl.prototype.getTransformProperty = function() { var transform, matrix3d; transform = window.getComputedStyle(this.$stage.get(0), null).getPropertyValue(this.vendorName + 'transform'); // var transform = this.$stage.css(this.vendorName + 'transform') transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(','); matrix3d = transform.length === 16; return matrix3d !== true ? transform[4] : transform[12]; }; /** * Gets absolute position of the closest item for a coordinate. * @todo Setting `freeDrag` makes `closest` not reusable. See #165. * @protected * @param {Number} coordinate - The coordinate in pixel. * @return {Number} - The absolute position of the closest item. */ Owl.prototype.closest = function(coordinate) { var position = -1, pull = 30, width = this.width(), coordinates = this.coordinates(); if (!this.settings.freeDrag) { // check closest item $.each(coordinates, $.proxy(function(index, value) { if (coordinate > value - pull && coordinate < value + pull) { position = index; } else if (this.op(coordinate, '<', value) && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { position = this.state.direction === 'left' ? index + 1 : index; } return position === -1; }, this)); } if (!this.settings.loop) { // non loop boundries if (this.op(coordinate, '>', coordinates[this.minimum()])) { position = coordinate = this.minimum(); } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { position = coordinate = this.maximum(); } } return position; }; /** * Animates the stage. * @public * @param {Number} coordinate - The coordinate in pixels. */ Owl.prototype.animate = function(coordinate) { this.trigger('translate'); this.state.inMotion = this.speed() > 0; if (this.support3d) { this.$stage.css({ transform: 'translate3d(' + coordinate + 'px' + ',0px, 0px)', transition: (this.speed() / 1000) + 's' }); } else if (this.state.isTouch) { this.$stage.css({ left: coordinate + 'px' }); } else { this.$stage.animate({ left: coordinate }, this.speed() / 1000, this.settings.fallbackEasing, $.proxy(function() { if (this.state.inMotion) { this.transitionEnd(); } }, this)); } }; /** * Sets the absolute position of the current item. * @public * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. * @returns {Number} - The absolute position of the current item. */ Owl.prototype.current = function(position) { if (position === undefined) { return this._current; } if (this._items.length === 0) { return undefined; } position = this.normalize(position); if (this._current !== position) { var event = this.trigger('change', { property: { name: 'position', value: position } }); if (event.data !== undefined) { position = this.normalize(event.data); } this._current = position; this.invalidate('position'); this.trigger('changed', { property: { name: 'position', value: this._current } }); } return this._current; }; /** * Invalidates the given part of the update routine. * @param {String} part - The part to invalidate. */ Owl.prototype.invalidate = function(part) { this._invalidated[part] = true; } /** * Resets the absolute position of the current item. * @public * @param {Number} position - The absolute position of the new item. */ Owl.prototype.reset = function(position) { position = this.normalize(position); if (position === undefined) { return; } this._speed = 0; this._current = position; this.suppress([ 'translate', 'translated' ]); this.animate(this.coordinates(position)); this.release([ 'translate', 'translated' ]); }; /** * Normalizes an absolute or a relative position for an item. * @public * @param {Number} position - The absolute or relative position to normalize. * @param {Boolean} [relative=false] - Whether the given position is relative or not. * @returns {Number} - The normalized position. */ Owl.prototype.normalize = function(position, relative) { var n = (relative ? this._items.length : this._items.length + this._clones.length); if (!$.isNumeric(position) || n < 1) { return undefined; } if (this._clones.length) { position = ((position % n) + n) % n; } else { position = Math.max(this.minimum(relative), Math.min(this.maximum(relative), position)); } return position; }; /** * Converts an absolute position for an item into a relative position. * @public * @param {Number} position - The absolute position to convert. * @returns {Number} - The converted position. */ Owl.prototype.relative = function(position) { position = this.normalize(position); position = position - this._clones.length / 2; return this.normalize(position, true); }; /** * Gets the maximum position for an item. * @public * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. * @returns {Number} */ Owl.prototype.maximum = function(relative) { var maximum, width, i = 0, coordinate, settings = this.settings; if (relative) { return this._items.length - 1; } if (!settings.loop && settings.center) { maximum = this._items.length - 1; } else if (!settings.loop && !settings.center) { maximum = this._items.length - settings.items; } else if (settings.loop || settings.center) { maximum = this._items.length + settings.items; } else if (settings.autoWidth || settings.merge) { revert = settings.rtl ? 1 : -1; width = this.$stage.width() - this.$element.width(); while (coordinate = this.coordinates(i)) { if (coordinate * revert >= width) { break; } maximum = ++i; } } else { throw 'Can not detect maximum absolute position.' } return maximum; }; /** * Gets the minimum position for an item. * @public * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. * @returns {Number} */ Owl.prototype.minimum = function(relative) { if (relative) { return 0; } return this._clones.length / 2; }; /** * Gets an item at the specified relative position. * @public * @param {Number} [position] - The relative position of the item. * @return {jQuery|Array.} - The item at the given position or all items if no position was given. */ Owl.prototype.items = function(position) { if (position === undefined) { return this._items.slice(); } position = this.normalize(position, true); return this._items[position]; }; /** * Gets an item at the specified relative position. * @public * @param {Number} [position] - The relative position of the item. * @return {jQuery|Array.} - The item at the given position or all items if no position was given. */ Owl.prototype.mergers = function(position) { if (position === undefined) { return this._mergers.slice(); } position = this.normalize(position, true); return this._mergers[position]; }; /** * Gets the absolute positions of clones for an item. * @public * @param {Number} [position] - The relative position of the item. * @returns {Array.} - The absolute positions of clones for the item or all if no position was given. */ Owl.prototype.clones = function(position) { var odd = this._clones.length / 2, even = odd + this._items.length, map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; if (position === undefined) { return $.map(this._clones, function(v, i) { return map(i) }); } return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); }; /** * Sets the current animation speed. * @public * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. * @returns {Number} - The current animation speed in milliseconds. */ Owl.prototype.speed = function(speed) { if (speed !== undefined) { this._speed = speed; } return this._speed; }; /** * Gets the coordinate of an item. * @todo The name of this method is missleanding. * @public * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. * @returns {Number|Array.} - The coordinate of the item in pixel or all coordinates. */ Owl.prototype.coordinates = function(position) { var coordinate = null; if (position === undefined) { return $.map(this._coordinates, $.proxy(function(coordinate, index) { return this.coordinates(index); }, this)); } if (this.settings.center) { coordinate = this._coordinates[position]; coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); } else { coordinate = this._coordinates[position - 1] || 0; } return coordinate; }; /** * Calculates the speed for a translation. * @protected * @param {Number} from - The absolute position of the start item. * @param {Number} to - The absolute position of the target item. * @param {Number} [factor=undefined] - The time factor in milliseconds. * @returns {Number} - The time in milliseconds for the translation. */ Owl.prototype.duration = function(from, to, factor) { return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); }; /** * Slides to the specified item. * @public * @param {Number} position - The position of the item. * @param {Number} [speed] - The time in milliseconds for the transition. */ Owl.prototype.to = function(position, speed) { if (this.settings.loop) { var distance = position - this.relative(this.current()), revert = this.current(), before = this.current(), after = this.current() + distance, direction = before - after < 0 ? true : false, items = this._clones.length + this._items.length; if (after < this.settings.items && direction === false) { revert = before + this._items.length; this.reset(revert); } else if (after >= items - this.settings.items && direction === true) { revert = before - this._items.length; this.reset(revert); } window.clearTimeout(this.e._goToLoop); this.e._goToLoop = window.setTimeout($.proxy(function() { this.speed(this.duration(this.current(), revert + distance, speed)); this.current(revert + distance); this.update(); }, this), 30); } else { this.speed(this.duration(this.current(), position, speed)); this.current(position); this.update(); } }; /** * Slides to the next item. * @public * @param {Number} [speed] - The time in milliseconds for the transition. */ Owl.prototype.next = function(speed) { speed = speed || false; this.to(this.relative(this.current()) + 1, speed); }; /** * Slides to the previous item. * @public * @param {Number} [speed] - The time in milliseconds for the transition. */ Owl.prototype.prev = function(speed) { speed = speed || false; this.to(this.relative(this.current()) - 1, speed); }; /** * Handles the end of an animation. * @protected * @param {Event} event - The event arguments. */ Owl.prototype.transitionEnd = function(event) { // if css2 animation then event object is undefined if (event !== undefined) { event.stopPropagation(); // Catch only owl-stage transitionEnd event if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { return false; } } this.state.inMotion = false; this.trigger('translated'); }; /** * Gets viewport width. * @protected * @return {Number} - The width in pixel. */ Owl.prototype.viewport = function() { var width; if (this.options.responsiveBaseElement !== window) { width = $(this.options.responsiveBaseElement).width(); } else if (window.innerWidth) { width = window.innerWidth; } else if (document.documentElement && document.documentElement.clientWidth) { width = document.documentElement.clientWidth; } else { throw 'Can not detect viewport width.'; } return width; }; /** * Replaces the current content. * @public * @param {HTMLElement|jQuery|String} content - The new content. */ Owl.prototype.replace = function(content) { this.$stage.empty(); this._items = []; if (content) { content = (content instanceof jQuery) ? content : $(content); } if (this.settings.nestedItemSelector) { content = content.find('.' + this.settings.nestedItemSelector); } content.filter(function() { return this.nodeType === 1; }).each($.proxy(function(index, item) { item = this.prepare(item); this.$stage.append(item); this._items.push(item); this._mergers.push(item.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); }, this)); this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); this.invalidate('items'); }; /** * Adds an item. * @todo Use `item` instead of `content` for the event arguments. * @public * @param {HTMLElement|jQuery|String} content - The item content to add. * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. */ Owl.prototype.add = function(content, position) { position = position === undefined ? this._items.length : this.normalize(position, true); this.trigger('add', { content: content, position: position }); if (this._items.length === 0 || position === this._items.length) { this.$stage.append(content); this._items.push(content); this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); } else { this._items[position].before(content); this._items.splice(position, 0, content); this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); } this.invalidate('items'); this.trigger('added', { content: content, position: position }); }; /** * Removes an item by its position. * @todo Use `item` instead of `content` for the event arguments. * @public * @param {Number} position - The relative position of the item to remove. */ Owl.prototype.remove = function(position) { position = this.normalize(position, true); if (position === undefined) { return; } this.trigger('remove', { content: this._items[position], position: position }); this._items[position].remove(); this._items.splice(position, 1); this._mergers.splice(position, 1); this.invalidate('items'); this.trigger('removed', { content: null, position: position }); }; /** * Adds triggerable events. * @protected */ Owl.prototype.addTriggerableEvents = function() { var handler = $.proxy(function(callback, event) { return $.proxy(function(e) { if (e.relatedTarget !== this) { this.suppress([ event ]); callback.apply(this, [].slice.call(arguments, 1)); this.release([ event ]); } }, this); }, this); $.each({ 'next': this.next, 'prev': this.prev, 'to': this.to, 'destroy': this.destroy, 'refresh': this.refresh, 'replace': this.replace, 'add': this.add, 'remove': this.remove }, $.proxy(function(event, callback) { this.$element.on(event + '.owl.carousel', handler(callback, event + '.owl.carousel')); }, this)); }; /** * Watches the visibility of the carousel element. * @protected */ Owl.prototype.watchVisibility = function() { // test on zepto if (!isElVisible(this.$element.get(0))) { this.$element.addClass('owl-hidden'); window.clearInterval(this.e._checkVisibile); this.e._checkVisibile = window.setInterval($.proxy(checkVisible, this), 500); } function isElVisible(el) { return el.offsetWidth > 0 && el.offsetHeight > 0; } function checkVisible() { if (isElVisible(this.$element.get(0))) { this.$element.removeClass('owl-hidden'); this.refresh(); window.clearInterval(this.e._checkVisibile); } } }; /** * Preloads images with auto width. * @protected * @todo Still to test */ Owl.prototype.preloadAutoWidthImages = function(imgs) { var loaded, that, $el, img; loaded = 0; that = this; imgs.each(function(i, el) { $el = $(el); img = new Image(); img.onload = function() { loaded++; $el.attr('src', img.src); $el.css('opacity', 1); if (loaded >= imgs.length) { that.state.imagesLoaded = true; that.initialize(); } }; img.src = $el.attr('src') || $el.attr('data-src') || $el.attr('data-src-retina'); }); }; /** * Destroys the carousel. * @public */ Owl.prototype.destroy = function() { if (this.$element.hasClass(this.settings.themeClass)) { this.$element.removeClass(this.settings.themeClass); } if (this.settings.responsive !== false) { $(window).off('resize.owl.carousel'); } if (this.transitionEndVendor) { this.off(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd); } for ( var i in this._plugins) { this._plugins[i].destroy(); } if (this.settings.mouseDrag || this.settings.touchDrag) { this.$stage.off('mousedown touchstart touchcancel'); $(document).off('.owl.dragEvents'); this.$stage.get(0).onselectstart = function() {}; this.$stage.off('dragstart', function() { return false }); } // remove event handlers in the ".owl.carousel" namespace this.$element.off('.owl'); this.$stage.children('.cloned').remove(); this.e = null; this.$element.removeData('owlCarousel'); this.$stage.children().contents().unwrap(); this.$stage.children().unwrap(); this.$stage.unwrap(); }; /** * Operators to calculate right-to-left and left-to-right. * @protected * @param {Number} [a] - The left side operand. * @param {String} [o] - The operator. * @param {Number} [b] - The right side operand. */ Owl.prototype.op = function(a, o, b) { var rtl = this.settings.rtl; switch (o) { case '<': return rtl ? a > b : a < b; case '>': return rtl ? a < b : a > b; case '>=': return rtl ? a <= b : a >= b; case '<=': return rtl ? a >= b : a <= b; default: break; } }; /** * Attaches to an internal event. * @protected * @param {HTMLElement} element - The event source. * @param {String} event - The event name. * @param {Function} listener - The event handler to attach. * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. */ Owl.prototype.on = function(element, event, listener, capture) { if (element.addEventListener) { element.addEventListener(event, listener, capture); } else if (element.attachEvent) { element.attachEvent('on' + event, listener); } }; /** * Detaches from an internal event. * @protected * @param {HTMLElement} element - The event source. * @param {String} event - The event name. * @param {Function} listener - The attached event handler to detach. * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. */ Owl.prototype.off = function(element, event, listener, capture) { if (element.removeEventListener) { element.removeEventListener(event, listener, capture); } else if (element.detachEvent) { element.detachEvent('on' + event, listener); } }; /** * Triggers an public event. * @protected * @param {String} name - The event name. * @param {*} [data=null] - The event data. * @param {String} [namespace=.owl.carousel] - The event namespace. * @returns {Event} - The event arguments. */ Owl.prototype.trigger = function(name, data, namespace) { var status = { item: { count: this._items.length, index: this.current() } }, handler = $.camelCase( $.grep([ 'on', name, namespace ], function(v) { return v }) .join('-').toLowerCase() ), event = $.Event( [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), $.extend({ relatedTarget: this }, status, data) ); if (!this._supress[name]) { $.each(this._plugins, function(name, plugin) { if (plugin.onTrigger) { plugin.onTrigger(event); } }); this.$element.trigger(event); if (this.settings && typeof this.settings[handler] === 'function') { this.settings[handler].apply(this, event); } } return event; }; /** * Suppresses events. * @protected * @param {Array.} events - The events to suppress. */ Owl.prototype.suppress = function(events) { $.each(events, $.proxy(function(index, event) { this._supress[event] = true; }, this)); } /** * Releases suppressed events. * @protected * @param {Array.} events - The events to release. */ Owl.prototype.release = function(events) { $.each(events, $.proxy(function(index, event) { delete this._supress[event]; }, this)); } /** * Checks the availability of some browser features. * @protected */ Owl.prototype.browserSupport = function() { this.support3d = isPerspective(); if (this.support3d) { this.transformVendor = isTransform(); // take transitionend event name by detecting transition var endVendors = [ 'transitionend', 'webkitTransitionEnd', 'transitionend', 'oTransitionEnd' ]; this.transitionEndVendor = endVendors[isTransition()]; // take vendor name from transform name this.vendorName = this.transformVendor.replace(/Transform/i, ''); this.vendorName = this.vendorName !== '' ? '-' + this.vendorName.toLowerCase() + '-' : ''; } this.state.orientation = window.orientation; }; /** * Get touch/drag coordinats. * @private * @param {event} - mousedown/touchstart event * @returns {object} - Contains X and Y of current mouse/touch position */ function getTouches(event) { if (event.touches !== undefined) { return { x: event.touches[0].pageX, y: event.touches[0].pageY }; } if (event.touches === undefined) { if (event.pageX !== undefined) { return { x: event.pageX, y: event.pageY }; } if (event.pageX === undefined) { return { x: event.clientX, y: event.clientY }; } } } /** * Checks for CSS support. * @private * @param {Array} array - The CSS properties to check for. * @returns {Array} - Contains the supported CSS property name and its index or `false`. */ function isStyleSupported(array) { var p, s, fake = document.createElement('div'), list = array; for (p in list) { s = list[p]; if (typeof fake.style[s] !== 'undefined') { fake = null; return [ s, p ]; } } return [ false ]; } /** * Checks for CSS transition support. * @private * @todo Realy bad design * @returns {Number} */ function isTransition() { return isStyleSupported([ 'transition', 'WebkitTransition', 'MozTransition', 'OTransition' ])[1]; } /** * Checks for CSS transform support. * @private * @returns {String} The supported property name or false. */ function isTransform() { return isStyleSupported([ 'transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ])[0]; } /** * Checks for CSS perspective support. * @private * @returns {String} The supported property name or false. */ function isPerspective() { return isStyleSupported([ 'perspective', 'webkitPerspective', 'MozPerspective', 'OPerspective', 'MsPerspective' ])[0]; } /** * Checks wether touch is supported or not. * @private * @returns {Boolean} */ function isTouchSupport() { return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints); } /** * Checks wether touch is supported or not for IE. * @private * @returns {Boolean} */ function isTouchSupportIE() { return window.navigator.msPointerEnabled; } /** * The jQuery Plugin for the Owl Carousel * @public */ $.fn.owlCarousel = function(options) { return this.each(function() { if (!$(this).data('owlCarousel')) { $(this).data('owlCarousel', new Owl(this, options)); } }); }; /** * The constructor for the jQuery Plugin * @public */ $.fn.owlCarousel.Constructor = Owl; })(window.Zepto || window.jQuery, window, document); /** * Lazy Plugin * @version 2.0.0 * @author Bartosz Wojciechowski * @license The MIT License (MIT) */ ;(function($, window, document, undefined) { /** * Creates the lazy plugin. * @class The Lazy Plugin * @param {Owl} carousel - The Owl Carousel */ var Lazy = function(carousel) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Already loaded items. * @protected * @type {Array.} */ this._loaded = []; /** * Event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { if (!e.namespace) { return; } if (!this._core.settings || !this._core.settings.lazyLoad) { return; } if ((e.property && e.property.name == 'position') || e.type == 'initialized') { var settings = this._core.settings, n = (settings.center && Math.ceil(settings.items / 2) || settings.items), i = ((settings.center && n * -1) || 0), position = ((e.property && e.property.value) || this._core.current()) + i, clones = this._core.clones().length, load = $.proxy(function(i, v) { this.load(v) }, this); while (i++ < n) { this.load(clones / 2 + this._core.relative(position)); clones && $.each(this._core.clones(this._core.relative(position++)), load); } } }, this) }; // set the default options this._core.options = $.extend({}, Lazy.Defaults, this._core.options); // register event handler this._core.$element.on(this._handlers); } /** * Default options. * @public */ Lazy.Defaults = { lazyLoad: false } /** * Loads all resources of an item at the specified position. * @param {Number} position - The absolute position of the item. * @protected */ Lazy.prototype.load = function(position) { var $item = this._core.$stage.children().eq(position), $elements = $item && $item.find('.owl-lazy'); if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { return; } $elements.each($.proxy(function(index, element) { var $element = $(element), image, url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); this._core.trigger('load', { element: $element, url: url }, 'lazy'); if ($element.is('img')) { $element.one('load.owl.lazy', $.proxy(function() { $element.css('opacity', 1); this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); }, this)).attr('src', url); } else { image = new Image(); image.onload = $.proxy(function() { $element.css({ 'background-image': 'url(' + url + ')', 'opacity': '1' }); this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); }, this); image.src = url; } }, this)); this._loaded.push($item.get(0)); } /** * Destroys the plugin. * @public */ Lazy.prototype.destroy = function() { var handler, property; for (handler in this.handlers) { this._core.$element.off(handler, this.handlers[handler]); } for (property in Object.getOwnPropertyNames(this)) { typeof this[property] != 'function' && (this[property] = null); } } $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; })(window.Zepto || window.jQuery, window, document); /** * AutoHeight Plugin * @version 2.0.0 * @author Bartosz Wojciechowski * @license The MIT License (MIT) */ ;(function($, window, document, undefined) { /** * Creates the auto height plugin. * @class The Auto Height Plugin * @param {Owl} carousel - The Owl Carousel */ var AutoHeight = function(carousel) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel': $.proxy(function() { if (this._core.settings.autoHeight) { this.update(); } }, this), 'changed.owl.carousel': $.proxy(function(e) { if (this._core.settings.autoHeight && e.property.name == 'position'){ this.update(); } }, this), 'loaded.owl.lazy': $.proxy(function(e) { if (this._core.settings.autoHeight && e.element.closest('.' + this._core.settings.itemClass) === this._core.$stage.children().eq(this._core.current())) { this.update(); } }, this) }; // set default options this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); // register event handlers this._core.$element.on(this._handlers); }; /** * Default options. * @public */ AutoHeight.Defaults = { autoHeight: false, autoHeightClass: 'owl-height' }; /** * Updates the view. */ AutoHeight.prototype.update = function() { this._core.$stage.parent() .height(this._core.$stage.children().eq(this._core.current()).height()) .addClass(this._core.settings.autoHeightClass); }; AutoHeight.prototype.destroy = function() { var handler, property; for (handler in this._handlers) { this._core.$element.off(handler, this._handlers[handler]); } for (property in Object.getOwnPropertyNames(this)) { typeof this[property] != 'function' && (this[property] = null); } }; $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; })(window.Zepto || window.jQuery, window, document); /** * Video Plugin * @version 2.0.0 * @author Bartosz Wojciechowski * @license The MIT License (MIT) */ ;(function($, window, document, undefined) { /** * Creates the video plugin. * @class The Video Plugin * @param {Owl} carousel - The Owl Carousel */ var Video = function(carousel) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Cache all video URLs. * @protected * @type {Object} */ this._videos = {}; /** * Current playing item. * @protected * @type {jQuery} */ this._playing = null; /** * Whether this is in fullscreen or not. * @protected * @type {Boolean} */ this._fullscreen = false; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'resize.owl.carousel': $.proxy(function(e) { if (this._core.settings.video && !this.isInFullScreen()) { e.preventDefault(); } }, this), 'refresh.owl.carousel changed.owl.carousel': $.proxy(function(e) { if (this._playing) { this.stop(); } }, this), 'prepared.owl.carousel': $.proxy(function(e) { var $element = $(e.content).find('.owl-video'); if ($element.length) { $element.css('display', 'none'); this.fetch($element, $(e.content)); } }, this) }; // set default options this._core.options = $.extend({}, Video.Defaults, this._core.options); // register event handlers this._core.$element.on(this._handlers); this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { this.play(e); }, this)); }; /** * Default options. * @public */ Video.Defaults = { video: false, videoHeight: false, videoWidth: false }; /** * Gets the video ID and the type (YouTube/Vimeo only). * @protected * @param {jQuery} target - The target containing the video data. * @param {jQuery} item - The item containing the video. */ Video.prototype.fetch = function(target, item) { var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), width = target.attr('data-width') || this._core.settings.videoWidth, height = target.attr('data-height') || this._core.settings.videoHeight, url = target.attr('href'); if (url) { id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/); if (id[3].indexOf('youtu') > -1) { type = 'youtube'; } else if (id[3].indexOf('vimeo') > -1) { type = 'vimeo'; } else { throw new Error('Video URL not supported.'); } id = id[6]; } else { throw new Error('Missing video URL.'); } this._videos[url] = { type: type, id: id, width: width, height: height }; item.attr('data-video', url); this.thumbnail(target, this._videos[url]); }; /** * Creates video thumbnail. * @protected * @param {jQuery} target - The target containing the video data. * @param {Object} info - The video info object. * @see `fetch` */ Video.prototype.thumbnail = function(target, video) { var tnLink, icon, path, dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', customTn = target.find('img'), srcType = 'src', lazyClass = '', settings = this._core.settings, create = function(path) { icon = '
'; if (settings.lazyLoad) { tnLink = '
'; } else { tnLink = '
'; } target.after(tnLink); target.after(icon); }; // wrap video content into owl-video-wrapper div target.wrap('
'); if (this._core.settings.lazyLoad) { srcType = 'data-src'; lazyClass = 'owl-lazy'; } // custom thumbnail if (customTn.length) { create(customTn.attr(srcType)); customTn.remove(); return false; } if (video.type === 'youtube') { path = "http://img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; create(path); } else if (video.type === 'vimeo') { $.ajax({ type: 'GET', url: 'http://vimeo.com/api/v2/video/' + video.id + '.json', jsonp: 'callback', dataType: 'jsonp', success: function(data) { path = data[0].thumbnail_large; create(path); } }); } }; /** * Stops the current video. * @public */ Video.prototype.stop = function() { this._core.trigger('stop', null, 'video'); this._playing.find('.owl-video-frame').remove(); this._playing.removeClass('owl-video-playing'); this._playing = null; }; /** * Starts the current video. * @public * @param {Event} ev - The event arguments. */ Video.prototype.play = function(ev) { this._core.trigger('play', null, 'video'); if (this._playing) { this.stop(); } var target = $(ev.target || ev.srcElement), item = target.closest('.' + this._core.settings.itemClass), video = this._videos[item.attr('data-video')], width = video.width || '100%', height = video.height || this._core.$stage.height(), html, wrap; if (video.type === 'youtube') { html = ''; } else if (video.type === 'vimeo') { html = ''; } item.addClass('owl-video-playing'); this._playing = item; wrap = $('
' + html + '
'); target.after(wrap); }; /** * Checks whether an video is currently in full screen mode or not. * @todo Bad style because looks like a readonly method but changes members. * @protected * @returns {Boolean} */ Video.prototype.isInFullScreen = function() { // if Vimeo Fullscreen mode var element = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement; if (element && $(element).parent().hasClass('owl-video-frame')) { this._core.speed(0); this._fullscreen = true; } if (element && this._fullscreen && this._playing) { return false; } // comming back from fullscreen if (this._fullscreen) { this._fullscreen = false; return false; } // check full screen mode and window orientation if (this._playing) { if (this._core.state.orientation !== window.orientation) { this._core.state.orientation = window.orientation; return false; } } return true; }; /** * Destroys the plugin. */ Video.prototype.destroy = function() { var handler, property; this._core.$element.off('click.owl.video'); for (handler in this._handlers) { this._core.$element.off(handler, this._handlers[handler]); } for (property in Object.getOwnPropertyNames(this)) { typeof this[property] != 'function' && (this[property] = null); } }; $.fn.owlCarousel.Constructor.Plugins.Video = Video; })(window.Zepto || window.jQuery, window, document); /** * Animate Plugin * @version 2.0.0 * @author Bartosz Wojciechowski * @license The MIT License (MIT) */ ;(function($, window, document, undefined) { /** * Creates the animate plugin. * @class The Navigation Plugin * @param {Owl} scope - The Owl Carousel */ var Animate = function(scope) { this.core = scope; this.core.options = $.extend({}, Animate.Defaults, this.core.options); this.swapping = true; this.previous = undefined; this.next = undefined; this.handlers = { 'change.owl.carousel': $.proxy(function(e) { if (e.property.name == 'position') { this.previous = this.core.current(); this.next = e.property.value; } }, this), 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { this.swapping = e.type == 'translated'; }, this), 'translate.owl.carousel': $.proxy(function(e) { if (this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { this.swap(); } }, this) }; this.core.$element.on(this.handlers); }; /** * Default options. * @public */ Animate.Defaults = { animateOut: false, animateIn: false }; /** * Toggles the animation classes whenever an translations starts. * @protected * @returns {Boolean|undefined} */ Animate.prototype.swap = function() { if (this.core.settings.items !== 1 || !this.core.support3d) { return; } this.core.speed(0); var left, clear = $.proxy(this.clear, this), previous = this.core.$stage.children().eq(this.previous), next = this.core.$stage.children().eq(this.next), incoming = this.core.settings.animateIn, outgoing = this.core.settings.animateOut; if (this.core.current() === this.previous) { return; } if (outgoing) { left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); previous.css( { 'left': left + 'px' } ) .addClass('animated owl-animated-out') .addClass(outgoing) .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); } if (incoming) { next.addClass('animated owl-animated-in') .addClass(incoming) .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear); } }; Animate.prototype.clear = function(e) { $(e.target).css( { 'left': '' } ) .removeClass('animated owl-animated-out owl-animated-in') .removeClass(this.core.settings.animateIn) .removeClass(this.core.settings.animateOut); this.core.transitionEnd(); } /** * Destroys the plugin. * @public */ Animate.prototype.destroy = function() { var handler, property; for (handler in this.handlers) { this.core.$element.off(handler, this.handlers[handler]); } for (property in Object.getOwnPropertyNames(this)) { typeof this[property] != 'function' && (this[property] = null); } }; $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; })(window.Zepto || window.jQuery, window, document); /** * Autoplay Plugin * @version 2.0.0 * @author Bartosz Wojciechowski * @license The MIT License (MIT) */ ;(function($, window, document, undefined) { /** * Creates the autoplay plugin. * @class The Autoplay Plugin * @param {Owl} scope - The Owl Carousel */ var Autoplay = function(scope) { this.core = scope; this.core.options = $.extend({}, Autoplay.Defaults, this.core.options); this.handlers = { 'translated.owl.carousel refreshed.owl.carousel': $.proxy(function() { this.autoplay(); }, this), 'play.owl.autoplay': $.proxy(function(e, t, s) { this.play(t, s); }, this), 'stop.owl.autoplay': $.proxy(function() { this.stop(); }, this), 'mouseover.owl.autoplay': $.proxy(function() { if (this.core.settings.autoplayHoverPause) { this.pause(); } }, this), 'mouseleave.owl.autoplay': $.proxy(function() { if (this.core.settings.autoplayHoverPause) { this.autoplay(); } }, this) }; this.core.$element.on(this.handlers); }; /** * Default options. * @public */ Autoplay.Defaults = { autoplay: false, autoplayTimeout: 5000, autoplayHoverPause: false, autoplaySpeed: false }; /** * @protected * @todo Must be documented. */ Autoplay.prototype.autoplay = function() { if (this.core.settings.autoplay && !this.core.state.videoPlay) { window.clearInterval(this.interval); this.interval = window.setInterval($.proxy(function() { this.play(); }, this), this.core.settings.autoplayTimeout); } else { window.clearInterval(this.interval); } }; /** * Starts the autoplay. * @public * @param {Number} [timeout] - ... * @param {Number} [speed] - ... * @returns {Boolean|undefined} - ... * @todo Must be documented. */ Autoplay.prototype.play = function(timeout, speed) { // if tab is inactive - doesnt work in } */ this._templates = []; /** * The carousel element. * @type {jQuery} */ this.$element = this._core.$element; /** * Overridden methods of the carousel. * @protected * @type {Object} */ this._overrides = { next: this._core.next, prev: this._core.prev, to: this._core.to }; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'prepared.owl.carousel': $.proxy(function(e) { if (this._core.settings.dotsData) { this._templates.push($(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot')); } }, this), 'add.owl.carousel': $.proxy(function(e) { if (this._core.settings.dotsData) { this._templates.splice(e.position, 0, $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot')); } }, this), 'remove.owl.carousel prepared.owl.carousel': $.proxy(function(e) { if (this._core.settings.dotsData) { this._templates.splice(e.position, 1); } }, this), 'change.owl.carousel': $.proxy(function(e) { if (e.property.name == 'position') { if (!this._core.state.revert && !this._core.settings.loop && this._core.settings.navRewind) { var current = this._core.current(), maximum = this._core.maximum(), minimum = this._core.minimum(); e.data = e.property.value > maximum ? current >= maximum ? minimum : maximum : e.property.value < minimum ? maximum : e.property.value; } } }, this), 'changed.owl.carousel': $.proxy(function(e) { if (e.property.name == 'position') { this.draw(); } }, this), 'refreshed.owl.carousel': $.proxy(function() { if (!this._initialized) { this.initialize(); this._initialized = true; } this._core.trigger('refresh', null, 'navigation'); this.update(); this.draw(); this._core.trigger('refreshed', null, 'navigation'); }, this) }; // set default options this._core.options = $.extend({}, Navigation.Defaults, this._core.options); // register event handlers this.$element.on(this._handlers); } /** * Default options. * @public * @todo Rename `slideBy` to `navBy` */ Navigation.Defaults = { nav: false, navRewind: true, navText: [ 'prev', 'next' ], navSpeed: false, navElement: 'div', navContainer: false, navContainerClass: 'owl-nav', navClass: [ 'owl-prev', 'owl-next' ], slideBy: 1, dotClass: 'owl-dot', dotsClass: 'owl-dots', dots: true, dotsEach: false, dotData: false, dotsSpeed: false, dotsContainer: false, controlsClass: 'owl-controls' } /** * Initializes the layout of the plugin and extends the carousel. * @protected */ Navigation.prototype.initialize = function() { var $container, override, options = this._core.settings; // create the indicator template if (!options.dotsData) { this._templates = [ $('
') .addClass(options.dotClass) .append($('')) .prop('outerHTML') ]; } // create controls container if needed if (!options.navContainer || !options.dotsContainer) { this._controls.$container = $('
') .addClass(options.controlsClass) .appendTo(this.$element); } // create DOM structure for absolute navigation this._controls.$indicators = options.dotsContainer ? $(options.dotsContainer) : $('
').hide().addClass(options.dotsClass).appendTo(this._controls.$container); this._controls.$indicators.on('click', 'div', $.proxy(function(e) { var index = $(e.target).parent().is(this._controls.$indicators) ? $(e.target).index() : $(e.target).parent().index(); e.preventDefault(); this.to(index, options.dotsSpeed); }, this)); // create DOM structure for relative navigation $container = options.navContainer ? $(options.navContainer) : $('
').addClass(options.navContainerClass).prependTo(this._controls.$container); this._controls.$next = $('<' + options.navElement + '>'); this._controls.$previous = this._controls.$next.clone(); this._controls.$previous .addClass(options.navClass[0]) .html(options.navText[0]) .hide() .prependTo($container) .on('click', $.proxy(function(e) { this.prev(options.navSpeed); }, this)); this._controls.$next .addClass(options.navClass[1]) .html(options.navText[1]) .hide() .appendTo($container) .on('click', $.proxy(function(e) { this.next(options.navSpeed); }, this)); // override public methods of the carousel for (override in this._overrides) { this._core[override] = $.proxy(this[override], this); } } /** * Destroys the plugin. * @protected */ Navigation.prototype.destroy = function() { var handler, control, property, override; for (handler in this._handlers) { this.$element.off(handler, this._handlers[handler]); } for (control in this._controls) { this._controls[control].remove(); } for (override in this.overides) { this._core[override] = this._overrides[override]; } for (property in Object.getOwnPropertyNames(this)) { typeof this[property] != 'function' && (this[property] = null); } } /** * Updates the internal state. * @protected */ Navigation.prototype.update = function() { var i, j, k, options = this._core.settings, lower = this._core.clones().length / 2, upper = lower + this._core.items().length, size = options.center || options.autoWidth || options.dotData ? 1 : options.dotsEach || options.items; if (options.slideBy !== 'page') { options.slideBy = Math.min(options.slideBy, options.items); } if (options.dots || options.slideBy == 'page') { this._pages = []; for (i = lower, j = 0, k = 0; i < upper; i++) { if (j >= size || j === 0) { this._pages.push({ start: i - lower, end: i - lower + size - 1 }); j = 0, ++k; } j += this._core.mergers(this._core.relative(i)); } } } /** * Draws the user interface. * @todo The option `dotData` wont work. * @protected */ Navigation.prototype.draw = function() { var difference, i, html = '', options = this._core.settings, $items = this._core.$stage.children(), index = this._core.relative(this._core.current()); if (options.nav && !options.loop && !options.navRewind) { this._controls.$previous.toggleClass('disabled', index <= 0); this._controls.$next.toggleClass('disabled', index >= this._core.maximum()); } this._controls.$previous.toggle(options.nav); this._controls.$next.toggle(options.nav); if (options.dots) { difference = this._pages.length - this._controls.$indicators.children().length; if (options.dotData && difference !== 0) { for (i = 0; i < this._controls.$indicators.children().length; i++) { html += this._templates[this._core.relative(i)]; } this._controls.$indicators.html(html); } else if (difference > 0) { html = new Array(difference + 1).join(this._templates[0]); this._controls.$indicators.append(html); } else if (difference < 0) { this._controls.$indicators.children().slice(difference).remove(); } this._controls.$indicators.find('.active').removeClass('active'); this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active'); } this._controls.$indicators.toggle(options.dots); } /** * Extends event data. * @protected * @param {Event} event - The event object which gets thrown. */ Navigation.prototype.onTrigger = function(event) { var settings = this._core.settings; event.page = { index: $.inArray(this.current(), this._pages), count: this._pages.length, size: settings && (settings.center || settings.autoWidth || settings.dotData ? 1 : settings.dotsEach || settings.items) }; } /** * Gets the current page position of the carousel. * @protected * @returns {Number} */ Navigation.prototype.current = function() { var index = this._core.relative(this._core.current()); return $.grep(this._pages, function(o) { return o.start <= index && o.end >= index; }).pop(); } /** * Gets the current succesor/predecessor position. * @protected * @returns {Number} */ Navigation.prototype.getPosition = function(successor) { var position, length, options = this._core.settings; if (options.slideBy == 'page') { position = $.inArray(this.current(), this._pages); length = this._pages.length; successor ? ++position : --position; position = this._pages[((position % length) + length) % length].start; } else { position = this._core.relative(this._core.current()); length = this._core.items().length; successor ? position += options.slideBy : position -= options.slideBy; } return position; } /** * Slides to the next item or page. * @public * @param {Number} [speed=false] - The time in milliseconds for the transition. */ Navigation.prototype.next = function(speed) { $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); } /** * Slides to the previous item or page. * @public * @param {Number} [speed=false] - The time in milliseconds for the transition. */ Navigation.prototype.prev = function(speed) { $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); } /** * Slides to the specified item or page. * @public * @param {Number} position - The position of the item or page. * @param {Number} [speed] - The time in milliseconds for the transition. * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. */ Navigation.prototype.to = function(position, speed, standard) { var length; if (!standard) { length = this._pages.length; $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); } else { $.proxy(this._overrides.to, this._core)(position, speed); } } $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; })(window.Zepto || window.jQuery, window, document); /** * Hash Plugin * @version 2.0.0 * @author Artus Kolanowski * @license The MIT License (MIT) */ ;(function($, window, document, undefined) { 'use strict'; /** * Creates the hash plugin. * @class The Hash Plugin * @param {Owl} carousel - The Owl Carousel */ var Hash = function(carousel) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Hash table for the hashes. * @protected * @type {Object} */ this._hashes = {}; /** * The carousel element. * @type {jQuery} */ this.$element = this._core.$element; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel': $.proxy(function() { if (this._core.settings.startPosition == 'URLHash') { $(window).trigger('hashchange.owl.navigation'); } }, this), 'prepared.owl.carousel': $.proxy(function(e) { var hash = $(e.content).find('[data-hash]').andSelf('[data-hash]').attr('data-hash'); this._hashes[hash] = e.content; }, this) }; // set default options this._core.options = $.extend({}, Hash.Defaults, this._core.options); // register the event handlers this.$element.on(this._handlers); // register event listener for hash navigation $(window).on('hashchange.owl.navigation', $.proxy(function() { var hash = window.location.hash.substring(1), items = this._core.$stage.children(), position = this._hashes[hash] && items.index(this._hashes[hash]) || 0; if (!hash) { return false; } this._core.to(position, false, true); }, this)); } /** * Default options. * @public */ Hash.Defaults = { URLhashListener: false } /** * Destroys the plugin. * @public */ Hash.prototype.destroy = function() { var handler, property; $(window).off('hashchange.owl.navigation'); for (handler in this._handlers) { this._core.$element.off(handler, this._handlers[handler]); } for (property in Object.getOwnPropertyNames(this)) { typeof this[property] != 'function' && (this[property] = null); } } $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; })(window.Zepto || window.jQuery, window, document); // source --> https://blue4u.com.br/wp-content/plugins/smart-logo-showcase-lite/js/tooltipster.bundle.js?ver=1.1.8 /** * tooltipster http://iamceege.github.io/tooltipster/ * A rockin' custom tooltip jQuery plugin * Developed by Caleb Jacob and Louis Ameline * MIT license */ (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module unless amdModuleId is set define(["jquery"], function (a0) { return (factory(a0)); }); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(require("jquery")); } else { factory(jQuery); } }(this, function ($) { // This file will be UMDified by a build task. var defaults = { animation: 'fade', animationDuration: 350, content: null, contentAsHTML: false, contentCloning: false, debug: true, delay: 300, delayTouch: [300, 500], functionInit: null, functionBefore: null, functionReady: null, functionAfter: null, functionFormat: null, IEmin: 6, interactive: false, multiple: false, // must be 'body' for now, or an element positioned at (0, 0) // in the document, typically like the very top views of an app. parent: 'body', plugins: ['sideTip'], repositionOnScroll: false, restoration: 'none', selfDestruction: true, theme: [], timer: 0, trackerInterval: 500, trackOrigin: false, trackTooltip: false, trigger: 'hover', triggerClose: { click: false, mouseleave: false, originClick: false, scroll: false, tap: false, touchleave: false }, triggerOpen: { click: false, mouseenter: false, tap: false, touchstart: false }, updateAnimation: 'rotate', zIndex: 9999999 }, // we'll avoid using the 'window' global as a good practice but npm's // jquery@<2.1.0 package actually requires a 'window' global, so not sure // it's useful at all win = (typeof window != 'undefined') ? window : null, // env will be proxied by the core for plugins to have access its properties env = { // detect if this device can trigger touch events. Better have a false // positive (unused listeners, that's ok) than a false negative. // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js // http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript hasTouchCapability: !!( win && ( 'ontouchstart' in win || (win.DocumentTouch && win.document instanceof win.DocumentTouch) || win.navigator.maxTouchPoints ) ), hasTransitions: transitionSupport(), IE: false, // don't set manually, it will be updated by a build task after the manifest semVer: '4.1.6', window: win }, core = function() { // core variables // the core emitters this.__$emitterPrivate = $({}); this.__$emitterPublic = $({}); this.__instancesLatestArr = []; // collects plugin constructors this.__plugins = {}; // proxy env variables for plugins who might use them this._env = env; }; // core methods core.prototype = { /** * A function to proxy the public methods of an object onto another * * @param {object} constructor The constructor to bridge * @param {object} obj The object that will get new methods (an instance or the core) * @param {string} pluginName A plugin name for the console log message * @return {core} * @private */ __bridge: function(constructor, obj, pluginName) { // if it's not already bridged if (!obj[pluginName]) { var fn = function() {}; fn.prototype = constructor; var pluginInstance = new fn(); // the _init method has to exist in instance constructors but might be missing // in core constructors if (pluginInstance.__init) { pluginInstance.__init(obj); } $.each(constructor, function(methodName, fn) { // don't proxy "private" methods, only "protected" and public ones if (methodName.indexOf('__') != 0) { // if the method does not exist yet if (!obj[methodName]) { obj[methodName] = function() { return pluginInstance[methodName].apply(pluginInstance, Array.prototype.slice.apply(arguments)); }; // remember to which plugin this method corresponds (several plugins may // have methods of the same name, we need to be sure) obj[methodName].bridged = pluginInstance; } else if (defaults.debug) { console.log('The '+ methodName +' method of the '+ pluginName +' plugin conflicts with another plugin or native methods'); } } }); obj[pluginName] = pluginInstance; } return this; }, /** * For mockup in Node env if need be, for testing purposes * * @return {core} * @private */ __setWindow: function(window) { env.window = window; return this; }, /** * Returns a ruler, a tool to help measure the size of a tooltip under * various settings. Meant for plugins * * @see Ruler * @return {object} A Ruler instance * @protected */ _getRuler: function($tooltip) { return new Ruler($tooltip); }, /** * For internal use by plugins, if needed * * @return {core} * @protected */ _off: function() { this.__$emitterPrivate.off.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); return this; }, /** * For internal use by plugins, if needed * * @return {core} * @protected */ _on: function() { this.__$emitterPrivate.on.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); return this; }, /** * For internal use by plugins, if needed * * @return {core} * @protected */ _one: function() { this.__$emitterPrivate.one.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); return this; }, /** * Returns (getter) or adds (setter) a plugin * * @param {string|object} plugin Provide a string (in the full form * "namespace.name") to use as as getter, an object to use as a setter * @return {object|core} * @protected */ _plugin: function(plugin) { var self = this; // getter if (typeof plugin == 'string') { var pluginName = plugin, p = null; // if the namespace is provided, it's easy to search if (pluginName.indexOf('.') > 0) { p = self.__plugins[pluginName]; } // otherwise, return the first name that matches else { $.each(self.__plugins, function(i, plugin) { if (plugin.name.substring(plugin.name.length - pluginName.length - 1) == '.'+ pluginName) { p = plugin; return false; } }); } return p; } // setter else { // force namespaces if (plugin.name.indexOf('.') < 0) { throw new Error('Plugins must be namespaced'); } self.__plugins[plugin.name] = plugin; // if the plugin has core features if (plugin.core) { // bridge non-private methods onto the core to allow new core methods self.__bridge(plugin.core, self, plugin.name); } return this; } }, /** * Trigger events on the core emitters * * @returns {core} * @protected */ _trigger: function() { var args = Array.prototype.slice.apply(arguments); if (typeof args[0] == 'string') { args[0] = { type: args[0] }; } // note: the order of emitters matters this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate, args); this.__$emitterPublic.trigger.apply(this.__$emitterPublic, args); return this; }, /** * Returns instances of all tooltips in the page or an a given element * * @param {string|HTML object collection} selector optional Use this * parameter to restrict the set of objects that will be inspected * for the retrieval of instances. By default, all instances in the * page are returned. * @return {array} An array of instance objects * @public */ instances: function(selector) { var instances = [], sel = selector || '.tooltipstered'; $(sel).each(function() { var $this = $(this), ns = $this.data('tooltipster-ns'); if (ns) { $.each(ns, function(i, namespace) { instances.push($this.data(namespace)); }); } }); return instances; }, /** * Returns the Tooltipster objects generated by the last initializing call * * @return {array} An array of instance objects * @public */ instancesLatest: function() { return this.__instancesLatestArr; }, /** * For public use only, not to be used by plugins (use ::_off() instead) * * @return {core} * @public */ off: function() { this.__$emitterPublic.off.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); return this; }, /** * For public use only, not to be used by plugins (use ::_on() instead) * * @return {core} * @public */ on: function() { this.__$emitterPublic.on.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); return this; }, /** * For public use only, not to be used by plugins (use ::_one() instead) * * @return {core} * @public */ one: function() { this.__$emitterPublic.one.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); return this; }, /** * Returns all HTML elements which have one or more tooltips * * @param {string} selector optional Use this to restrict the results * to the descendants of an element * @return {array} An array of HTML elements * @public */ origins: function(selector) { var sel = selector ? selector +' ' : ''; return $(sel +'.tooltipstered').toArray(); }, /** * Change default options for all future instances * * @param {object} d The options that should be made defaults * @return {core} * @public */ setDefaults: function(d) { $.extend(defaults, d); return this; }, /** * For users to trigger their handlers on the public emitter * * @returns {core} * @public */ triggerHandler: function() { this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); return this; } }; // $.tooltipster will be used to call core methods $.tooltipster = new core(); // the Tooltipster instance class (mind the capital T) $.Tooltipster = function(element, options) { // list of instance variables // stack of custom callbacks provided as parameters to API methods this.__callbacks = { close: [], open: [] }; // the schedule time of DOM removal this.__closingTime; // this will be the user content shown in the tooltip. A capital "C" is used // because there is also a method called content() this.__Content; // for the size tracker this.__contentBcr; // to disable the tooltip once the destruction has begun this.__destroyed = false; this.__destroying = false; // we can't emit directly on the instance because if a method with the same // name as the event exists, it will be called by jQuery. Se we use a plain // object as emitter. This emitter is for internal use by plugins, // if needed. this.__$emitterPrivate = $({}); // this emitter is for the user to listen to events without risking to mess // with our internal listeners this.__$emitterPublic = $({}); this.__enabled = true; // the reference to the gc interval this.__garbageCollector; // various position and size data recomputed before each repositioning this.__Geometry; // the tooltip position, saved after each repositioning by a plugin this.__lastPosition; // a unique namespace per instance this.__namespace = 'tooltipster-'+ Math.round(Math.random()*1000000); this.__options; // will be used to support origins in scrollable areas this.__$originParents; this.__pointerIsOverOrigin = false; // to remove themes if needed this.__previousThemes = []; // the state can be either: appearing, stable, disappearing, closed this.__state = 'closed'; // timeout references this.__timeouts = { close: [], open: null }; // store touch events to be able to detect emulated mouse events this.__touchEvents = []; // the reference to the tracker interval this.__tracker = null; // the element to which this tooltip is associated this._$origin; // this will be the tooltip element (jQuery wrapped HTML element). // It's the job of a plugin to create it and append it to the DOM this._$tooltip; // launch this.__init(element, options); }; $.Tooltipster.prototype = { /** * @param origin * @param options * @private */ __init: function(origin, options) { var self = this; self._$origin = $(origin); self.__options = $.extend(true, {}, defaults, options); // some options may need to be reformatted self.__optionsFormat(); // don't run on old IE if asked no to if ( !env.IE || env.IE >= self.__options.IEmin ) { // note: the content is null (empty) by default and can stay that // way if the plugin remains initialized but not fed any content. The // tooltip will just not appear. // let's save the initial value of the title attribute for later // restoration if need be. var initialTitle = null; // it will already have been saved in case of multiple tooltips if (self._$origin.data('tooltipster-initialTitle') === undefined) { initialTitle = self._$origin.attr('title'); // we do not want initialTitle to be "undefined" because // of how jQuery's .data() method works if (initialTitle === undefined) initialTitle = null; self._$origin.data('tooltipster-initialTitle', initialTitle); } // If content is provided in the options, it has precedence over the // title attribute. // Note: an empty string is considered content, only 'null' represents // the absence of content. // Also, an existing title="" attribute will result in an empty string // content if (self.__options.content !== null) { self.__contentSet(self.__options.content); } else { var selector = self._$origin.attr('data-tooltip-content'), $el; if (selector){ $el = $(selector); } if ($el && $el[0]) { self.__contentSet($el.first()); } else { self.__contentSet(initialTitle); } } self._$origin // strip the title off of the element to prevent the default tooltips // from popping up .removeAttr('title') // to be able to find all instances on the page later (upon window // events in particular) .addClass('tooltipstered'); // set listeners on the origin self.__prepareOrigin(); // set the garbage collector self.__prepareGC(); // init plugins $.each(self.__options.plugins, function(i, pluginName) { self._plug(pluginName); }); // to detect swiping if (env.hasTouchCapability) { $('body').on('touchmove.'+ self.__namespace +'-triggerOpen', function(event) { self._touchRecordEvent(event); }); } self // prepare the tooltip when it gets created. This event must // be fired by a plugin ._on('created', function() { self.__prepareTooltip(); }) // save position information when it's sent by a plugin ._on('repositioned', function(e) { self.__lastPosition = e.position; }); } else { self.__options.disabled = true; } }, /** * Insert the content into the appropriate HTML element of the tooltip * * @returns {self} * @private */ __contentInsert: function() { var self = this, $el = self._$tooltip.find('.tooltipster-content'), formattedContent = self.__Content, format = function(content) { formattedContent = content; }; self._trigger({ type: 'format', content: self.__Content, format: format }); if (self.__options.functionFormat) { formattedContent = self.__options.functionFormat.call( self, self, { origin: self._$origin[0] }, self.__Content ); } if (typeof formattedContent === 'string' && !self.__options.contentAsHTML) { $el.text(formattedContent); } else { $el .empty() .append(formattedContent); } return self; }, /** * Save the content, cloning it beforehand if need be * * @param content * @returns {self} * @private */ __contentSet: function(content) { // clone if asked. Cloning the object makes sure that each instance has its // own version of the content (in case a same object were provided for several // instances) // reminder: typeof null === object if (content instanceof $ && this.__options.contentCloning) { content = content.clone(true); } this.__Content = content; this._trigger({ type: 'updated', content: content }); return this; }, /** * Error message about a method call made after destruction * * @private */ __destroyError: function() { throw new Error('This tooltip has been destroyed and cannot execute your method call.'); }, /** * Gather all information about dimensions and available space, * called before every repositioning * * @private * @returns {object} */ __geometry: function() { var self = this, $target = self._$origin, originIsArea = self._$origin.is('area'); // if this._$origin is a map area, the target we'll need // the dimensions of is actually the image using the map, // not the area itself if (originIsArea) { var mapName = self._$origin.parent().attr('name'); $target = $('img[usemap="#'+ mapName +'"]'); } var bcr = $target[0].getBoundingClientRect(), $document = $(env.window.document), $window = $(env.window), $parent = $target, // some useful properties of important elements geo = { // available space for the tooltip, see down below available: { document: null, window: null }, document: { size: { height: $document.height(), width: $document.width() } }, window: { scroll: { // the second ones are for IE compatibility left: env.window.scrollX || env.window.document.documentElement.scrollLeft, top: env.window.scrollY || env.window.document.documentElement.scrollTop }, size: { height: $window.height(), width: $window.width() } }, origin: { // the origin has a fixed lineage if itself or one of its // ancestors has a fixed position fixedLineage: false, // relative to the document offset: {}, size: { height: bcr.bottom - bcr.top, width: bcr.right - bcr.left }, usemapImage: originIsArea ? $target[0] : null, // relative to the window windowOffset: { bottom: bcr.bottom, left: bcr.left, right: bcr.right, top: bcr.top } } }, geoFixed = false; // if the element is a map area, some properties may need // to be recalculated if (originIsArea) { var shape = self._$origin.attr('shape'), coords = self._$origin.attr('coords'); if (coords) { coords = coords.split(','); $.map(coords, function(val, i) { coords[i] = parseInt(val); }); } // if the image itself is the area, nothing more to do if (shape != 'default') { switch(shape) { case 'circle': var circleCenterLeft = coords[0], circleCenterTop = coords[1], circleRadius = coords[2], areaTopOffset = circleCenterTop - circleRadius, areaLeftOffset = circleCenterLeft - circleRadius; geo.origin.size.height = circleRadius * 2; geo.origin.size.width = geo.origin.size.height; geo.origin.windowOffset.left += areaLeftOffset; geo.origin.windowOffset.top += areaTopOffset; break; case 'rect': var areaLeft = coords[0], areaTop = coords[1], areaRight = coords[2], areaBottom = coords[3]; geo.origin.size.height = areaBottom - areaTop; geo.origin.size.width = areaRight - areaLeft; geo.origin.windowOffset.left += areaLeft; geo.origin.windowOffset.top += areaTop; break; case 'poly': var areaSmallestX = 0, areaSmallestY = 0, areaGreatestX = 0, areaGreatestY = 0, arrayAlternate = 'even'; for (var i = 0; i < coords.length; i++) { var areaNumber = coords[i]; if (arrayAlternate == 'even') { if (areaNumber > areaGreatestX) { areaGreatestX = areaNumber; if (i === 0) { areaSmallestX = areaGreatestX; } } if (areaNumber < areaSmallestX) { areaSmallestX = areaNumber; } arrayAlternate = 'odd'; } else { if (areaNumber > areaGreatestY) { areaGreatestY = areaNumber; if (i == 1) { areaSmallestY = areaGreatestY; } } if (areaNumber < areaSmallestY) { areaSmallestY = areaNumber; } arrayAlternate = 'even'; } } geo.origin.size.height = areaGreatestY - areaSmallestY; geo.origin.size.width = areaGreatestX - areaSmallestX; geo.origin.windowOffset.left += areaSmallestX; geo.origin.windowOffset.top += areaSmallestY; break; } } } // user callback through an event var edit = function(r) { geo.origin.size.height = r.height, geo.origin.windowOffset.left = r.left, geo.origin.windowOffset.top = r.top, geo.origin.size.width = r.width }; self._trigger({ type: 'geometry', edit: edit, geometry: { height: geo.origin.size.height, left: geo.origin.windowOffset.left, top: geo.origin.windowOffset.top, width: geo.origin.size.width } }); // calculate the remaining properties with what we got geo.origin.windowOffset.right = geo.origin.windowOffset.left + geo.origin.size.width; geo.origin.windowOffset.bottom = geo.origin.windowOffset.top + geo.origin.size.height; geo.origin.offset.left = geo.origin.windowOffset.left + geo.window.scroll.left; geo.origin.offset.top = geo.origin.windowOffset.top + geo.window.scroll.top; geo.origin.offset.bottom = geo.origin.offset.top + geo.origin.size.height; geo.origin.offset.right = geo.origin.offset.left + geo.origin.size.width; // the space that is available to display the tooltip relatively to the document geo.available.document = { bottom: { height: geo.document.size.height - geo.origin.offset.bottom, width: geo.document.size.width }, left: { height: geo.document.size.height, width: geo.origin.offset.left }, right: { height: geo.document.size.height, width: geo.document.size.width - geo.origin.offset.right }, top: { height: geo.origin.offset.top, width: geo.document.size.width } }; // the space that is available to display the tooltip relatively to the viewport // (the resulting values may be negative if the origin overflows the viewport) geo.available.window = { bottom: { // the inner max is here to make sure the available height is no bigger // than the viewport height (when the origin is off screen at the top). // The outer max just makes sure that the height is not negative (when // the origin overflows at the bottom). height: Math.max(geo.window.size.height - Math.max(geo.origin.windowOffset.bottom, 0), 0), width: geo.window.size.width }, left: { height: geo.window.size.height, width: Math.max(geo.origin.windowOffset.left, 0) }, right: { height: geo.window.size.height, width: Math.max(geo.window.size.width - Math.max(geo.origin.windowOffset.right, 0), 0) }, top: { height: Math.max(geo.origin.windowOffset.top, 0), width: geo.window.size.width } }; while ($parent[0].tagName.toLowerCase() != 'html') { if ($parent.css('position') == 'fixed') { geo.origin.fixedLineage = true; break; } $parent = $parent.parent(); } return geo; }, /** * Some options may need to be formated before being used * * @returns {self} * @private */ __optionsFormat: function() { if (typeof this.__options.animationDuration == 'number') { this.__options.animationDuration = [this.__options.animationDuration, this.__options.animationDuration]; } if (typeof this.__options.delay == 'number') { this.__options.delay = [this.__options.delay, this.__options.delay]; } if (typeof this.__options.delayTouch == 'number') { this.__options.delayTouch = [this.__options.delayTouch, this.__options.delayTouch]; } if (typeof this.__options.theme == 'string') { this.__options.theme = [this.__options.theme]; } // determine the future parent if (typeof this.__options.parent == 'string') { this.__options.parent = $(this.__options.parent); } if (this.__options.trigger == 'hover') { this.__options.triggerOpen = { mouseenter: true, touchstart: true }; this.__options.triggerClose = { mouseleave: true, originClick: true, touchleave: true }; } else if (this.__options.trigger == 'click') { this.__options.triggerOpen = { click: true, tap: true }; this.__options.triggerClose = { click: true, tap: true }; } // for the plugins this._trigger('options'); return this; }, /** * Schedules or cancels the garbage collector task * * @returns {self} * @private */ __prepareGC: function() { var self = this; // in case the selfDestruction option has been changed by a method call if (self.__options.selfDestruction) { // the GC task self.__garbageCollector = setInterval(function() { var now = new Date().getTime(); // forget the old events self.__touchEvents = $.grep(self.__touchEvents, function(event, i) { // 1 minute return now - event.time > 60000; }); // auto-destruct if the origin is gone if (!bodyContains(self._$origin)) { self.destroy(); } }, 20000); } else { clearInterval(self.__garbageCollector); } return self; }, /** * Sets listeners on the origin if the open triggers require them. * Unlike the listeners set at opening time, these ones * remain even when the tooltip is closed. It has been made a * separate method so it can be called when the triggers are * changed in the options. Closing is handled in _open() * because of the bindings that may be needed on the tooltip * itself * * @returns {self} * @private */ __prepareOrigin: function() { var self = this; // in case we're resetting the triggers self._$origin.off('.'+ self.__namespace +'-triggerOpen'); // if the device is touch capable, even if only mouse triggers // are asked, we need to listen to touch events to know if the mouse // events are actually emulated (so we can ignore them) if (env.hasTouchCapability) { self._$origin.on( 'touchstart.'+ self.__namespace +'-triggerOpen ' + 'touchend.'+ self.__namespace +'-triggerOpen ' + 'touchcancel.'+ self.__namespace +'-triggerOpen', function(event){ self._touchRecordEvent(event); } ); } // mouse click and touch tap work the same way if ( self.__options.triggerOpen.click || (self.__options.triggerOpen.tap && env.hasTouchCapability) ) { var eventNames = ''; if (self.__options.triggerOpen.click) { eventNames += 'click.'+ self.__namespace +'-triggerOpen '; } if (self.__options.triggerOpen.tap && env.hasTouchCapability) { eventNames += 'touchend.'+ self.__namespace +'-triggerOpen'; } self._$origin.on(eventNames, function(event) { if (self._touchIsMeaningfulEvent(event)) { self._open(event); } }); } // mouseenter and touch start work the same way if ( self.__options.triggerOpen.mouseenter || (self.__options.triggerOpen.touchstart && env.hasTouchCapability) ) { var eventNames = ''; if (self.__options.triggerOpen.mouseenter) { eventNames += 'mouseenter.'+ self.__namespace +'-triggerOpen '; } if (self.__options.triggerOpen.touchstart && env.hasTouchCapability) { eventNames += 'touchstart.'+ self.__namespace +'-triggerOpen'; } self._$origin.on(eventNames, function(event) { if ( self._touchIsTouchEvent(event) || !self._touchIsEmulatedEvent(event) ) { self.__pointerIsOverOrigin = true; self._openShortly(event); } }); } // info for the mouseleave/touchleave close triggers when they use a delay if ( self.__options.triggerClose.mouseleave || (self.__options.triggerClose.touchleave && env.hasTouchCapability) ) { var eventNames = ''; if (self.__options.triggerClose.mouseleave) { eventNames += 'mouseleave.'+ self.__namespace +'-triggerOpen '; } if (self.__options.triggerClose.touchleave && env.hasTouchCapability) { eventNames += 'touchend.'+ self.__namespace +'-triggerOpen touchcancel.'+ self.__namespace +'-triggerOpen'; } self._$origin.on(eventNames, function(event) { if (self._touchIsMeaningfulEvent(event)) { self.__pointerIsOverOrigin = false; } }); } return self; }, /** * Do the things that need to be done only once after the tooltip * HTML element it has been created. It has been made a separate * method so it can be called when options are changed. Remember * that the tooltip may actually exist in the DOM before it is * opened, and present after it has been closed: it's the display * plugin that takes care of handling it. * * @returns {self} * @private */ __prepareTooltip: function() { var self = this, p = self.__options.interactive ? 'auto' : ''; // this will be useful to know quickly if the tooltip is in // the DOM or not self._$tooltip .attr('id', self.__namespace) .css({ // pointer events 'pointer-events': p, zIndex: self.__options.zIndex }); // themes // remove the old ones and add the new ones $.each(self.__previousThemes, function(i, theme) { self._$tooltip.removeClass(theme); }); $.each(self.__options.theme, function(i, theme) { self._$tooltip.addClass(theme); }); self.__previousThemes = $.merge([], self.__options.theme); return self; }, /** * Handles the scroll on any of the parents of the origin (when the * tooltip is open) * * @param {object} event * @returns {self} * @private */ __scrollHandler: function(event) { var self = this; if (self.__options.triggerClose.scroll) { self._close(event); } else { // if the scroll happened on the window if (event.target === env.window.document) { // if the origin has a fixed lineage, window scroll will have no // effect on its position nor on the position of the tooltip if (!self.__Geometry.origin.fixedLineage) { // we don't need to do anything unless repositionOnScroll is true // because the tooltip will already have moved with the window // (and of course with the origin) if (self.__options.repositionOnScroll) { self.reposition(event); } } } // if the scroll happened on another parent of the tooltip, it means // that it's in a scrollable area and now needs to have its position // adjusted or recomputed, depending ont the repositionOnScroll // option. Also, if the origin is partly hidden due to a parent that // hides its overflow, we'll just hide (not close) the tooltip. else { var g = self.__geometry(), overflows = false; // a fixed position origin is not affected by the overflow hiding // of a parent if (self._$origin.css('position') != 'fixed') { self.__$originParents.each(function(i, el) { var $el = $(el), overflowX = $el.css('overflow-x'), overflowY = $el.css('overflow-y'); if (overflowX != 'visible' || overflowY != 'visible') { var bcr = el.getBoundingClientRect(); if (overflowX != 'visible') { if ( g.origin.windowOffset.left < bcr.left || g.origin.windowOffset.right > bcr.right ) { overflows = true; return false; } } if (overflowY != 'visible') { if ( g.origin.windowOffset.top < bcr.top || g.origin.windowOffset.bottom > bcr.bottom ) { overflows = true; return false; } } } // no need to go further if fixed, for the same reason as above if ($el.css('position') == 'fixed') { return false; } }); } if (overflows) { self._$tooltip.css('visibility', 'hidden'); } else { self._$tooltip.css('visibility', 'visible'); // reposition if (self.__options.repositionOnScroll) { self.reposition(event); } // or just adjust offset else { // we have to use offset and not windowOffset because this way, // only the scroll distance of the scrollable areas are taken into // account (the scrolltop value of the main window must be // ignored since the tooltip already moves with it) var offsetLeft = g.origin.offset.left - self.__Geometry.origin.offset.left, offsetTop = g.origin.offset.top - self.__Geometry.origin.offset.top; // add the offset to the position initially computed by the display plugin self._$tooltip.css({ left: self.__lastPosition.coord.left + offsetLeft, top: self.__lastPosition.coord.top + offsetTop }); } } } self._trigger({ type: 'scroll', event: event }); } return self; }, /** * Changes the state of the tooltip * * @param {string} state * @returns {self} * @private */ __stateSet: function(state) { this.__state = state; this._trigger({ type: 'state', state: state }); return this; }, /** * Clear appearance timeouts * * @returns {self} * @private */ __timeoutsClear: function() { // there is only one possible open timeout: the delayed opening // when the mouseenter/touchstart open triggers are used clearTimeout(this.__timeouts.open); this.__timeouts.open = null; // ... but several close timeouts: the delayed closing when the // mouseleave close trigger is used and the timer option $.each(this.__timeouts.close, function(i, timeout) { clearTimeout(timeout); }); this.__timeouts.close = []; return this; }, /** * Start the tracker that will make checks at regular intervals * * @returns {self} * @private */ __trackerStart: function() { var self = this, $content = self._$tooltip.find('.tooltipster-content'); // get the initial content size if (self.__options.trackTooltip) { self.__contentBcr = $content[0].getBoundingClientRect(); } self.__tracker = setInterval(function() { // if the origin or tooltip elements have been removed. // Note: we could destroy the instance now if the origin has // been removed but we'll leave that task to our garbage collector if (!bodyContains(self._$origin) || !bodyContains(self._$tooltip)) { self._close(); } // if everything is alright else { // compare the former and current positions of the origin to reposition // the tooltip if need be if (self.__options.trackOrigin) { var g = self.__geometry(), identical = false; // compare size first (a change requires repositioning too) if (areEqual(g.origin.size, self.__Geometry.origin.size)) { // for elements that have a fixed lineage (see __geometry()), we track the // top and left properties (relative to window) if (self.__Geometry.origin.fixedLineage) { if (areEqual(g.origin.windowOffset, self.__Geometry.origin.windowOffset)) { identical = true; } } // otherwise, track total offset (relative to document) else { if (areEqual(g.origin.offset, self.__Geometry.origin.offset)) { identical = true; } } } if (!identical) { // close the tooltip when using the mouseleave close trigger // (see https://github.com/iamceege/tooltipster/pull/253) if (self.__options.triggerClose.mouseleave) { self._close(); } else { self.reposition(); } } } if (self.__options.trackTooltip) { var currentBcr = $content[0].getBoundingClientRect(); if ( currentBcr.height !== self.__contentBcr.height || currentBcr.width !== self.__contentBcr.width ) { self.reposition(); self.__contentBcr = currentBcr; } } } }, self.__options.trackerInterval); return self; }, /** * Closes the tooltip (after the closing delay) * * @param event * @param callback * @returns {self} * @protected */ _close: function(event, callback) { var self = this, ok = true; self._trigger({ type: 'close', event: event, stop: function() { ok = false; } }); // a destroying tooltip may not refuse to close if (ok || self.__destroying) { // save the method custom callback and cancel any open method custom callbacks if (callback) self.__callbacks.close.push(callback); self.__callbacks.open = []; // clear open/close timeouts self.__timeoutsClear(); var finishCallbacks = function() { // trigger any close method custom callbacks and reset them $.each(self.__callbacks.close, function(i,c) { c.call(self, self, { event: event, origin: self._$origin[0] }); }); self.__callbacks.close = []; }; if (self.__state != 'closed') { var necessary = true, d = new Date(), now = d.getTime(), newClosingTime = now + self.__options.animationDuration[1]; // the tooltip may already already be disappearing, but if a new // call to close() is made after the animationDuration was changed // to 0 (for example), we ought to actually close it sooner than // previously scheduled. In that case it should be noted that the // browser will not adapt the animation duration to the new // animationDuration that was set after the start of the closing // animation. // Note: the same thing could be considered at opening, but is not // really useful since the tooltip is actually opened immediately // upon a call to _open(). Since it would not make the opening // animation finish sooner, its sole impact would be to trigger the // state event and the open callbacks sooner than the actual end of // the opening animation, which is not great. if (self.__state == 'disappearing') { if (newClosingTime > self.__closingTime) { necessary = false; } } if (necessary) { self.__closingTime = newClosingTime; if (self.__state != 'disappearing') { self.__stateSet('disappearing'); } var finish = function() { // stop the tracker clearInterval(self.__tracker); // a "beforeClose" option has been asked several times but would // probably useless since the content element is still accessible // via ::content(), and because people can always use listeners // inside their content to track what's going on. For the sake of // simplicity, this has been denied. Bur for the rare people who // really need the option (for old browsers or for the case where // detaching the content is actually destructive, for file or // password inputs for example), this event will do the work. self._trigger({ type: 'closing', event: event }); // unbind listeners which are no longer needed self._$tooltip .off('.'+ self.__namespace +'-triggerClose') .removeClass('tooltipster-dying'); // orientationchange, scroll and resize listeners $(env.window).off('.'+ self.__namespace +'-triggerClose'); // scroll listeners self.__$originParents.each(function(i, el) { $(el).off('scroll.'+ self.__namespace +'-triggerClose'); }); // clear the array to prevent memory leaks self.__$originParents = null; $('body').off('.'+ self.__namespace +'-triggerClose'); self._$origin.off('.'+ self.__namespace +'-triggerClose'); self._off('dismissable'); // a plugin that would like to remove the tooltip from the // DOM when closed should bind on this self.__stateSet('closed'); // trigger event self._trigger({ type: 'after', event: event }); // call our constructor custom callback function if (self.__options.functionAfter) { self.__options.functionAfter.call(self, self, { event: event, origin: self._$origin[0] }); } // call our method custom callbacks functions finishCallbacks(); }; if (env.hasTransitions) { self._$tooltip.css({ '-moz-animation-duration': self.__options.animationDuration[1] + 'ms', '-ms-animation-duration': self.__options.animationDuration[1] + 'ms', '-o-animation-duration': self.__options.animationDuration[1] + 'ms', '-webkit-animation-duration': self.__options.animationDuration[1] + 'ms', 'animation-duration': self.__options.animationDuration[1] + 'ms', 'transition-duration': self.__options.animationDuration[1] + 'ms' }); self._$tooltip // clear both potential open and close tasks .clearQueue() .removeClass('tooltipster-show') // for transitions only .addClass('tooltipster-dying'); if (self.__options.animationDuration[1] > 0) { self._$tooltip.delay(self.__options.animationDuration[1]); } self._$tooltip.queue(finish); } else { self._$tooltip .stop() .fadeOut(self.__options.animationDuration[1], finish); } } } // if the tooltip is already closed, we still need to trigger // the method custom callbacks else { finishCallbacks(); } } return self; }, /** * For internal use by plugins, if needed * * @returns {self} * @protected */ _off: function() { this.__$emitterPrivate.off.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); return this; }, /** * For internal use by plugins, if needed * * @returns {self} * @protected */ _on: function() { this.__$emitterPrivate.on.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); return this; }, /** * For internal use by plugins, if needed * * @returns {self} * @protected */ _one: function() { this.__$emitterPrivate.one.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); return this; }, /** * Opens the tooltip right away * * @param event * @param callback * @returns {self} * @protected */ _open: function(event, callback) { var self = this; // if the destruction process has not begun and if this was not // triggered by an unwanted emulated click event if (!self.__destroying) { // check that the origin is still in the DOM if ( bodyContains(self._$origin) // if the tooltip is enabled && self.__enabled ) { var ok = true; // if the tooltip is not open yet, we need to call functionBefore. // otherwise we can jst go on if (self.__state == 'closed') { // trigger an event. The event.stop function allows the callback // to prevent the opening of the tooltip self._trigger({ type: 'before', event: event, stop: function() { ok = false; } }); if (ok && self.__options.functionBefore) { // call our custom function before continuing ok = self.__options.functionBefore.call(self, self, { event: event, origin: self._$origin[0] }); } } if (ok !== false) { // if there is some content if (self.__Content !== null) { // save the method callback and cancel close method callbacks if (callback) { self.__callbacks.open.push(callback); } self.__callbacks.close = []; // get rid of any appearance timeouts self.__timeoutsClear(); var extraTime, finish = function() { if (self.__state != 'stable') { self.__stateSet('stable'); } // trigger any open method custom callbacks and reset them $.each(self.__callbacks.open, function(i,c) { c.call(self, self, { origin: self._$origin[0], tooltip: self._$tooltip[0] }); }); self.__callbacks.open = []; }; // if the tooltip is already open if (self.__state !== 'closed') { // the timer (if any) will start (or restart) right now extraTime = 0; // if it was disappearing, cancel that if (self.__state === 'disappearing') { self.__stateSet('appearing'); if (env.hasTransitions) { self._$tooltip .clearQueue() .removeClass('tooltipster-dying') .addClass('tooltipster-show'); if (self.__options.animationDuration[0] > 0) { self._$tooltip.delay(self.__options.animationDuration[0]); } self._$tooltip.queue(finish); } else { // in case the tooltip was currently fading out, bring it back // to life self._$tooltip .stop() .fadeIn(finish); } } // if the tooltip is already open, we still need to trigger the method // custom callback else if (self.__state == 'stable') { finish(); } } // if the tooltip isn't already open, open it else { // a plugin must bind on this and store the tooltip in this._$tooltip self.__stateSet('appearing'); // the timer (if any) will start when the tooltip has fully appeared // after its transition extraTime = self.__options.animationDuration[0]; // insert the content inside the tooltip self.__contentInsert(); // reposition the tooltip and attach to the DOM self.reposition(event, true); // animate in the tooltip. If the display plugin wants no css // animations, it may override the animation option with a // dummy value that will produce no effect if (env.hasTransitions) { // note: there seems to be an issue with start animations which // are randomly not played on fast devices in both Chrome and FF, // couldn't find a way to solve it yet. It seems that applying // the classes before appending to the DOM helps a little, but // it messes up some CSS transitions. The issue almost never // happens when delay[0]==0 though self._$tooltip .addClass('tooltipster-'+ self.__options.animation) .addClass('tooltipster-initial') .css({ '-moz-animation-duration': self.__options.animationDuration[0] + 'ms', '-ms-animation-duration': self.__options.animationDuration[0] + 'ms', '-o-animation-duration': self.__options.animationDuration[0] + 'ms', '-webkit-animation-duration': self.__options.animationDuration[0] + 'ms', 'animation-duration': self.__options.animationDuration[0] + 'ms', 'transition-duration': self.__options.animationDuration[0] + 'ms' }); setTimeout( function() { // a quick hover may have already triggered a mouseleave if (self.__state != 'closed') { self._$tooltip .addClass('tooltipster-show') .removeClass('tooltipster-initial'); if (self.__options.animationDuration[0] > 0) { self._$tooltip.delay(self.__options.animationDuration[0]); } self._$tooltip.queue(finish); } }, 0 ); } else { // old browsers will have to live with this self._$tooltip .css('display', 'none') .fadeIn(self.__options.animationDuration[0], finish); } // checks if the origin is removed while the tooltip is open self.__trackerStart(); // NOTE: the listeners below have a '-triggerClose' namespace // because we'll remove them when the tooltip closes (unlike // the '-triggerOpen' listeners). So some of them are actually // not about close triggers, rather about positioning. $(env.window) // reposition on resize .on('resize.'+ self.__namespace +'-triggerClose', function(e) { var $ae = $(document.activeElement); // reposition only if the resize event was not triggered upon the opening // of a virtual keyboard due to an input field being focused within the tooltip // (otherwise the repositioning would lose the focus) if ( (!$ae.is('input') && !$ae.is('textarea')) || !$.contains(self._$tooltip[0], $ae[0]) ) { self.reposition(e); } }) // same as below for parents .on('scroll.'+ self.__namespace +'-triggerClose', function(e) { self.__scrollHandler(e); }); self.__$originParents = self._$origin.parents(); // scrolling may require the tooltip to be moved or even // repositioned in some cases self.__$originParents.each(function(i, parent) { $(parent).on('scroll.'+ self.__namespace +'-triggerClose', function(e) { self.__scrollHandler(e); }); }); if ( self.__options.triggerClose.mouseleave || (self.__options.triggerClose.touchleave && env.hasTouchCapability) ) { // we use an event to allow users/plugins to control when the mouseleave/touchleave // close triggers will come to action. It allows to have more triggering elements // than just the origin and the tooltip for example, or to cancel/delay the closing, // or to make the tooltip interactive even if it wasn't when it was open, etc. self._on('dismissable', function(event) { if (event.dismissable) { if (event.delay) { timeout = setTimeout(function() { // event.event may be undefined self._close(event.event); }, event.delay); self.__timeouts.close.push(timeout); } else { self._close(event); } } else { clearTimeout(timeout); } }); // now set the listeners that will trigger 'dismissable' events var $elements = self._$origin, eventNamesIn = '', eventNamesOut = '', timeout = null; // if we have to allow interaction, bind on the tooltip too if (self.__options.interactive) { $elements = $elements.add(self._$tooltip); } if (self.__options.triggerClose.mouseleave) { eventNamesIn += 'mouseenter.'+ self.__namespace +'-triggerClose '; eventNamesOut += 'mouseleave.'+ self.__namespace +'-triggerClose '; } if (self.__options.triggerClose.touchleave && env.hasTouchCapability) { eventNamesIn += 'touchstart.'+ self.__namespace +'-triggerClose'; eventNamesOut += 'touchend.'+ self.__namespace +'-triggerClose touchcancel.'+ self.__namespace +'-triggerClose'; } $elements // close after some time spent outside of the elements .on(eventNamesOut, function(event) { // it's ok if the touch gesture ended up to be a swipe, // it's still a "touch leave" situation if ( self._touchIsTouchEvent(event) || !self._touchIsEmulatedEvent(event) ) { var delay = (event.type == 'mouseleave') ? self.__options.delay : self.__options.delayTouch; self._trigger({ delay: delay[1], dismissable: true, event: event, type: 'dismissable' }); } }) // suspend the mouseleave timeout when the pointer comes back // over the elements .on(eventNamesIn, function(event) { // it's also ok if the touch event is a swipe gesture if ( self._touchIsTouchEvent(event) || !self._touchIsEmulatedEvent(event) ) { self._trigger({ dismissable: false, event: event, type: 'dismissable' }); } }); } // close the tooltip when the origin gets a mouse click (common behavior of // native tooltips) if (self.__options.triggerClose.originClick) { self._$origin.on('click.'+ self.__namespace + '-triggerClose', function(event) { // we could actually let a tap trigger this but this feature just // does not make sense on touch devices if ( !self._touchIsTouchEvent(event) && !self._touchIsEmulatedEvent(event) ) { self._close(event); } }); } // set the same bindings for click and touch on the body to close the tooltip if ( self.__options.triggerClose.click || (self.__options.triggerClose.tap && env.hasTouchCapability) ) { // don't set right away since the click/tap event which triggered this method // (if it was a click/tap) is going to bubble up to the body, we don't want it // to close the tooltip immediately after it opened setTimeout(function() { if (self.__state != 'closed') { var eventNames = ''; if (self.__options.triggerClose.click) { eventNames += 'click.'+ self.__namespace +'-triggerClose '; } if (self.__options.triggerClose.tap && env.hasTouchCapability) { eventNames += 'touchend.'+ self.__namespace +'-triggerClose'; } $('body').on(eventNames, function(event) { if (self._touchIsMeaningfulEvent(event)) { self._touchRecordEvent(event); if (!self.__options.interactive || !$.contains(self._$tooltip[0], event.target)) { self._close(event); } } }); // needed to detect and ignore swiping if (self.__options.triggerClose.tap && env.hasTouchCapability) { $('body').on('touchstart.'+ self.__namespace +'-triggerClose', function(event) { self._touchRecordEvent(event); }); } } }, 0); } self._trigger('ready'); // call our custom callback if (self.__options.functionReady) { self.__options.functionReady.call(self, self, { origin: self._$origin[0], tooltip: self._$tooltip[0] }); } } // if we have a timer set, let the countdown begin if (self.__options.timer > 0) { var timeout = setTimeout(function() { self._close(); }, self.__options.timer + extraTime); self.__timeouts.close.push(timeout); } } } } } return self; }, /** * When using the mouseenter/touchstart open triggers, this function will * schedule the opening of the tooltip after the delay, if there is one * * @param event * @returns {self} * @protected */ _openShortly: function(event) { var self = this, ok = true; if (self.__state != 'stable' && self.__state != 'appearing') { // if a timeout is not already running if (!self.__timeouts.open) { self._trigger({ type: 'start', event: event, stop: function() { ok = false; } }); if (ok) { var delay = (event.type.indexOf('touch') == 0) ? self.__options.delayTouch : self.__options.delay; if (delay[0]) { self.__timeouts.open = setTimeout(function() { self.__timeouts.open = null; // open only if the pointer (mouse or touch) is still over the origin. // The check on the "meaningful event" can only be made here, after some // time has passed (to know if the touch was a swipe or not) if (self.__pointerIsOverOrigin && self._touchIsMeaningfulEvent(event)) { // signal that we go on self._trigger('startend'); self._open(event); } else { // signal that we cancel self._trigger('startcancel'); } }, delay[0]); } else { // signal that we go on self._trigger('startend'); self._open(event); } } } } return self; }, /** * Meant for plugins to get their options * * @param {string} pluginName The name of the plugin that asks for its options * @param {object} defaultOptions The default options of the plugin * @returns {object} The options * @protected */ _optionsExtract: function(pluginName, defaultOptions) { var self = this, options = $.extend(true, {}, defaultOptions); // if the plugin options were isolated in a property named after the // plugin, use them (prevents conflicts with other plugins) var pluginOptions = self.__options[pluginName]; // if not, try to get them as regular options if (!pluginOptions){ pluginOptions = {}; $.each(defaultOptions, function(optionName, value) { var o = self.__options[optionName]; if (o !== undefined) { pluginOptions[optionName] = o; } }); } // let's merge the default options and the ones that were provided. We'd want // to do a deep copy but not let jQuery merge arrays, so we'll do a shallow // extend on two levels, that will be enough if options are not more than 1 // level deep $.each(options, function(optionName, value) { if (pluginOptions[optionName] !== undefined) { if (( typeof value == 'object' && !(value instanceof Array) && value != null ) && ( typeof pluginOptions[optionName] == 'object' && !(pluginOptions[optionName] instanceof Array) && pluginOptions[optionName] != null ) ) { $.extend(options[optionName], pluginOptions[optionName]); } else { options[optionName] = pluginOptions[optionName]; } } }); return options; }, /** * Used at instantiation of the plugin, or afterwards by plugins that activate themselves * on existing instances * * @param {object} pluginName * @returns {self} * @protected */ _plug: function(pluginName) { var plugin = $.tooltipster._plugin(pluginName); if (plugin) { // if there is a constructor for instances if (plugin.instance) { // proxy non-private methods on the instance to allow new instance methods $.tooltipster.__bridge(plugin.instance, this, plugin.name); } } else { throw new Error('The "'+ pluginName +'" plugin is not defined'); } return this; }, /** * This will return true if the event is a mouse event which was * emulated by the browser after a touch event. This allows us to * really dissociate mouse and touch triggers. * * There is a margin of error if a real mouse event is fired right * after (within the delay shown below) a touch event on the same * element, but hopefully it should not happen often. * * @returns {boolean} * @protected */ _touchIsEmulatedEvent: function(event) { var isEmulated = false, now = new Date().getTime(); for (var i = this.__touchEvents.length - 1; i >= 0; i--) { var e = this.__touchEvents[i]; // delay, in milliseconds. It's supposed to be 300ms in // most browsers (350ms on iOS) to allow a double tap but // can be less (check out FastClick for more info) if (now - e.time < 500) { if (e.target === event.target) { isEmulated = true; } } else { break; } } return isEmulated; }, /** * Returns false if the event was an emulated mouse event or * a touch event involved in a swipe gesture. * * @param {object} event * @returns {boolean} * @protected */ _touchIsMeaningfulEvent: function(event) { return ( (this._touchIsTouchEvent(event) && !this._touchSwiped(event.target)) || (!this._touchIsTouchEvent(event) && !this._touchIsEmulatedEvent(event)) ); }, /** * Checks if an event is a touch event * * @param {object} event * @returns {boolean} * @protected */ _touchIsTouchEvent: function(event){ return event.type.indexOf('touch') == 0; }, /** * Store touch events for a while to detect swiping and emulated mouse events * * @param {object} event * @returns {self} * @protected */ _touchRecordEvent: function(event) { if (this._touchIsTouchEvent(event)) { event.time = new Date().getTime(); this.__touchEvents.push(event); } return this; }, /** * Returns true if a swipe happened after the last touchstart event fired on * event.target. * * We need to differentiate a swipe from a tap before we let the event open * or close the tooltip. A swipe is when a touchmove (scroll) event happens * on the body between the touchstart and the touchend events of an element. * * @param {object} target The HTML element that may have triggered the swipe * @returns {boolean} * @protected */ _touchSwiped: function(target) { var swiped = false; for (var i = this.__touchEvents.length - 1; i >= 0; i--) { var e = this.__touchEvents[i]; if (e.type == 'touchmove') { swiped = true; break; } else if ( e.type == 'touchstart' && target === e.target ) { break; } } return swiped; }, /** * Triggers an event on the instance emitters * * @returns {self} * @protected */ _trigger: function() { var args = Array.prototype.slice.apply(arguments); if (typeof args[0] == 'string') { args[0] = { type: args[0] }; } // add properties to the event args[0].instance = this; args[0].origin = this._$origin ? this._$origin[0] : null; args[0].tooltip = this._$tooltip ? this._$tooltip[0] : null; // note: the order of emitters matters this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate, args); $.tooltipster._trigger.apply($.tooltipster, args); this.__$emitterPublic.trigger.apply(this.__$emitterPublic, args); return this; }, /** * Deactivate a plugin on this instance * * @returns {self} * @protected */ _unplug: function(pluginName) { var self = this; // if the plugin has been activated on this instance if (self[pluginName]) { var plugin = $.tooltipster._plugin(pluginName); // if there is a constructor for instances if (plugin.instance) { // unbridge $.each(plugin.instance, function(methodName, fn) { // if the method exists (privates methods do not) and comes indeed from // this plugin (may be missing or come from a conflicting plugin). if ( self[methodName] && self[methodName].bridged === self[pluginName] ) { delete self[methodName]; } }); } // destroy the plugin if (self[pluginName].__destroy) { self[pluginName].__destroy(); } // remove the reference to the plugin instance delete self[pluginName]; } return self; }, /** * @see self::_close * @returns {self} * @public */ close: function(callback) { if (!this.__destroyed) { this._close(null, callback); } else { this.__destroyError(); } return this; }, /** * Sets or gets the content of the tooltip * * @returns {mixed|self} * @public */ content: function(content) { var self = this; // getter method if (content === undefined) { return self.__Content; } // setter method else { if (!self.__destroyed) { // change the content self.__contentSet(content); if (self.__Content !== null) { // update the tooltip if it is open if (self.__state !== 'closed') { // reset the content in the tooltip self.__contentInsert(); // reposition and resize the tooltip self.reposition(); // if we want to play a little animation showing the content changed if (self.__options.updateAnimation) { if (env.hasTransitions) { // keep the reference in the local scope var animation = self.__options.updateAnimation; self._$tooltip.addClass('tooltipster-update-'+ animation); // remove the class after a while. The actual duration of the // update animation may be shorter, it's set in the CSS rules setTimeout(function() { if (self.__state != 'closed') { self._$tooltip.removeClass('tooltipster-update-'+ animation); } }, 1000); } else { self._$tooltip.fadeTo(200, 0.5, function() { if (self.__state != 'closed') { self._$tooltip.fadeTo(200, 1); } }); } } } } else { self._close(); } } else { self.__destroyError(); } return self; } }, /** * Destroys the tooltip * * @returns {self} * @public */ destroy: function() { var self = this; if (!self.__destroyed) { if (!self.__destroying) { self.__destroying = true; self._close(null, function() { self._trigger('destroy'); self.__destroying = false; self.__destroyed = true; self._$origin .removeData(self.__namespace) // remove the open trigger listeners .off('.'+ self.__namespace +'-triggerOpen'); // remove the touch listener $('body').off('.' + self.__namespace +'-triggerOpen'); var ns = self._$origin.data('tooltipster-ns'); // if the origin has been removed from DOM, its data may // well have been destroyed in the process and there would // be nothing to clean up or restore if (ns) { // if there are no more tooltips on this element if (ns.length === 1) { // optional restoration of a title attribute var title = null; if (self.__options.restoration == 'previous') { title = self._$origin.data('tooltipster-initialTitle'); } else if (self.__options.restoration == 'current') { // old school technique to stringify when outerHTML is not supported title = (typeof self.__Content == 'string') ? self.__Content : $('
').append(self.__Content).html(); } if (title) { self._$origin.attr('title', title); } // final cleaning self._$origin.removeClass('tooltipstered'); self._$origin .removeData('tooltipster-ns') .removeData('tooltipster-initialTitle'); } else { // remove the instance namespace from the list of namespaces of // tooltips present on the element ns = $.grep(ns, function(el, i) { return el !== self.__namespace; }); self._$origin.data('tooltipster-ns', ns); } } // last event self._trigger('destroyed'); // unbind private and public event listeners self._off(); self.off(); // remove external references, just in case self.__Content = null; self.__$emitterPrivate = null; self.__$emitterPublic = null; self.__options.parent = null; self._$origin = null; self._$tooltip = null; // make sure the object is no longer referenced in there to prevent // memory leaks $.tooltipster.__instancesLatestArr = $.grep($.tooltipster.__instancesLatestArr, function(el, i) { return self !== el; }); clearInterval(self.__garbageCollector); }); } } else { self.__destroyError(); } // we return the scope rather than true so that the call to // .tooltipster('destroy') actually returns the matched elements // and applies to all of them return self; }, /** * Disables the tooltip * * @returns {self} * @public */ disable: function() { if (!this.__destroyed) { // close first, in case the tooltip would not disappear on // its own (no close trigger) this._close(); this.__enabled = false; return this; } else { this.__destroyError(); } return this; }, /** * Returns the HTML element of the origin * * @returns {self} * @public */ elementOrigin: function() { if (!this.__destroyed) { return this._$origin[0]; } else { this.__destroyError(); } }, /** * Returns the HTML element of the tooltip * * @returns {self} * @public */ elementTooltip: function() { return this._$tooltip ? this._$tooltip[0] : null; }, /** * Enables the tooltip * * @returns {self} * @public */ enable: function() { this.__enabled = true; return this; }, /** * Alias, deprecated in 4.0.0 * * @param {function} callback * @returns {self} * @public */ hide: function(callback) { return this.close(callback); }, /** * Returns the instance * * @returns {self} * @public */ instance: function() { return this; }, /** * For public use only, not to be used by plugins (use ::_off() instead) * * @returns {self} * @public */ off: function() { if (!this.__destroyed) { this.__$emitterPublic.off.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); } return this; }, /** * For public use only, not to be used by plugins (use ::_on() instead) * * @returns {self} * @public */ on: function() { if (!this.__destroyed) { this.__$emitterPublic.on.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); } else { this.__destroyError(); } return this; }, /** * For public use only, not to be used by plugins * * @returns {self} * @public */ one: function() { if (!this.__destroyed) { this.__$emitterPublic.one.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); } else { this.__destroyError(); } return this; }, /** * @see self::_open * @returns {self} * @public */ open: function(callback) { if (!this.__destroyed && !this.__destroying) { this._open(null, callback); } else { this.__destroyError(); } return this; }, /** * Get or set options. For internal use and advanced users only. * * @param {string} o Option name * @param {mixed} val optional A new value for the option * @return {mixed|self} If val is omitted, the value of the option * is returned, otherwise the instance itself is returned * @public */ option: function(o, val) { // getter if (val === undefined) { return this.__options[o]; } // setter else { if (!this.__destroyed) { // change value this.__options[o] = val; // format this.__optionsFormat(); // re-prepare the triggers if needed if ($.inArray(o, ['trigger', 'triggerClose', 'triggerOpen']) >= 0) { this.__prepareOrigin(); } if (o === 'selfDestruction') { this.__prepareGC(); } } else { this.__destroyError(); } return this; } }, /** * This method is in charge of setting the position and size properties of the tooltip. * All the hard work is delegated to the display plugin. * Note: The tooltip may be detached from the DOM at the moment the method is called * but must be attached by the end of the method call. * * @param {object} event For internal use only. Defined if an event such as * window resizing triggered the repositioning * @param {boolean} tooltipIsDetached For internal use only. Set this to true if you * know that the tooltip not being in the DOM is not an issue (typically when the * tooltip element has just been created but has not been added to the DOM yet). * @returns {self} * @public */ reposition: function(event, tooltipIsDetached) { var self = this; if (!self.__destroyed) { // if the tooltip is still open and the origin is still in the DOM if (self.__state != 'closed' && bodyContains(self._$origin)) { // if the tooltip has not been removed from DOM manually (or if it // has been detached on purpose) if (tooltipIsDetached || bodyContains(self._$tooltip)) { if (!tooltipIsDetached) { // detach in case the tooltip overflows the window and adds // scrollbars to it, so __geometry can be accurate self._$tooltip.detach(); } // refresh the geometry object before passing it as a helper self.__Geometry = self.__geometry(); // let a plugin fo the rest self._trigger({ type: 'reposition', event: event, helper: { geo: self.__Geometry } }); } } } else { self.__destroyError(); } return self; }, /** * Alias, deprecated in 4.0.0 * * @param callback * @returns {self} * @public */ show: function(callback) { return this.open(callback); }, /** * Returns some properties about the instance * * @returns {object} * @public */ status: function() { return { destroyed: this.__destroyed, destroying: this.__destroying, enabled: this.__enabled, open: this.__state !== 'closed', state: this.__state }; }, /** * For public use only, not to be used by plugins * * @returns {self} * @public */ triggerHandler: function() { if (!this.__destroyed) { this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); } else { this.__destroyError(); } return this; } }; $.fn.tooltipster = function() { // for using in closures var args = Array.prototype.slice.apply(arguments), // common mistake: an HTML element can't be in several tooltips at the same time contentCloningWarning = 'You are using a single HTML element as content for several tooltips. You probably want to set the contentCloning option to TRUE.'; // this happens with $(sel).tooltipster(...) when $(sel) does not match anything if (this.length === 0) { // still chainable return this; } // this happens when calling $(sel).tooltipster('methodName or options') // where $(sel) matches one or more elements else { // method calls if (typeof args[0] === 'string') { var v = '#*$~&'; this.each(function() { // retrieve the namepaces of the tooltip(s) that exist on that element. // We will interact with the first tooltip only. var ns = $(this).data('tooltipster-ns'), // self represents the instance of the first tooltipster plugin // associated to the current HTML object of the loop self = ns ? $(this).data(ns[0]) : null; // if the current element holds a tooltipster instance if (self) { if (typeof self[args[0]] === 'function') { if ( this.length > 1 && args[0] == 'content' && ( args[1] instanceof $ || (typeof args[1] == 'object' && args[1] != null && args[1].tagName) ) && !self.__options.contentCloning && self.__options.debug ) { console.log(contentCloningWarning); } // note : args[1] and args[2] may not be defined var resp = self[args[0]](args[1], args[2]); } else { throw new Error('Unknown method "'+ args[0] +'"'); } // if the function returned anything other than the instance // itself (which implies chaining, except for the `instance` method) if (resp !== self || args[0] === 'instance') { v = resp; // return false to stop .each iteration on the first element // matched by the selector return false; } } else { throw new Error('You called Tooltipster\'s "'+ args[0] +'" method on an uninitialized element'); } }); return (v !== '#*$~&') ? v : this; } // first argument is undefined or an object: the tooltip is initializing else { // reset the array of last initialized objects $.tooltipster.__instancesLatestArr = []; // is there a defined value for the multiple option in the options object ? var multipleIsSet = args[0] && args[0].multiple !== undefined, // if the multiple option is set to true, or if it's not defined but // set to true in the defaults multiple = (multipleIsSet && args[0].multiple) || (!multipleIsSet && defaults.multiple), // same for content contentIsSet = args[0] && args[0].content !== undefined, content = (contentIsSet && args[0].content) || (!contentIsSet && defaults.content), // same for contentCloning contentCloningIsSet = args[0] && args[0].contentCloning !== undefined, contentCloning = (contentCloningIsSet && args[0].contentCloning) || (!contentCloningIsSet && defaults.contentCloning), // same for debug debugIsSet = args[0] && args[0].debug !== undefined, debug = (debugIsSet && args[0].debug) || (!debugIsSet && defaults.debug); if ( this.length > 1 && ( content instanceof $ || (typeof content == 'object' && content != null && content.tagName) ) && !contentCloning && debug ) { console.log(contentCloningWarning); } // create a tooltipster instance for each element if it doesn't // already have one or if the multiple option is set, and attach the // object to it this.each(function() { var go = false, $this = $(this), ns = $this.data('tooltipster-ns'), obj = null; if (!ns) { go = true; } else if (multiple) { go = true; } else if (debug) { console.log('Tooltipster: one or more tooltips are already attached to the element below. Ignoring.'); console.log(this); } if (go) { obj = new $.Tooltipster(this, args[0]); // save the reference of the new instance if (!ns) ns = []; ns.push(obj.__namespace); $this.data('tooltipster-ns', ns); // save the instance itself $this.data(obj.__namespace, obj); // call our constructor custom function. // we do this here and not in ::init() because we wanted // the object to be saved in $this.data before triggering // it if (obj.__options.functionInit) { obj.__options.functionInit.call(obj, obj, { origin: this }); } // and now the event, for the plugins and core emitter obj._trigger('init'); } $.tooltipster.__instancesLatestArr.push(obj); }); return this; } } }; // Utilities /** * A class to check if a tooltip can fit in given dimensions * * @param {object} $tooltip The jQuery wrapped tooltip element, or a clone of it */ function Ruler($tooltip) { // list of instance variables this.$container; this.constraints = null; this.__$tooltip; this.__init($tooltip); } Ruler.prototype = { /** * Move the tooltip into an invisible div that does not allow overflow to make * size tests. Note: the tooltip may or may not be attached to the DOM at the * moment this method is called, it does not matter. * * @param {object} $tooltip The object to test. May be just a clone of the * actual tooltip. * @private */ __init: function($tooltip) { this.__$tooltip = $tooltip; this.__$tooltip .css({ // for some reason we have to specify top and left 0 left: 0, // any overflow will be ignored while measuring overflow: 'hidden', // positions at (0,0) without the div using 100% of the available width position: 'absolute', top: 0 }) // overflow must be auto during the test. We re-set this in case // it were modified by the user .find('.tooltipster-content') .css('overflow', 'auto'); this.$container = $('
') .append(this.__$tooltip) .appendTo('body'); }, /** * Force the browser to redraw (re-render) the tooltip immediately. This is required * when you changed some CSS properties and need to make something with it * immediately, without waiting for the browser to redraw at the end of instructions. * * @see http://stackoverflow.com/questions/3485365/how-can-i-force-webkit-to-redraw-repaint-to-propagate-style-changes * @private */ __forceRedraw: function() { // note: this would work but for Webkit only //this.__$tooltip.close(); //this.__$tooltip[0].offsetHeight; //this.__$tooltip.open(); // works in FF too var $p = this.__$tooltip.parent(); this.__$tooltip.detach(); this.__$tooltip.appendTo($p); }, /** * Set maximum dimensions for the tooltip. A call to ::measure afterwards * will tell us if the content overflows or if it's ok * * @param {int} width * @param {int} height * @return {Ruler} * @public */ constrain: function(width, height) { this.constraints = { width: width, height: height }; this.__$tooltip.css({ // we disable display:flex, otherwise the content would overflow without // creating horizontal scrolling (which we need to detect). display: 'block', // reset any previous height height: '', // we'll check if horizontal scrolling occurs overflow: 'auto', // we'll set the width and see what height is generated and if there // is horizontal overflow width: width }); return this; }, /** * Reset the tooltip content overflow and remove the test container * * @returns {Ruler} * @public */ destroy: function() { // in case the element was not a clone this.__$tooltip .detach() .find('.tooltipster-content') .css({ // reset to CSS value display: '', overflow: '' }); this.$container.remove(); }, /** * Removes any constraints * * @returns {Ruler} * @public */ free: function() { this.constraints = null; // reset to natural size this.__$tooltip.css({ display: '', height: '', overflow: 'visible', width: '' }); return this; }, /** * Returns the size of the tooltip. When constraints are applied, also returns * whether the tooltip fits in the provided dimensions. * The idea is to see if the new height is small enough and if the content does * not overflow horizontally. * * @param {int} width * @param {int} height * @returns {object} An object with a bool `fits` property and a `size` property * @public */ measure: function() { this.__forceRedraw(); var tooltipBcr = this.__$tooltip[0].getBoundingClientRect(), result = { size: { // bcr.width/height are not defined in IE8- but in this // case, bcr.right/bottom will have the same value // except in iOS 8+ where tooltipBcr.bottom/right are wrong // after scrolling for reasons yet to be determined height: tooltipBcr.height || tooltipBcr.bottom, width: tooltipBcr.width || tooltipBcr.right }}; if (this.constraints) { // note: we used to use offsetWidth instead of boundingRectClient but // it returned rounded values, causing issues with sub-pixel layouts. // note2: noticed that the bcrWidth of text content of a div was once // greater than the bcrWidth of its container by 1px, causing the final // tooltip box to be too small for its content. However, evaluating // their widths one against the other (below) surprisingly returned // equality. Happened only once in Chrome 48, was not able to reproduce // => just having fun with float position values... var $content = this.__$tooltip.find('.tooltipster-content'), height = this.__$tooltip.outerHeight(), contentBcr = $content[0].getBoundingClientRect(), fits = { height: height <= this.constraints.height, width: ( // this condition accounts for min-width property that // may apply tooltipBcr.width <= this.constraints.width // the -1 is here because scrollWidth actually returns // a rounded value, and may be greater than bcr.width if // it was rounded up. This may cause an issue for contents // which actually really overflow by 1px or so, but that // should be rare. Not sure how to solve this efficiently. // See http://blogs.msdn.com/b/ie/archive/2012/02/17/sub-pixel-rendering-and-the-css-object-model.aspx && contentBcr.width >= $content[0].scrollWidth - 1 ) }; result.fits = fits.height && fits.width; } // old versions of IE get the width wrong for some reason and it causes // the text to be broken to a new line, so we round it up. If the width // is the width of the screen though, we can assume it is accurate. if ( env.IE && env.IE <= 11 && result.size.width !== env.window.document.documentElement.clientWidth ) { result.size.width = Math.ceil(result.size.width) + 1; } return result; } }; // quick & dirty compare function, not bijective nor multidimensional function areEqual(a,b) { var same = true; $.each(a, function(i, _) { if (b[i] === undefined || a[i] !== b[i]) { same = false; return false; } }); return same; } /** * A fast function to check if an element is still in the DOM. It * tries to use an id as ids are indexed by the browser, or falls * back to jQuery's `contains` method. May fail if two elements * have the same id, but so be it * * @param {object} $obj A jQuery-wrapped HTML element * @return {boolean} */ function bodyContains($obj) { var id = $obj.attr('id'), el = id ? env.window.document.getElementById(id) : null; // must also check that the element with the id is the one we want return el ? el === $obj[0] : $.contains(env.window.document.body, $obj[0]); } // detect IE versions for dirty fixes var uA = navigator.userAgent.toLowerCase(); if (uA.indexOf('msie') != -1) env.IE = parseInt(uA.split('msie')[1]); else if (uA.toLowerCase().indexOf('trident') !== -1 && uA.indexOf(' rv:11') !== -1) env.IE = 11; else if (uA.toLowerCase().indexOf('edge/') != -1) env.IE = parseInt(uA.toLowerCase().split('edge/')[1]); // detecting support for CSS transitions function transitionSupport() { // env.window is not defined yet when this is called if (!win) return false; var b = win.document.body || win.document.documentElement, s = b.style, p = 'transition', v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms']; if (typeof s[p] == 'string') { return true; } p = p.charAt(0).toUpperCase() + p.substr(1); for (var i=0; i' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' ); // hide arrow if asked if (!this.__options.arrow) { $html .find('.tooltipster-box') .css('margin', 0) .end() .find('.tooltipster-arrow') .hide(); } // apply min/max width if asked if (this.__options.minWidth) { $html.css('min-width', this.__options.minWidth + 'px'); } if (this.__options.maxWidth) { $html.css('max-width', this.__options.maxWidth + 'px'); } this.__instance._$tooltip = $html; // tell the instance that the tooltip element has been created this.__instance._trigger('created'); }, /** * Used when the plugin is to be unplugged * * @private */ __destroy: function() { this.__instance._off('.'+ self.__namespace); }, /** * (Re)compute this.__options from the options declared to the instance * * @private */ __optionsFormat: function() { var self = this; // get the options self.__options = self.__instance._optionsExtract(pluginName, self.__defaults()); // for backward compatibility, deprecated in v4.0.0 if (self.__options.position) { self.__options.side = self.__options.position; } // options formatting // format distance as a four-cell array if it ain't one yet and then make // it an object with top/bottom/left/right properties if (typeof self.__options.distance != 'object') { self.__options.distance = [self.__options.distance]; } if (self.__options.distance.length < 4) { if (self.__options.distance[1] === undefined) self.__options.distance[1] = self.__options.distance[0]; if (self.__options.distance[2] === undefined) self.__options.distance[2] = self.__options.distance[0]; if (self.__options.distance[3] === undefined) self.__options.distance[3] = self.__options.distance[1]; self.__options.distance = { top: self.__options.distance[0], right: self.__options.distance[1], bottom: self.__options.distance[2], left: self.__options.distance[3] }; } // let's transform: // 'top' into ['top', 'bottom', 'right', 'left'] // 'right' into ['right', 'left', 'top', 'bottom'] // 'bottom' into ['bottom', 'top', 'right', 'left'] // 'left' into ['left', 'right', 'top', 'bottom'] if (typeof self.__options.side == 'string') { var opposites = { 'top': 'bottom', 'right': 'left', 'bottom': 'top', 'left': 'right' }; self.__options.side = [self.__options.side, opposites[self.__options.side]]; if (self.__options.side[0] == 'left' || self.__options.side[0] == 'right') { self.__options.side.push('top', 'bottom'); } else { self.__options.side.push('right', 'left'); } } // misc // disable the arrow in IE6 unless the arrow option was explicitly set to true if ( $.tooltipster._env.IE === 6 && self.__options.arrow !== true ) { self.__options.arrow = false; } }, /** * This method must compute and set the positioning properties of the * tooltip (left, top, width, height, etc.). It must also make sure the * tooltip is eventually appended to its parent (since the element may be * detached from the DOM at the moment the method is called). * * We'll evaluate positioning scenarios to find which side can contain the * tooltip in the best way. We'll consider things relatively to the window * (unless the user asks not to), then to the document (if need be, or if the * user explicitly requires the tests to run on the document). For each * scenario, measures are taken, allowing us to know how well the tooltip * is going to fit. After that, a sorting function will let us know what * the best scenario is (we also allow the user to choose his favorite * scenario by using an event). * * @param {object} helper An object that contains variables that plugin * creators may find useful (see below) * @param {object} helper.geo An object with many layout properties * about objects of interest (window, document, origin). This should help * plugin users compute the optimal position of the tooltip * @private */ __reposition: function(event, helper) { var self = this, finalResult, // to know where to put the tooltip, we need to know on which point // of the x or y axis we should center it. That coordinate is the target targets = self.__targetFind(helper), testResults = []; // make sure the tooltip is detached while we make tests on a clone self.__instance._$tooltip.detach(); // we could actually provide the original element to the Ruler and // not a clone, but it just feels right to keep it out of the // machinery. var $clone = self.__instance._$tooltip.clone(), // start position tests session ruler = $.tooltipster._getRuler($clone), satisfied = false, animation = self.__instance.option('animation'); // an animation class could contain properties that distort the size if (animation) { $clone.removeClass('tooltipster-'+ animation); } // start evaluating scenarios $.each(['window', 'document'], function(i, container) { var takeTest = null; // let the user decide to keep on testing or not self.__instance._trigger({ container: container, helper: helper, satisfied: satisfied, takeTest: function(bool) { takeTest = bool; }, results: testResults, type: 'positionTest' }); if ( takeTest == true || ( takeTest != false && satisfied == false // skip the window scenarios if asked. If they are reintegrated by // the callback of the positionTest event, they will have to be // excluded using the callback of positionTested && (container != 'window' || self.__options.viewportAware) ) ) { // for each allowed side for (var i=0; i < self.__options.side.length; i++) { var distance = { horizontal: 0, vertical: 0 }, side = self.__options.side[i]; if (side == 'top' || side == 'bottom') { distance.vertical = self.__options.distance[side]; } else { distance.horizontal = self.__options.distance[side]; } // this may have an effect on the size of the tooltip if there are css // rules for the arrow or something else self.__sideChange($clone, side); $.each(['natural', 'constrained'], function(i, mode) { takeTest = null; // emit an event on the instance self.__instance._trigger({ container: container, event: event, helper: helper, mode: mode, results: testResults, satisfied: satisfied, side: side, takeTest: function(bool) { takeTest = bool; }, type: 'positionTest' }); if ( takeTest == true || ( takeTest != false && satisfied == false ) ) { var testResult = { container: container, // we let the distance as an object here, it can make things a little easier // during the user's calculations at positionTest/positionTested distance: distance, // whether the tooltip can fit in the size of the viewport (does not mean // that we'll be able to make it initially entirely visible, see 'whole') fits: null, mode: mode, outerSize: null, side: side, size: null, target: targets[side], // check if the origin has enough surface on screen for the tooltip to // aim at it without overflowing the viewport (this is due to the thickness // of the arrow represented by the minIntersection length). // If not, the tooltip will have to be partly or entirely off screen in // order to stay docked to the origin. This value will stay null when the // container is the document, as it is not relevant whole: null }; // get the size of the tooltip with or without size constraints var rulerConfigured = (mode == 'natural') ? ruler.free() : ruler.constrain( helper.geo.available[container][side].width - distance.horizontal, helper.geo.available[container][side].height - distance.vertical ), rulerResults = rulerConfigured.measure(); testResult.size = rulerResults.size; testResult.outerSize = { height: rulerResults.size.height + distance.vertical, width: rulerResults.size.width + distance.horizontal }; if (mode == 'natural') { if( helper.geo.available[container][side].width >= testResult.outerSize.width && helper.geo.available[container][side].height >= testResult.outerSize.height ) { testResult.fits = true; } else { testResult.fits = false; } } else { testResult.fits = rulerResults.fits; } if (container == 'window') { if (!testResult.fits) { testResult.whole = false; } else { if (side == 'top' || side == 'bottom') { testResult.whole = ( helper.geo.origin.windowOffset.right >= self.__options.minIntersection && helper.geo.window.size.width - helper.geo.origin.windowOffset.left >= self.__options.minIntersection ); } else { testResult.whole = ( helper.geo.origin.windowOffset.bottom >= self.__options.minIntersection && helper.geo.window.size.height - helper.geo.origin.windowOffset.top >= self.__options.minIntersection ); } } } testResults.push(testResult); // we don't need to compute more positions if we have one fully on screen if (testResult.whole) { satisfied = true; } else { // don't run the constrained test unless the natural width was greater // than the available width, otherwise it's pointless as we know it // wouldn't fit either if ( testResult.mode == 'natural' && ( testResult.fits || testResult.size.width <= helper.geo.available[container][side].width ) ) { return false; } } } }); } } }); // the user may eliminate the unwanted scenarios from testResults, but he's // not supposed to alter them at this point. functionPosition and the // position event serve that purpose. self.__instance._trigger({ edit: function(r) { testResults = r; }, event: event, helper: helper, results: testResults, type: 'positionTested' }); /** * Sort the scenarios to find the favorite one. * * The favorite scenario is when we can fully display the tooltip on screen, * even if it means that the middle of the tooltip is no longer centered on * the middle of the origin (when the origin is near the edge of the screen * or even partly off screen). We want the tooltip on the preferred side, * even if it means that we have to use a constrained size rather than a * natural one (as long as it fits). When the origin is off screen at the top * the tooltip will be positioned at the bottom (if allowed), if the origin * is off screen on the right, it will be positioned on the left, etc. * If there are no scenarios where the tooltip can fit on screen, or if the * user does not want the tooltip to fit on screen (viewportAware == false), * we fall back to the scenarios relative to the document. * * When the tooltip is bigger than the viewport in either dimension, we stop * looking at the window scenarios and consider the document scenarios only, * with the same logic to find on which side it would fit best. * * If the tooltip cannot fit the document on any side, we force it at the * bottom, so at least the user can scroll to see it. */ testResults.sort(function(a, b) { // best if it's whole (the tooltip fits and adapts to the viewport) if (a.whole && !b.whole) { return -1; } else if (!a.whole && b.whole) { return 1; } else if (a.whole && b.whole) { var ai = self.__options.side.indexOf(a.side), bi = self.__options.side.indexOf(b.side); // use the user's sides fallback array if (ai < bi) { return -1; } else if (ai > bi) { return 1; } else { // will be used if the user forced the tests to continue return a.mode == 'natural' ? -1 : 1; } } else { // better if it fits if (a.fits && !b.fits) { return -1; } else if (!a.fits && b.fits) { return 1; } else if (a.fits && b.fits) { var ai = self.__options.side.indexOf(a.side), bi = self.__options.side.indexOf(b.side); // use the user's sides fallback array if (ai < bi) { return -1; } else if (ai > bi) { return 1; } else { // will be used if the user forced the tests to continue return a.mode == 'natural' ? -1 : 1; } } else { // if everything failed, this will give a preference to the case where // the tooltip overflows the document at the bottom if ( a.container == 'document' && a.side == 'bottom' && a.mode == 'natural' ) { return -1; } else { return 1; } } } }); finalResult = testResults[0]; // now let's find the coordinates of the tooltip relatively to the window finalResult.coord = {}; switch (finalResult.side) { case 'left': case 'right': finalResult.coord.top = Math.floor(finalResult.target - finalResult.size.height / 2); break; case 'bottom': case 'top': finalResult.coord.left = Math.floor(finalResult.target - finalResult.size.width / 2); break; } switch (finalResult.side) { case 'left': finalResult.coord.left = helper.geo.origin.windowOffset.left - finalResult.outerSize.width; break; case 'right': finalResult.coord.left = helper.geo.origin.windowOffset.right + finalResult.distance.horizontal; break; case 'top': finalResult.coord.top = helper.geo.origin.windowOffset.top - finalResult.outerSize.height; break; case 'bottom': finalResult.coord.top = helper.geo.origin.windowOffset.bottom + finalResult.distance.vertical; break; } // if the tooltip can potentially be contained within the viewport dimensions // and that we are asked to make it fit on screen if (finalResult.container == 'window') { // if the tooltip overflows the viewport, we'll move it accordingly (then it will // not be centered on the middle of the origin anymore). We only move horizontally // for top and bottom tooltips and vice versa. if (finalResult.side == 'top' || finalResult.side == 'bottom') { // if there is an overflow on the left if (finalResult.coord.left < 0) { // prevent the overflow unless the origin itself gets off screen (minus the // margin needed to keep the arrow pointing at the target) if (helper.geo.origin.windowOffset.right - this.__options.minIntersection >= 0) { finalResult.coord.left = 0; } else { finalResult.coord.left = helper.geo.origin.windowOffset.right - this.__options.minIntersection - 1; } } // or an overflow on the right else if (finalResult.coord.left > helper.geo.window.size.width - finalResult.size.width) { if (helper.geo.origin.windowOffset.left + this.__options.minIntersection <= helper.geo.window.size.width) { finalResult.coord.left = helper.geo.window.size.width - finalResult.size.width; } else { finalResult.coord.left = helper.geo.origin.windowOffset.left + this.__options.minIntersection + 1 - finalResult.size.width; } } } else { // overflow at the top if (finalResult.coord.top < 0) { if (helper.geo.origin.windowOffset.bottom - this.__options.minIntersection >= 0) { finalResult.coord.top = 0; } else { finalResult.coord.top = helper.geo.origin.windowOffset.bottom - this.__options.minIntersection - 1; } } // or at the bottom else if (finalResult.coord.top > helper.geo.window.size.height - finalResult.size.height) { if (helper.geo.origin.windowOffset.top + this.__options.minIntersection <= helper.geo.window.size.height) { finalResult.coord.top = helper.geo.window.size.height - finalResult.size.height; } else { finalResult.coord.top = helper.geo.origin.windowOffset.top + this.__options.minIntersection + 1 - finalResult.size.height; } } } } else { // there might be overflow here too but it's easier to handle. If there has // to be an overflow, we'll make sure it's on the right side of the screen // (because the browser will extend the document size if there is an overflow // on the right, but not on the left). The sort function above has already // made sure that a bottom document overflow is preferred to a top overflow, // so we don't have to care about it. // if there is an overflow on the right if (finalResult.coord.left > helper.geo.window.size.width - finalResult.size.width) { // this may actually create on overflow on the left but we'll fix it in a sec finalResult.coord.left = helper.geo.window.size.width - finalResult.size.width; } // if there is an overflow on the left if (finalResult.coord.left < 0) { // don't care if it overflows the right after that, we made our best finalResult.coord.left = 0; } } // submit the positioning proposal to the user function which may choose to change // the side, size and/or the coordinates // first, set the rules that corresponds to the proposed side: it may change // the size of the tooltip, and the custom functionPosition may want to detect the // size of something before making a decision. So let's make things easier for the // implementor self.__sideChange($clone, finalResult.side); // add some variables to the helper helper.tooltipClone = $clone[0]; helper.tooltipParent = self.__instance.option('parent').parent[0]; // move informative values to the helper helper.mode = finalResult.mode; helper.whole = finalResult.whole; // add some variables to the helper for the functionPosition callback (these // will also be added to the event fired by self.__instance._trigger but that's // ok, we're just being consistent) helper.origin = self.__instance._$origin[0]; helper.tooltip = self.__instance._$tooltip[0]; // leave only the actionable values in there for functionPosition delete finalResult.container; delete finalResult.fits; delete finalResult.mode; delete finalResult.outerSize; delete finalResult.whole; // keep only the distance on the relevant side, for clarity finalResult.distance = finalResult.distance.horizontal || finalResult.distance.vertical; // beginners may not be comfortable with the concept of editing the object // passed by reference, so we provide an edit function and pass a clone var finalResultClone = $.extend(true, {}, finalResult); // emit an event on the instance self.__instance._trigger({ edit: function(result) { finalResult = result; }, event: event, helper: helper, position: finalResultClone, type: 'position' }); if (self.__options.functionPosition) { var result = self.__options.functionPosition.call(self, self.__instance, helper, finalResultClone); if (result) finalResult = result; } // end the positioning tests session (the user might have had a // use for it during the position event, now it's over) ruler.destroy(); // compute the position of the target relatively to the tooltip root // element so we can place the arrow and make the needed adjustments var arrowCoord, maxVal; if (finalResult.side == 'top' || finalResult.side == 'bottom') { arrowCoord = { prop: 'left', val: finalResult.target - finalResult.coord.left }; maxVal = finalResult.size.width - this.__options.minIntersection; } else { arrowCoord = { prop: 'top', val: finalResult.target - finalResult.coord.top }; maxVal = finalResult.size.height - this.__options.minIntersection; } // cannot lie beyond the boundaries of the tooltip, minus the // arrow margin if (arrowCoord.val < this.__options.minIntersection) { arrowCoord.val = this.__options.minIntersection; } else if (arrowCoord.val > maxVal) { arrowCoord.val = maxVal; } var originParentOffset; // let's convert the window-relative coordinates into coordinates relative to the // future positioned parent that the tooltip will be appended to if (helper.geo.origin.fixedLineage) { // same as windowOffset when the position is fixed originParentOffset = helper.geo.origin.windowOffset; } else { // this assumes that the parent of the tooltip is located at // (0, 0) in the document, typically like when the parent is // . // If we ever allow other types of parent, .tooltipster-ruler // will have to be appended to the parent to inherit css style // values that affect the display of the text and such. originParentOffset = { left: helper.geo.origin.windowOffset.left + helper.geo.window.scroll.left, top: helper.geo.origin.windowOffset.top + helper.geo.window.scroll.top }; } finalResult.coord = { left: originParentOffset.left + (finalResult.coord.left - helper.geo.origin.windowOffset.left), top: originParentOffset.top + (finalResult.coord.top - helper.geo.origin.windowOffset.top) }; // set position values on the original tooltip element self.__sideChange(self.__instance._$tooltip, finalResult.side); if (helper.geo.origin.fixedLineage) { self.__instance._$tooltip .css('position', 'fixed'); } else { // CSS default self.__instance._$tooltip .css('position', ''); } self.__instance._$tooltip .css({ left: finalResult.coord.left, top: finalResult.coord.top, // we need to set a size even if the tooltip is in its natural size // because when the tooltip is positioned beyond the width of the body // (which is by default the width of the window; it will happen when // you scroll the window horizontally to get to the origin), its text // content will otherwise break lines at each word to keep up with the // body overflow strategy. height: finalResult.size.height, width: finalResult.size.width }) .find('.tooltipster-arrow') .css({ 'left': '', 'top': '' }) .css(arrowCoord.prop, arrowCoord.val); // append the tooltip HTML element to its parent self.__instance._$tooltip.appendTo(self.__instance.option('parent')); self.__instance._trigger({ type: 'repositioned', event: event, position: finalResult }); }, /** * Make whatever modifications are needed when the side is changed. This has * been made an independant method for easy inheritance in custom plugins based * on this default plugin. * * @param {object} $obj * @param {string} side * @private */ __sideChange: function($obj, side) { $obj .removeClass('tooltipster-bottom') .removeClass('tooltipster-left') .removeClass('tooltipster-right') .removeClass('tooltipster-top') .addClass('tooltipster-'+ side); }, /** * Returns the target that the tooltip should aim at for a given side. * The calculated value is a distance from the edge of the window * (left edge for top/bottom sides, top edge for left/right side). The * tooltip will be centered on that position and the arrow will be * positioned there (as much as possible). * * @param {object} helper * @return {integer} * @private */ __targetFind: function(helper) { var target = {}, rects = this.__instance._$origin[0].getClientRects(); // these lines fix a Chrome bug (issue #491) if (rects.length > 1) { var opacity = this.__instance._$origin.css('opacity'); if(opacity == 1) { this.__instance._$origin.css('opacity', 0.99); rects = this.__instance._$origin[0].getClientRects(); this.__instance._$origin.css('opacity', 1); } } // by default, the target will be the middle of the origin if (rects.length < 2) { target.top = Math.floor(helper.geo.origin.windowOffset.left + (helper.geo.origin.size.width / 2)); target.bottom = target.top; target.left = Math.floor(helper.geo.origin.windowOffset.top + (helper.geo.origin.size.height / 2)); target.right = target.left; } // if multiple client rects exist, the element may be text split // up into multiple lines and the middle of the origin may not be // best option anymore. We need to choose the best target client rect else { // top: the first var targetRect = rects[0]; target.top = Math.floor(targetRect.left + (targetRect.right - targetRect.left) / 2); // right: the middle line, rounded down in case there is an even // number of lines (looks more centered => check out the // demo with 4 split lines) if (rects.length > 2) { targetRect = rects[Math.ceil(rects.length / 2) - 1]; } else { targetRect = rects[0]; } target.right = Math.floor(targetRect.top + (targetRect.bottom - targetRect.top) / 2); // bottom: the last targetRect = rects[rects.length - 1]; target.bottom = Math.floor(targetRect.left + (targetRect.right - targetRect.left) / 2); // left: the middle line, rounded up if (rects.length > 2) { targetRect = rects[Math.ceil((rects.length + 1) / 2) - 1]; } else { targetRect = rects[rects.length - 1]; } target.left = Math.floor(targetRect.top + (targetRect.bottom - targetRect.top) / 2); } return target; } } }); /* a build task will add "return $;" here */ return $; })); // source --> https://blue4u.com.br/wp-content/plugins/smart-logo-showcase-lite/js/smls-frontend-script.js?ver=1.1.8 function resize() { if (jQuery(window).width() <= 1024) { jQuery('.smls-main-logo-wrapper').addClass('smls-resposive-wrap'); } else { jQuery('.smls-main-logo-wrapper').removeClass('smls-resposive-wrap'); } } jQuery(document).ready(function($) { $(window).resize(resize); resize(); /* * * check window width */ var smlsWindowWidth = $(window).width(); $(window).resize(function() { smlsWindowWidth = $(window).width(); }); /* * Add responsive class for grid column */ if (smlsWindowWidth > 1024) { for (i = 2; i <= 4; i++) { if ($('.smls-grid').hasClass('smls-tablet-column-' + i + '')) { $('.smls-grid').removeClass('smls-tablet-column-' + i + ''); } } for (i = 1; i <= 2; i++) { if ($('.smls-grid').hasClass('smls-mobile-column-' + i + '')) { $('.smls-grid').removeClass('smls-mobile-column-' + i + ''); } } } if (smlsWindowWidth > 740 && smlsWindowWidth <= 1024) { for (i = 2; i <= 6; i++) { if ($('.smls-grid').hasClass('smls-grid-column-' + i + '')) { $('.smls-grid').removeClass('smls-grid-column-' + i + ''); } } for (i = 1; i <= 2; i++) { if ($('.smls-grid').hasClass('smls-mobile-column-' + i + '')) { $('.smls-grid').removeClass('smls-mobile-column-' + i + ''); } } } if (smlsWindowWidth <= 740) { for (i = 2; i <= 6; i++) { if ($('.smls-grid').hasClass('smls-grid-column-' + i + '')) { $('.smls-grid').removeClass('smls-grid-column-' + i + ''); } } for (i = 2; i <= 4; i++) { if ($('.smls-grid').hasClass('smls-tablet-column-' + i + '')) { $('.smls-grid').removeClass('smls-tablet-column-' + i + ''); } } } //for horizontal slide of logo var smls_carousel = {}; $('.smls-carousel-logo').each(function() { var id = $(this).data('id'); var pager = $(this).data('pager'); var controls = $(this).data('controls'); var controls_type = $(this).data('controls-type'); var slide_count = $(this).data('slide-count'); var auto = $(this).data('autoplay'); var auto_speed = $(this).data('auto-speed'); var template = $(this).data('template'); var arrow_type = $(this).data('arrow-type'); if (template == 'template-2') { var margin = 0; } else { var margin = 15; } if (controls_type == 'arrow') { if (arrow_type == 'type-5') { var nav_type = [ '', '' ]; } else { var nav_type = [ '', '' ]; } } else { var nav_type = ['prev', 'next']; } smls_carousel.id = $(this).owlCarousel({ center: false, items: 1, loop: true, margin: margin, nav: controls, dots: pager, dotsEach: true, navText: nav_type, autoplay: auto, autoplayHoverPause: true, autoplayTimeout: auto_speed, animateOut: 'slideOutUp', animateIn: 'slideInUp', responsiveClass: true, responsive: { 768: { items: slide_count }, 0: { items: 1, center: false, nav: false, dots: false }, 480: { items: 1, center: false, nav: false, dots: false }, 481: { items: 2, center: false, nav: false, dots: false }, 740: { items: 2, center: false, nav: false, dots: false } } }); }); /* * Tooltip */ var smls_tool = {}; $('.smls-tooltip').each(function() { var id = $(this).data('id'); var tool_content = $(this).data('tooltip-content'); var tool_template = $(this).data('template'); var tool_position = $(this).data('position'); var animation = $(this).data('animation'); var duration = $(this).data('duration'); if(tool_content != '') { smls_tool.id = $(this).tooltipster({ content: tool_content, animation: animation, animationDuration: duration, position: tool_position, // display the tips to the right of the element theme: ['tooltipster-noir', 'smls-tooltip-' + tool_template + ''] }); } }); /* $('.smls-open').click(() => { $('.smls-overlay-contact-info, .popup-content').addClass('active'); }); $('.smls-close').click(() => { $('.smls-overlay-contact-info, .popup-content').removeClass('active'); }); $('.smls-close').click(() => { $('.smls-popup-open').removeClass('inactive'); }); $('.smls-open').click(() => { $('.smls-popup-open').addClass('inactive'); }); */ //added codes for open and close $('body').on('click','.smls-open',function(){ var myiD = $(this).attr('data-contact-id'); $('.smls-overlay-contact-info').removeClass('active'); $('#contact-'+myiD+' .smls-overlay-contact-info').addClass('active'); }); $('body').on('click','.smls-close',function(){ $('.smls-overlay-contact-info').removeClass('active'); }); }); // source --> https://blue4u.com.br/wp-includes/js/plupload/moxie.min.js?ver=1.3.5 var MXI_DEBUG=!1;!function(s,E){"use strict";var a={};function n(e,t){for(var i,n=[],r=0;rt[s]){a=1;break}}if(!i)return a;switch(i){case">":case"gt":return 0=":case"ge":return 0<=a;case"<=":case"le":return a<=0;case"==":case"=":case"eq":return 0===a;case"<>":case"!=":case"ne":return 0!==a;case"":case"<":case"lt":return a<0;default:return null}},global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return s.OS=s.os,MXI_DEBUG&&(s.debug={runtime:!0,events:!1},s.log=function(){var e,t,i=arguments[0];"string"===n.typeOf(i)&&(i=n.sprintf.apply(this,arguments)),window&&window.console&&window.console.log?window.console.log(i):document&&((e=document.getElementById("moxie-console"))||((e=document.createElement("pre")).id="moxie-console",document.body.appendChild(e)),-1!==n.inArray(n.typeOf(i),["object","array"])?(t=i,e.appendChild(document.createTextNode(t+"\n"))):e.appendChild(document.createTextNode(i+"\n")))}),s}),e("moxie/core/I18n",["moxie/core/utils/Basic"],function(i){var t={};return{addI18n:function(e){return i.extend(t,e)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(e){var t=[].slice.call(arguments,1);return e.replace(/%[a-z]/g,function(){var e=t.shift();return"undefined"!==i.typeOf(e)?e:""})}}}),e("moxie/core/utils/Mime",["moxie/core/utils/Basic","moxie/core/I18n"],function(a,n){var e={mimes:{},extensions:{},addMimeType:function(e){for(var t,i,n=e.split(/,/),r=0;r>16&255,n=s>>8&255,s=255&s,d[l++]=64==r?String.fromCharCode(i):64==o?String.fromCharCode(i,n):String.fromCharCode(i,n,s),c>12&63,n=o>>6&63,r=63&o,l[u++]=s.charAt(o>>18&63)+s.charAt(i)+s.charAt(n)+s.charAt(r),ap.MAX_RESIZE_WIDTH||this.height>p.MAX_RESIZE_HEIGHT)throw new u.ImageError(u.ImageError.MAX_RESOLUTION_ERR);this.exec("Image","downsize",e.width,e.height,e.crop,e.preserveHeaders)}catch(e){this.trigger("error",e.code)}},crop:function(e,t,i){this.downsize(e,t,!0,i)},getAsCanvas:function(){if(!l.can("create_canvas"))throw new u.RuntimeError(u.RuntimeError.NOT_SUPPORTED_ERR);return this.connectRuntime(this.ruid).exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new u.DOMException(u.DOMException.INVALID_STATE_ERR);return this.exec("Image","getAsBlob",e||"image/jpeg",t||90)},getAsDataURL:function(e,t){if(!this.size)throw new u.DOMException(u.DOMException.INVALID_STATE_ERR);return this.exec("Image","getAsDataURL",e||"image/jpeg",t||90)},getAsBinaryString:function(e,t){t=this.getAsDataURL(e,t);return h.atob(t.substring(t.indexOf("base64,")+7))},embed:function(r,e){var o,s=this;e=a.extend({width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90},e||{});try{if(!(r=n.get(r)))throw new u.DOMException(u.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new u.DOMException(u.DOMException.INVALID_STATE_ERR);this.width>p.MAX_RESIZE_WIDTH||this.height;var t=new p;return t.bind("Resize",function(){!function(e,t){var i=this;if(l.can("create_canvas")){var n=i.getAsCanvas();if(n)return r.appendChild(n),n=null,i.destroy(),void s.trigger("embedded")}if(!(n=i.getAsDataURL(e,t)))throw new u.ImageError(u.ImageError.WRONG_FORMAT);l.can("use_data_uri_of",n.length)?(r.innerHTML='',i.destroy(),s.trigger("embedded")):((t=new c).bind("TransportingComplete",function(){o=s.connectRuntime(this.result.ruid),s.bind("Embedded",function(){a.extend(o.getShimContainer().style,{top:"0px",left:"0px",width:i.width+"px",height:i.height+"px"}),o=null},999),o.exec.call(s,"ImageView","display",this.result.uid,width,height),i.destroy()}),t.transport(h.atob(n.substring(n.indexOf("base64,")+7)),e,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:r}))}.call(this,e.type,e.quality)}),t.bind("Load",function(){t.downsize(e)}),this.meta.thumb&&this.meta.thumb.width>=e.width&&this.meta.thumb.height>=e.height?t.load(this.meta.thumb.data):t.clone(this,!1),t}catch(e){this.trigger("error",e.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}}),this.handleEventProps(f),this.bind("Load Resize",function(){!function(e){e=e||this.exec("Image","getInfo");this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}.call(this)},999)}return p.MAX_RESIZE_WIDTH=8192,p.MAX_RESIZE_HEIGHT=8192,p.prototype=i.instance,p}),e("moxie/runtime/html5/Runtime",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/Runtime","moxie/core/utils/Env"],function(s,e,a,u){var c={};return a.addConstructor("html5",function(e){var t,i,n=this,r=a.capTest,o=a.capTrue,o=s.extend({access_binary:r(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return n.can("access_binary")&&!!c.Image},display_media:r(u.can("create_canvas")||u.can("use_data_uri_over32kb")),do_cors:r(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:r(("draggable"in(t=document.createElement("div"))||"ondragstart"in t&&"ondrop"in t)&&("IE"!==u.browser||u.verComp(u.version,9,">"))),filter_by_extension:r("Chrome"===u.browser&&u.verComp(u.version,28,">=")||"IE"===u.browser&&u.verComp(u.version,10,">=")||"Safari"===u.browser&&u.verComp(u.version,7,">=")),return_response_headers:o,return_response_type:function(e){return!("json"!==e||!window.JSON)||u.can("return_response_type",e)},return_status_code:o,report_upload_progress:r(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return n.can("access_binary")&&u.can("create_canvas")},select_file:function(){return u.can("use_fileinput")&&window.File},select_folder:function(){return n.can("select_file")&&"Chrome"===u.browser&&u.verComp(u.version,21,">=")},select_multiple:function(){return n.can("select_file")&&!("Safari"===u.browser&&"Windows"===u.os)&&!("iOS"===u.os&&u.verComp(u.osVersion,"7.0.0",">")&&u.verComp(u.osVersion,"8.0.0","<"))},send_binary_string:r(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:r(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||n.can("send_binary_string")},slice_blob:r(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return n.can("slice_blob")&&n.can("send_multipart")},summon_file_dialog:function(){return n.can("select_file")&&("Firefox"===u.browser&&u.verComp(u.version,4,">=")||"Opera"===u.browser&&u.verComp(u.version,12,">=")||"IE"===u.browser&&u.verComp(u.version,10,">=")||!!~s.inArray(u.browser,["Chrome","Safari"]))},upload_filesize:o},arguments[2]);a.call(this,e,arguments[1]||"html5",o),s.extend(this,{init:function(){this.trigger("Init")},destroy:(i=this.destroy,function(){i.call(n),i=n=null})}),s.extend(this.getShim(),c)}),c}),e("moxie/core/utils/Events",["moxie/core/utils/Basic"],function(o){var s={},a="moxie_"+o.guid();function u(){this.returnValue=!1}function c(){this.cancelBubble=!0}function r(t,e,i){if(e=e.toLowerCase(),t[a]&&s[t[a]]&&s[t[a]][e]){for(var n,r=(n=s[t[a]][e]).length-1;0<=r&&(n[r].orig!==i&&n[r].key!==i||(t.removeEventListener?t.removeEventListener(e,n[r].func,!1):t.detachEvent&&t.detachEvent("on"+e,n[r].func),n[r].orig=null,n[r].func=null,n.splice(r,1),void 0===i));r--);if(n.length||delete s[t[a]][e],o.isEmptyObj(s[t[a]])){delete s[t[a]];try{delete t[a]}catch(e){t[a]=void 0}}}}return{addEvent:function(e,t,i,n){var r;t=t.toLowerCase(),e.addEventListener?e.addEventListener(t,r=i,!1):e.attachEvent&&e.attachEvent("on"+t,r=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=u,e.stopPropagation=c,i(e)}),e[a]||(e[a]=o.guid()),s.hasOwnProperty(e[a])||(s[e[a]]={}),(e=s[e[a]]).hasOwnProperty(t)||(e[t]=[]),e[t].push({func:r,orig:i,key:n})},removeEvent:r,removeAllEvents:function(i,n){i&&i[a]&&o.each(s[i[a]],function(e,t){r(i,t,n)})}}}),e("moxie/runtime/html5/file/FileInput",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,a,u,c,l,d,m){return e.FileInput=function(){var s;u.extend(this,{init:function(e){var t,i,n=this,r=n.getRuntime(),o=(s=e).accept.mimes||d.extList2mimes(s.accept,r.can("filter_by_extension"));(i=r.getShimContainer()).innerHTML='",t=c.get(r.uid),u.extend(t.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),e=c.get(s.browse_button),r.can("summon_file_dialog")&&("static"===c.getStyle(e,"position")&&(e.style.position="relative"),o=parseInt(c.getStyle(e,"z-index"),10)||1,e.style.zIndex=o,i.style.zIndex=o-1,l.addEvent(e,"click",function(e){var t=c.get(r.uid);t&&!t.disabled&&t.click(),e.preventDefault()},n.uid)),e=r.can("summon_file_dialog")?e:i,l.addEvent(e,"mouseover",function(){n.trigger("mouseenter")},n.uid),l.addEvent(e,"mouseout",function(){n.trigger("mouseleave")},n.uid),l.addEvent(e,"mousedown",function(){n.trigger("mousedown")},n.uid),l.addEvent(c.get(s.container),"mouseup",function(){n.trigger("mouseup")},n.uid),t.onchange=function e(t){var i;n.files=[],u.each(this.files,function(e){var t="";if(s.directory&&"."==e.name)return!0;e.webkitRelativePath&&(t="/"+e.webkitRelativePath.replace(/^\//,"")),(e=new a(r.uid,e)).relativePath=t,n.files.push(e)}),"IE"!==m.browser&&"IEMobile"!==m.browser?this.value="":(i=this.cloneNode(!0),this.parentNode.replaceChild(i,this),i.onchange=e),n.files.length&&n.trigger("change")},n.trigger({type:"ready",async:!0}),i=null},disable:function(e){var t=this.getRuntime();(t=c.get(t.uid))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),e=e.getShimContainer();l.removeAllEvents(e,this.uid),l.removeAllEvents(s&&c.get(s.container),this.uid),l.removeAllEvents(s&&c.get(s.browse_button),this.uid),e&&(e.innerHTML=""),t.removeInstance(this.uid),s=e=t=null}})}}),e("moxie/runtime/html5/file/Blob",["moxie/runtime/html5/Runtime","moxie/file/Blob"],function(e,t){return e.Blob=function(){this.slice=function(){return new t(this.getRuntime().uid,function(t,i,n){var e;if(!window.File.prototype.slice)return(e=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?e.call(t,i,n):null;try{return t.slice(),t.slice(i,n)}catch(e){return t.slice(i,n-i)}}.apply(this,arguments))}}}),e("moxie/runtime/html5/file/FileDrop",["moxie/runtime/html5/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime"],function(e,r,c,l,d,m){return e.FileDrop=function(){var t,i,o=[],n=[];function s(e){if(e.dataTransfer&&e.dataTransfer.types){e=c.toArray(e.dataTransfer.types||[]);return-1!==c.inArray("Files",e)||-1!==c.inArray("public.file-url",e)||-1!==c.inArray("application/x-moz-file",e)}}function a(e,t){!function(e){if(!n.length)return!0;e=m.getFileExtension(e.name);return!e||-1!==c.inArray(e,n)}(e)||((e=new r(i,e)).relativePath=t||"",o.push(e))}function u(e,t){var i=[];c.each(e,function(n){i.push(function(e){var t,i;i=e,(t=n).isFile?t.file(function(e){a(e,t.fullPath),i()},function(){i()}):t.isDirectory?function(e,t){var n=[],r=e.createReader();!function t(i){r.readEntries(function(e){e.length?([].push.apply(n,e),t(i)):i()},i)}(function(){u(n,t)})}(t,i):i()})}),c.inSeries(i,function(){t()})}c.extend(this,{init:function(e){var r=this;t=e,i=r.ruid,n=function(e){for(var t=[],i=0;i=")&&p.verComp(p.version,7,"<"),o="Android Browser"===p.browser,s=!1;if(u=e.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),(a=!window.XMLHttpRequest||"IE"===p.browser&&p.verComp(p.version,8,"<")?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;tthis.length())throw new Error("You are trying to read outside the source boundaries.");for(n=this.littleEndian?0:-8*(t-1),i=r=0;rthis.length())throw new Error("You are trying to write outside the source boundaries.");for(n=this.littleEndian?0:-8*(i-1),r=0;r>Math.abs(n+8*r)&255)},BYTE:function(e){return this.read(e,1)},SHORT:function(e){return this.read(e,2)},LONG:function(e){return this.read(e,4)},SLONG:function(e){e=this.read(e,4);return 2147483647=o.length));i++);},purge:function(){this.headers=s=[]}}}}),e("moxie/runtime/html5/image/ExifParser",["moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader","moxie/core/Exceptions"],function(g,o,x){function s(e){var t,l,f,p,i;if(o.call(this,e),l={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"},thumb:{513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength"}},f={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},n=(p={tiffHeader:10}).tiffHeader,t={clear:this.clear},g.extend(this,{read:function(){try{return s.prototype.read.apply(this,arguments)}catch(e){throw new x.ImageError(x.ImageError.INVALID_META_ERR)}},write:function(){try{return s.prototype.write.apply(this,arguments)}catch(e){throw new x.ImageError(x.ImageError.INVALID_META_ERR)}},UNDEFINED:function(){return this.BYTE.apply(this,arguments)},RATIONAL:function(e){return this.LONG(e)/this.LONG(e+4)},SRATIONAL:function(e){return this.SLONG(e)/this.SLONG(e+4)},ASCII:function(e){return this.CHAR(e)},TIFF:function(){return i||null},EXIF:function(){var e=null;if(p.exifIFD){try{e=r.call(this,p.exifIFD,l.exif)}catch(e){return null}if(e.ExifVersion&&"array"===g.typeOf(e.ExifVersion)){for(var t=0,i="";t=this.length())throw new x.ImageError(x.ImageError.INVALID_META_ERR);"ASCII"!==s?(a=u.asArray(s,o,n),s=1==n?a[0]:a,f.hasOwnProperty(i)&&"object"!=typeof s?c[i]=f[i][s]:c[i]=s):c[i]=g.trim(u.STRING(o,n).replace(/\0$/,""))}return c}n&&(p.IFD1=p.tiffHeader+n)}return s.prototype=o.prototype,s}),e("moxie/runtime/html5/image/JPEG",["moxie/core/utils/Basic","moxie/core/Exceptions","moxie/runtime/html5/image/JPEGHeaders","moxie/runtime/html5/utils/BinaryReader","moxie/runtime/html5/image/ExifParser"],function(s,a,u,c,l){return function(e){var i,n,t,r=new c(e);if(65496!==r.SHORT(0))throw new a.ImageError(a.ImageError.WRONG_FORMAT);i=new u(e);try{n=new l(i.get("app1")[0])}catch(e){}function o(e){var t,i=0;for(e=e||r;i<=e.length();){if(65472<=(t=e.SHORT(i+=2))&&t<=65475)return i+=5,{height:e.SHORT(i),width:e.SHORT(i+=2)};t=e.SHORT(i+=2),i+=t-2}return null}t=o.call(this),s.extend(this,{type:"image/jpeg",size:r.length(),width:t&&t.width||0,height:t&&t.height||0,setExif:function(e,t){if(!n)return!1;"object"===s.typeOf(e)?s.each(e,function(e,t){n.setExif(t,e)}):n.setExif(e,t),i.set("app1",n.SEGMENT())},writeHeaders:function(){return arguments.length?i.restore(arguments[0]):i.restore(e)},stripHeaders:function(e){return i.strip(e)},purge:function(){!function(){n&&i&&r&&(n.clear(),i.purge(),r.clear(),t=i=n=r=null)}.call(this)}}),n&&(this.meta={tiff:n.TIFF(),exif:n.EXIF(),gps:n.GPS(),thumb:function(){var e,t,i=n.thumb();if(i&&(e=new c(i),t=o(e),e.clear(),t))return t.data=i,t;return null}()})}}),e("moxie/runtime/html5/image/PNG",["moxie/core/Exceptions","moxie/core/utils/Basic","moxie/runtime/html5/utils/BinaryReader"],function(n,o,s){return function(e){var r,t;function i(){r&&(r.clear(),e=t=r=null)}r=new s(e),function(){for(var e=0,t=0,i=[35152,20039,3338,6666],t=0;t>1;i=null;t=a/t;return 0==t?1:t}(e,r),f=0;f=")||"IE"===a.browser&&a.verComp(a.version,10,">=")||"Safari"===a.browser&&a.verComp(a.version,7,">=")),resize_image:function(){return u.Image&&i.can("access_binary")&&a.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(e){return!("json"!==e||!window.JSON)||!!~o.inArray(e,["text","document",""])},return_status_code:function(e){return!o.arrayDiff(e,[200,404])},select_file:function(){return a.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return i.can("select_file")},summon_file_dialog:function(){return i.can("select_file")&&("Firefox"===a.browser&&a.verComp(a.version,4,">=")||"Opera"===a.browser&&a.verComp(a.version,12,">=")||"IE"===a.browser&&a.verComp(a.version,10,">=")||!!~o.inArray(a.browser,["Chrome","Safari"]))},upload_filesize:r,use_http_method:function(e){return!o.arrayDiff(e,["GET","POST"])}}),o.extend(this,{init:function(){this.trigger("Init")},destroy:(t=this.destroy,function(){t.call(i),t=i=null})}),o.extend(this.getShim(),u)}),u}),e("moxie/runtime/html4/file/FileInput",["moxie/runtime/html4/Runtime","moxie/file/File","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Events","moxie/core/utils/Mime","moxie/core/utils/Env"],function(e,m,h,f,p,s,g){return e.FileInput=function(){var u,c,l=[];function d(){var e,t,i,n,r=this,o=r.getRuntime(),s=h.guid("uid_"),a=o.getShimContainer();u&&(t=f.get(u+"_form"))&&h.extend(t.style,{top:"100%"}),(i=document.createElement("form")).setAttribute("id",s+"_form"),i.setAttribute("method","post"),i.setAttribute("enctype","multipart/form-data"),i.setAttribute("encoding","multipart/form-data"),h.extend(i.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),(n=document.createElement("input")).setAttribute("id",s),n.setAttribute("type","file"),n.setAttribute("name",c.name||"Filedata"),n.setAttribute("accept",l.join(",")),h.extend(n.style,{fontSize:"999px",opacity:0}),i.appendChild(n),a.appendChild(i),h.extend(n.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===g.browser&&g.verComp(g.version,10,"<")&&h.extend(n.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),n.onchange=function(){var e;if(this.value){if(this.files){if(0===(e=this.files[0]).size)return void i.parentNode.removeChild(i)}else e={name:this.value};e=new m(o.uid,e),this.onchange=function(){},d.call(r),r.files=[e],n.setAttribute("id",e.uid),i.setAttribute("id",e.uid+"_form"),r.trigger("change"),n=i=null}},o.can("summon_file_dialog")&&(e=f.get(c.browse_button),p.removeEvent(e,"click",r.uid),p.addEvent(e,"click",function(e){n&&!n.disabled&&n.click(),e.preventDefault()},r.uid)),u=s,a=t=e=null}h.extend(this,{init:function(e){var t,i,n,r=this,o=r.getRuntime();l=(c=e).accept.mimes||s.extList2mimes(e.accept,o.can("filter_by_extension")),t=o.getShimContainer(),n=f.get(e.browse_button),o.can("summon_file_dialog")&&("static"===f.getStyle(n,"position")&&(n.style.position="relative"),i=parseInt(f.getStyle(n,"z-index"),10)||1,n.style.zIndex=i,t.style.zIndex=i-1),i=o.can("summon_file_dialog")?n:t,p.addEvent(i,"mouseover",function(){r.trigger("mouseenter")},r.uid),p.addEvent(i,"mouseout",function(){r.trigger("mouseleave")},r.uid),p.addEvent(i,"mousedown",function(){r.trigger("mousedown")},r.uid),p.addEvent(f.get(e.container),"mouseup",function(){r.trigger("mouseup")},r.uid),n=null,d.call(this),t=null,r.trigger({type:"ready",async:!0})},disable:function(e){var t;(t=f.get(u))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),e=e.getShimContainer();p.removeAllEvents(e,this.uid),p.removeAllEvents(c&&f.get(c.container),this.uid),p.removeAllEvents(c&&f.get(c.browse_button),this.uid),e&&(e.innerHTML=""),t.removeInstance(this.uid),u=l=c=e=t=null}})}}),e("moxie/runtime/html4/file/FileReader",["moxie/runtime/html4/Runtime","moxie/runtime/html5/file/FileReader"],function(e,t){return e.FileReader=t}),e("moxie/runtime/html4/xhr/XMLHttpRequest",["moxie/runtime/html4/Runtime","moxie/core/utils/Basic","moxie/core/utils/Dom","moxie/core/utils/Url","moxie/core/Exceptions","moxie/core/utils/Events","moxie/file/Blob","moxie/xhr/FormData"],function(e,f,p,g,x,E,y,w){return e.XMLHttpRequest=function(){var l,d,m;function h(t){var e,i,n,r=this,o=!1;if(m){if(e=m.id.replace(/_iframe$/,""),e=p.get(e+"_form")){for(n=(i=e.getElementsByTagName("input")).length;n--;)switch(i[n].getAttribute("type")){case"hidden":i[n].parentNode.removeChild(i[n]);break;case"file":o=!0}i=[],o||e.parentNode.removeChild(e),e=null}setTimeout(function(){E.removeEvent(m,"load",r.uid),m.parentNode&&m.parentNode.removeChild(m);var e=r.getRuntime().getShimContainer();e.children.length||e.parentNode.removeChild(e),e=m=null,t()},1)}}f.extend(this,{send:function(t,e){var i,n,r,o,s,a,u=this,c=u.getRuntime();if(l=d=null,e instanceof w&&e.hasBlob()){if(o=e.getBlob(),i=o.uid,r=p.get(i),!(n=p.get(i+"_form")))throw new x.DOMException(x.DOMException.NOT_FOUND_ERR)}else i=f.guid("uid_"),(n=document.createElement("form")).setAttribute("id",i+"_form"),n.setAttribute("method",t.method),n.setAttribute("enctype","multipart/form-data"),n.setAttribute("encoding","multipart/form-data"),c.getShimContainer().appendChild(n);n.setAttribute("target",i+"_iframe"),e instanceof w&&e.each(function(e,t){var i;e instanceof y?r&&r.setAttribute("name",t):(i=document.createElement("input"),f.extend(i,{type:"hidden",name:t,value:e}),r?n.insertBefore(i,r):n.appendChild(i))}),n.setAttribute("action",t.url),s=c.getShimContainer()||document.body,(a=document.createElement("div")).innerHTML='',m=a.firstChild,s.appendChild(m),E.addEvent(m,"load",function(){var e;try{e=m.contentWindow.document||m.contentDocument||window.frames[m.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(e.title)?l=e.title.replace(/^(\d+).*$/,"$1"):(l=200,d=f.trim(e.body.innerHTML),u.trigger({type:"progress",loaded:d.length,total:d.length}),o&&u.trigger({type:"uploadprogress",loaded:o.size||1025,total:o.size||1025}))}catch(e){if(!g.hasSameOrigin(t.url))return void h.call(u,function(){u.trigger("error")});l=404}h.call(u,function(){u.trigger("load")})},u.uid),n.submit(),u.trigger("loadstart")},getStatus:function(){return l},getResponse:function(e){if("json"===e&&"string"===f.typeOf(d)&&window.JSON)try{return JSON.parse(d.replace(/^\s*]*>/,"").replace(/<\/pre>\s*$/,""))}catch(e){return null}return d},abort:function(){var e=this;m&&m.contentWindow&&(m.contentWindow.stop?m.contentWindow.stop():m.contentWindow.document.execCommand?m.contentWindow.document.execCommand("Stop"):m.src="about:blank"),h.call(this,function(){e.dispatchEvent("abort")})}})}}),e("moxie/runtime/html4/image/Image",["moxie/runtime/html4/Runtime","moxie/runtime/html5/image/Image"],function(e,t){return e.Image=t}),function(e){for(var t=0;t https://blue4u.com.br/wp-includes/js/plupload/plupload.min.js?ver=2.1.9 !function(e,I,S){var T=e.setTimeout,D={};function w(e){var t=e.required_features,r={};function i(e,t,i){var n={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};n[e]?r[n[e]]=t:i||(r[e]=t)}return"string"==typeof t?F.each(t.split(/\s*,\s*/),function(e){i(e,!0)}):"object"==typeof t?F.each(t,function(e,t){i(t,e)}):!0===t&&(0":"gt","&":"amp",'"':"quot","'":"#39"};return e&&(""+e).replace(/[<>&\"\']/g,function(e){return t[e]?"&"+t[e]+";":e})},toArray:I.toArray,inArray:I.inArray,addI18n:I.addI18n,translate:I.translate,isEmptyObj:I.isEmptyObj,hasClass:I.hasClass,addClass:I.addClass,removeClass:I.removeClass,getStyle:I.getStyle,addEvent:I.addEvent,removeEvent:I.removeEvent,removeAllEvents:I.removeAllEvents,cleanName:function(e){for(var t=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"],i=0;i(i/=1024)?t(e/i,1)+" "+F.translate("gb"):e>(i/=1024)?t(e/i,1)+" "+F.translate("mb"):1024e?(this.trigger("Error",{code:F.FILE_SIZE_ERROR,message:F.translate("File size error."),file:t}),i(!1)):i(!0)}),F.addFileFilter("prevent_duplicates",function(e,t,i){if(e)for(var n=this.files.length;n--;)if(t.name===this.files[n].name&&t.size===this.files[n].size)return this.trigger("Error",{code:F.FILE_DUPLICATE_ERROR,message:F.translate("Duplicate file error."),file:t}),void i(!1);i(!0)}),F.Uploader=function(e){var u,i,n,p,t=F.guid(),l=[],h={},o=[],d=[],c=!1;function r(){var e,t,i=0;if(this.state==F.STARTED){for(t=0;tu?(t=Math.min(u,a.size-c),a.slice(c,c+t)):(t=a.size,a),u&&d.chunks&&(r.settings.send_chunk_number?(n.chunk=Math.ceil(c/u),n.chunks=Math.ceil(a.size/u)):(n.offset=c,n.total=a.size)),(p=new I.XMLHttpRequest).upload&&(p.upload.onprogress=function(e){s.loaded=Math.min(s.size,c+e.loaded),r.trigger("UploadProgress",s)}),p.onload=function(){400<=p.status?f():(l=r.settings.max_retries,t=a.size?(s.size!=s.origSize&&(a.destroy(),a=null),r.trigger("UploadProgress",s),s.status=F.DONE,r.trigger("FileUploaded",s,{response:p.responseText,status:p.status,responseHeaders:p.getAllResponseHeaders()})):T(g,1))},p.onerror=function(){f()},p.onloadend=function(){this.destroy(),p=null},r.settings.multipart&&d.multipart?(p.open("post",o,!0),F.each(r.settings.headers,function(e,t){p.setRequestHeader(t,e)}),i=new I.FormData,F.each(F.extend(n,r.settings.multipart_params),function(e,t){i.append(t,e)}),i.append(r.settings.file_data_name,e),p.send(i,{runtime_order:r.settings.runtimes,required_caps:r.settings.required_features,preferred_caps:h})):(o=F.buildUrl(r.settings.url,F.extend(n,r.settings.multipart_params)),p.open("post",o,!0),p.setRequestHeader("Content-Type","application/octet-stream"),F.each(r.settings.headers,function(e,t){p.setRequestHeader(t,e)}),p.send(e,{runtime_order:r.settings.runtimes,required_caps:r.settings.required_features,preferred_caps:h})))}s.loaded&&(c=s.loaded=u?u*Math.floor(s.loaded/u):0),a=s.getSource(),r.settings.resize.enabled&&function(e,t){if(e.ruid){e=I.Runtime.getInfo(e.ruid);if(e)return e.can(t)}}(a,"send_binary_string")&&~I.inArray(a.type,["image/jpeg","image/png"])?function(t,e,i){var n=new I.Image;try{n.onload=function(){if(e.width>this.width&&e.height>this.height&&e.quality===S&&e.preserve_headers&&!e.crop)return this.destroy(),i(t);n.downsize(e.width,e.height,e.crop,e.preserve_headers)},n.onresize=function(){i(this.getAsBlob(t.type,e.quality)),this.destroy()},n.onerror=function(){i(t)},n.load(t)}catch(e){i(t)}}.call(this,a,r.settings.resize,function(e){a=e,s.size=e.size,g()}):g()}function R(e,t){s(t)}function E(e){if(e.state==F.STARTED)i=+new Date;else if(e.state==F.STOPPED)for(var t=e.files.length-1;0<=t;t--)e.files[t].status==F.UPLOADING&&(e.files[t].status=F.QUEUED,a())}function y(){p&&p.abort()}function v(e){a(),T(function(){r.call(e)},1)}function z(e,t){t.code===F.INIT_ERROR?e.destroy():t.code===F.HTTP_ERROR&&(t.file.status=F.FAILED,s(t.file),e.state==F.STARTED&&(e.trigger("CancelUpload"),T(function(){r.call(e)},1)))}function O(e){e.stop(),F.each(l,function(e){e.destroy()}),l=[],o.length&&(F.each(o,function(e){e.destroy()}),o=[]),d.length&&(F.each(d,function(e){e.destroy()}),d=[]),c=!(h={}),i=p=null,n.reset()}u={runtimes:I.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},_.call(this,e,null,!0),n=new F.QueueProgress,F.extend(this,{id:t,uid:t,state:F.STOPPED,features:{},runtime:null,files:l,settings:u,total:n,init:function(){var t,i=this,e=i.getOption("preinit");return"function"==typeof e?e(i):F.each(e,function(e,t){i.bind(t,e)}),function(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",y),this.bind("BeforeUpload",m),this.bind("UploadFile",b),this.bind("UploadProgress",R),this.bind("StateChanged",E),this.bind("QueueChanged",a),this.bind("Error",z),this.bind("FileUploaded",v),this.bind("Destroy",O)}.call(i),F.each(["container","browse_button","drop_element"],function(e){if(null===i.getOption(e))return!(t={code:F.INIT_ERROR,message:F.translate("'%' specified, but cannot be found.")})}),t?i.trigger("Error",t):u.browse_button||u.drop_element?void g.call(i,u,function(e){var t=i.getOption("init");"function"==typeof t?t(i):F.each(t,function(e,t){i.bind(t,e)}),e?(i.runtime=I.Runtime.getInfo(f()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:F.INIT_ERROR,message:F.translate("Init error.")})}):i.trigger("Error",{code:F.INIT_ERROR,message:F.translate("You must specify either 'browse_button' or 'drop_element'.")})},setOption:function(e,t){_.call(this,e,t,!this.runtime)},getOption:function(e){return e?u[e]:u},refresh:function(){o.length&&F.each(o,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=F.STARTED&&(this.state=F.STARTED,this.trigger("StateChanged"),r.call(this))},stop:function(){this.state!=F.STOPPED&&(this.state=F.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){c=arguments[0]===S||arguments[0],o.length&&F.each(o,function(e){e.disable(c)}),this.trigger("DisableBrowse",c)},getFile:function(e){for(var t=l.length-1;0<=t;t--)if(l[t].id===e)return l[t]},addFile:function(e,n){var r,s=this,a=[],o=[];r=f(),function e(i){var t=I.typeOf(i);if(i instanceof I.File){if(!i.ruid&&!i.isDetached()){if(!r)return!1;i.ruid=r,i.connectRuntime(r)}e(new F.File(i))}else i instanceof I.Blob?(e(i.getSource()),i.destroy()):i instanceof F.File?(n&&(i.name=n),a.push(function(t){var n,e,r;n=i,e=function(e){e||(l.push(i),o.push(i),s.trigger("FileFiltered",i)),T(t,1)},r=[],I.each(s.settings.filters,function(e,i){D[i]&&r.push(function(t){D[i].call(s,e,n,function(e){t(!e)})})}),I.inSeries(r,e)})):-1!==I.inArray(t,["file","blob"])?e(new I.File(null,i)):"node"===t&&"filelist"===I.typeOf(i.files)?I.each(i.files,e):"array"===t&&(n=null,I.each(i,e))}(e),a.length&&I.inSeries(a,function(){o.length&&s.trigger("FilesAdded",o)})},removeFile:function(e){for(var t="string"==typeof e?e:e.id,i=l.length-1;0<=i;i--)if(l[i].id===t)return this.splice(i,1)[0]},splice:function(e,t){var t=l.splice(e===S?0:e,t===S?l.length:t),i=!1;return this.state==F.STARTED&&(F.each(t,function(e){if(e.status===F.UPLOADING)return!(i=!0)}),i&&this.stop()),this.trigger("FilesRemoved",t),F.each(t,function(e){e.destroy()}),i&&this.start(),t},dispatchEvent:function(e){var t,i;if(e=e.toLowerCase(),t=this.hasEventListener(e)){t.sort(function(e,t){return t.priority-e.priority}),(i=[].slice.call(arguments)).shift(),i.unshift(this);for(var n=0;n