/*! jQuery v3.7.1 | (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(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=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))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(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&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(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&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(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 U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);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&&C){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=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(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(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===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]||I.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]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(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(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(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=I.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 T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.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 ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(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 Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.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)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.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),v(t)&&(t=t.call(e,n,ce.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)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.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"===ce.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"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(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)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(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?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.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.on("mouseenter",e).on("mouseleave",t||e)}}),ce.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){ce.fn[n]=function(e,t){return 00) { return [parseInt(el.offsetWidth),parseInt(el.offsetHeight)]; } else if (el.clientWidth && parseInt(el.clientWidth)>0) { return [parseInt(el.clientWidth),parseInt(el.clientHeight)]; } return [0,0]; } function centerWindow(el) {// jQuery compatible if (typeof el == "string") el = getElement(el); ed = componentDimensions(el); elParent = el.parentNode; wd = componentDimensions(elParent); el.style.position = "absolute"; el.style.left = parseInt(wd[0]/2 - ed[0]/2) + "px"; el.style.top = parseInt(wd[1]/2 - ed[1]/2) + "px"; } function numberFormat(number,decimals,tsep,dsep) { // jQuery compatible if (isNaN(number) || isNaN(parseFloat(number))) { return 'NaN'; } if (decimals === false || decimals == null || decimals < 0) decimals = 0; if (!tsep) tsep = ','; if (!dsep) dsep = '.'; try { const parts = number.toFixed(decimals).split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, tsep); return parts.join(dsep); } catch (e) { return 'NaN'; } } function burpmail(el,name,reversedomain,linkit,usetitle) { if (typeof usetitle != "string") usetitle = ""; email = name + "@" for (c=reversedomain.length-1;c>=0;c--) email += reversedomain.charAt(c); email = linkit?"" + (usetitle != '' ? usetitle : email) + "":email; if (el != null) getElement(el).innerHTML = email; else return email; } function anchorOffset(anchor,offset) { // scroll screen to anchor +- offset document.location = anchor; window.scrollBy(0, offset); } function dateDiff(d1s,d2s) { if (d1s.length != 10 || d1s.length != d2s.length) return 0; const d1 = new Date(d1s); const d2 = new Date(d2s); const diffTime = d2.getTime() - d1.getTime(); const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24)); return diffDays; } function isDate(d, isDatetime) { if (isDatetime) dateRegex = /^[0-9]{4}-[0-9]{2}-[0-9]{2}( [0-9]{2}:[0-9]{2}:[0-9]{2})?$/; else dateRegex = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/; return dateRegex.test(d); } function isMail( email ) { emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; return emailRegex.test(email); } function shuffle( a ){ // randomize array var count = a.length, randomnumber, temp; while( count ){ randomnumber = Math.random() * count-- | 0; temp = a[count]; a[count] = a[randomnumber]; a[randomnumber] = temp } } function Toggle(el,reverses) { // uses bi. el is the element to open/close, and ico will display the icon. reverses is a set of elements to open/close opposite if (reverses != undefined) { for (c=0;c"; getElement('helpbox').style.overflow = canscroll==true?'auto':'hidden'; getElement('helpbox').style.scrollbar = canscroll==true?'auto':'none'; getElement('helpbox').style.display = 'block'; } } function popinpage(page) { if (inIframe()) { parent.popinpage(page); } else { popin("",true); getElement('helpbox').style.padding = '1px'; setTimeout(fixvpdif,100); } } function closepopin() { getElement("helpbox").style.display="none"; getElement("blackscreen").style.display = "none"; } // -- Soridata only -- function vpd(id) { if (inIframe()) { parent.vpd(id); } else { popin("",true); getElement('helpbox').style.padding = '1px'; setTimeout(fixvpdif,100); } } function fixvpdif() { cD = componentDimensions('helpbox'); getElement('vpdif').style.height = (cD[1] - 42) + "px"; } function dosearch() { if (getElement('gsearch').value == '') return false; stxt = encodeURIComponent(getElement('gsearch').value); if (stxt.length > 0) { getElement('gsearch').disabled = true; options = ''; if (getElement('search_mv').checked) options += 'm'; if (getElement('search_av').checked) options += 'b'; if (getElement('search_ar').checked) options += 'a'; if (getElement('search_cp').checked) options += 'c'; getElement('searchreturn').innerHTML = STR_LOADING + " ..."; $.ajax('/index_search.ajax', { async: true, method: 'POST', data: {o : options, k : stxt }, complete: search_complete }); } else alert(langOut('Type a bigger search parameter','Tente uma busca maior','더 넓은 검색을 시도하십시오')); } function langOut(en,pt,ko) { if (SITELANG=='en') return en; if (SITELANG=='pt') return en; if (SITELANG=='ko') return en; } function search_complete(data) { getElement('gsearch').disabled = false; data = parseajax(data); getElement('searchreturn').innerHTML = data; } function openOptions() { if (inIframe()) { parent.openOptions(); } else { if (SITELOGGED>0) { popin("",true); getElement('helpbox').style.padding = '1px'; setTimeout(fixvpdif,100); } else { document.location = '/account/index.php'; } } } function updateCK(opt) { $.ajax("/account/ajaxaccount.ajax?option="+opt+"&switchto=" + getElement(opt).value, { async: true, method: 'GET' }); } function toggledarkmode() { SITE_DARKMODE = !SITE_DARKMODE; document.location = '?darkmode='+(SITE_DARKMODE?"1":"0"); } var searchSize = 0; var searchMaxSize = 0; var searchPhrase = ""; var searchVariation = 30; var searchDirection = false; var addPrompt = false; function animateSearch() { if (searchSize == 0) { searchPhrase = getElement('gsearch').placeholder; searchSize = searchPhrase.length; searchMaxSize = searchSize; } addPrompt = !addPrompt; if (searchDirection) searchSize++; else searchSize--; if (searchSize <= searchMaxSize - searchVariation || searchSize == searchMaxSize) searchDirection = !searchDirection; a = searchPhrase.substring(0,searchSize+1); getElement('gsearch').placeholder = a + (addPrompt ? "|" : ""); setTimeout(animateSearch,searchSize==searchMaxSize?2000:100); } $( window ).scroll(function() { try { if (SITEMODE == 'sori') { if (window.scrollY>100) getElement('highlightmenu').style.position = "fixed"; else getElement('highlightmenu').style.position = 'relative'; } getElement('btntopme').style.display = 'block'; } catch (e) { } }); $(window).on( "beforeunload", function() { getElement('blackscreen').style.display = 'block'; getElement('blackscreen').style.opacity = 0.5; }); var STR_LOADING = ""; var AUTO_COMPLETE_TIMER = 1500; var SITE_DARKMODE = false; // if not defined by code, guarantee it exists function checkFavArtists() { if (SITELOGGED>0 && SITE_FAVS_NUMERIC.length > 1) { SITE_FAVS_NUMERIC.forEach(function(id) { $('.fava'+id).addClass('favartisttitle'); $('.favicoa'+id).css('display','block'); }); } } function onPageReady() { if (SITEWIDEWARNING != '') getElement('serversidewarning').innerHTML = SITEWIDEWARNING; if (SITEBMC_SHOW) { $('#frame_sitebmc_pct').attr('aria-valuenow', SITEBMC_PCT); getElement('frame_sitebmc_pct').style.width = SITEBMC_PCT + "%"; getElement('frame_sitebmc_pcttxt').innerHTML = SITEBMC_PCT + "%"; getElement('frame_sitebmc_need').innerHTML = SITEBMC_NEED; getElement('frame_sitebmc').style.display = 'block'; const today = new Date(); const dayOfMonth = today.getDate(); if (dayOfMonth>20 || SITEBMC_PCT < 50) getElement('frame_sitebmc_pct').style.backgroundColor = '#ba335a'; } if (SITEMODE=='sori' && !is_mobile && getElement('gsearch') != null) animateSearch(); if (SITEMODE=='root') burpmail('mail','getintouch','rb.moc.ikusiad',true); if (SITEMODE=='sori') { // the favs numeric comes with a preppended 0 checkFavArtists(); } } // last change 2025.03.30 class CZoomElement { // makes a span (preferably) have a pulsing zoom effect // Usage: CT = new CZoomElement(element,delay); _elementParent = null; _element = null; _elementShadow = null; _elementSize = 1; _delay = 50; constructor(element,delay) { this.zoom = this.zoom.bind(this); // get the parent and empty it (but set size) this._elementParent = document.getElementById(element); this._elementParent.style.display = "inline-block"; this._elementParent.style.position = "relative"; var bc = componentDimensions(element); this._elementParent.style.width = bc[0] + "px"; this._elementParent.style.height = bc[1] + "px"; var content = this._elementParent.innerHTML; this._elementParent.innerHTML = " "; // add two divs in this container this._element = document.createElement("div"); this._elementShadow = document.createElement("div"); this._elementParent.appendChild(this._element); this._elementParent.appendChild(this._elementShadow); // set styles this._element.style.position = "absolute"; this._element.style.display = "inline"; this._element.style.top = "50%"; this._element.style.left = "50%"; this._element.style.border = "0px"; this._element.style.background = "transparent"; this._element.style.transform = "translate(-50%, -50%)"; this._element.innerHTML = content; this._elementShadow.style.position = "absolute"; this._elementShadow.style.display = "inline"; this._elementShadow.style.border = "0px"; this._elementShadow.style.background = "transparent"; this._elementShadow.style.top = "50%"; this._elementShadow.style.left = "50%"; this._elementShadow.style.transform = "translate(-50%, -50%)"; this._elementShadow.innerHTML = content; // prepare delay this._delay = delay; setTimeout(this.zoom,delay); } zoom() { if (this._delay == 0) return false; this._elementSize = this._elementSize + 0.1; if (this._elementSize > 3) this._elementSize = 1; if (this._elementSize > 2) this._elementShadow.style.opacity = 0; else { this._elementShadow.style.fontSize = this._elementSize + "em"; this._elementShadow.style.opacity = (2-this._elementSize); } setTimeout(this.zoom,this._delay); } stop() { this._delay = 0; this._elementShadow.style.display = 'none'; } } class DragAndDrop { // Simple Drag and Drop implementation // Usage: DnD = new DragAndDrop(#containerSelector,callback when order changes); container = null; isDragging = false; dragItem = null; newOrder = ''; callback = null; constructor(containerSelector,callback) { this.container = $(containerSelector); this.callback = callback; this.isDragging = false; this.dragItem = null; this.container .on("mousedown touchstart", ".child", (e) => this.handleStart(e)) .on("mousemove touchmove", (e) => this.handleMove(e)) .on("mouseup touchend", (e) => this.handleEnd(e)); } handleStart(e) { e.preventDefault(); this.isDragging = true; this.dragItem = $(e.currentTarget); this.dragItem.css({ cursor: "grabbing", zIndex: 999, border: '1px solid #888' } ); } handleMove(e) { if (this.isDragging) { e.preventDefault(); let clientX = (e.type === "touchmove") ? e.originalEvent.touches[0].clientX : e.clientX; let clientY = (e.type === "touchmove") ? e.originalEvent.touches[0].clientY : e.clientY; let hoveredItem = this.findHoveredItem(clientX, clientY); if (hoveredItem) { this.swapOrder(this.dragItem, hoveredItem); } } } handleEnd(e) { if (this.isDragging) { e.preventDefault(); this.dragItem.css({ cursor: "grab", zIndex: "", border: '1px dotted #888'}); this.isDragging = false; this.dragItem = null; this.newOrder = this.container.find(".child").map(function () { return parseInt($(this).css("order")); }).get().join(","); if (this.callback !== null && this.callback !== undefined) this.callback(this.newOrder); } } findHoveredItem(clientX, clientY) { let hoveredItem = null; this.container.find(".child").each(function () { let elementRect = this.getBoundingClientRect(); if ( clientX > elementRect.left && clientX < elementRect.right && clientY > elementRect.top && clientY < elementRect.bottom ) { hoveredItem = $(this); return false; } }); return hoveredItem; } swapOrder(item1, item2) { let order1 = parseInt(item1.css("order")); let order2 = parseInt(item2.css("order")); item1.css("order", order2); item2.css("order", order1); } } /* Canvas Controler 4.1 ---------------------------------------------------- Uses jQuery By: Caio Vianna de Lima Netto @ www.daisuki.com.br (cc) Please keep this header when using Latest Revision: 2025.03.31 ############################ IMPORTANT ######################### Regarding internal functions: Coordinates 0,0 are the CENTER of the canvas Sprite 0,0 are the CENTER of the sprite ################################################################ SOME fill colors can be "#xxxxxx" or a gradient definition on the format "#xxxxxx,#xxxxxx,Y" where Y is the direction: 0 to top, 1 to right, 2 to bottom, 3 to left if there is no direction, a CIRCLE is considered Sample Usage: myCC = new CCanvasControler( { canvas: 'canvashtml', fps: is_mobile?5:15, width: 500, height: 500, ## optional autoFit: false, centerCoords: true, stopOnBlur: true, monitorClick: false, monitorHover: false, fillStyle: '#ffffff', fontColor: '#000000', fontFace: 'Helvetica Arial', showFPS: false, render hover tapdown tapup mouseout }); Sample calls: myCC.addSprite(fileurl,cellsX,cellsY) // add a sprite, that can have multiple cells (X,Y), if not, send 1,1 myCC._renderers.push(myRenderer); // add a renderer to the renderers list, a render function receives (CC, canvas, delay) where delay is in ms render ((CC, canvas, delay)) All mouse event handlers are called with this._mouseev being passed as parameter: _mouseev is an object: { pressing: false, isTouch: false, x: 0, y: 0, initX: 0, initY: 0, deltaX: 0, // since start deltaY: 0, // since start speedX: 0, // since start speedY: 0, // since start lastEvent: // mouse down or mouse up time elapsedTime: // time since above } myCC._mousemovehnd.push(mymmh); // add extra mouse move/swipe to monitoring myCC._mousedownhnd.push(mymdh); // add extra mouse/touch down to monitoring myCC._mouseuphnd.push(myMouseUpHandler); // add extra mouse/touch up and out to monitoring myCC.startPreload(plc); // start preload, call plc when complete (which will call myCC.start) function plc(pct) { // this function is called when the preloader is complete if (pct==1) myCC.start(); } Remember: X = width, Y = top To bind the functions with an object, use .bind(object) after the function call to ensure it is properly binded fillText({ text: "", x: 0, y: 0, fontSize: 10, ---- optionals fontFace: "Helvetica", fontColor: "#0000cc", alpha: 1, rotation: 0, align: 'center' // valid: 'left', 'center', 'right' }) draw({ x: 0, y: 0, width: 10, --- optional: height: 10, isSquare: false, rotation: 0, alpha: 1, lineStrike: '#000000', fill: null, lineWidth: 1 }) circle is an alias to draw with square set to false, and you can send radius rect is an alias to draw with square set ot true line({ startX: 0, startY: 0, endX: 0, endY: 0, --- optional: alpha: 1, lineStrike: '#000000', lineWidth: 1, dotted: [2,2] }) drawPolygonDirect({ // send raw data for a polygon instead of a shape + rotation + scale points: [] --- optional: alpha: 1, lineWidth: 1, lineStrike: '#000000', fill: null, clip: false }) drawPolygon({ points: [], // don't forget to close (Check the CCPolygon) center: [0,0], --- optional: alpha: 1, rotation: 0, lineWidth: 1, lineStrike: '#000000', fill: null, scale: 1, clip: false } arc({ x: 0, y: 0, radius: 50, angleStart: Math.PI, angleEnd: 2*Math.PI, --- optional: alpha: 1, lineStrike: '#229944', lineWidth: 1, fill: null }) drawSprite({ sprite: index of sprite, x: 0, y: 0, width: 100, height: 100 --- optionals: alpha: 1, rotation: 0, cellX: 0, cellY: 0 }) To print something in the debug, set _debugOut */ // Canvas attributes var CCCanvasObject = 0; var CCCanvasWidth = 1; var CCCanvasHeight = 2; var CCCanvasContext = 3; var CCCanvasObjectRatio = 4; var CCCanvasObjectScale = 5; // Performance Monitor (internal) var CCPmCounter = 0; var CCPmChkSec = 1; var CCPmDelay = 2; var CCPmFPS = 3; var CCPmFPSActual = 4; var CCPmLastTick = 5; // Sprites (internal) var CCSfile = 0; var CCScols = 1; var CCSrows = 2; var CCSimg = 3; var CCSwidth = 4; var CCSheight = 5; // Premade Polygons, use the drawPolygon with a scale to draw them properly // for square use draw var CCPolygonTriangle = [[0,-1],[-0.87,0.5],[0.87,0.5],[0,-1]]; var CCPolygonPentagon = [[0,-1],[0.93,-0.3],[0.58,0.81],[-0.58,0.81],[-0.93,-0.3],[0,-1]]; var CCPolygonHexagon = [[0.5,-0.87],[-0.5,-0.87],[-1,0],[-0.5,0.87],[0.5,0.87],[1,0],[0.5,0.-0.87]]; var CCPolygonHeptagon = [[0,-1],[-0.95,-0.31],[-0.59,0.81],[0.59,0.81],[0.95,-0.31],[0,-1]]; var CCPolygonStar = [[0,-1],[0.18,-0.26],[0.93,-0.3],[0.31,0.1],[0.58,0.81],[0,0.33],[-0.58,0.81],[-0.31,0.1],[-0.93,-0.3],[-0.18,-0.26],[0,-1]]; class CCanvasControler { _centerCoords = true; // default behaviour, 0,0 is at the CENTER of the canvas. Set to false to use 0,0 as top left _mobile = null; // you can either set prior to start; or let the first touch event detect it _canvas = null; // [ CCCanvasObject; CCCanvasWidth; CCCanvasHeight; CCCanvasContext; curW; curH; W/H; cW/H;initX;initY ] (CCCanvas) _mouseev = null; // See initialize (is an object) _perfMan = null; // [ CCPmCounter; CCPmChkSec; CCPmDelay; CCPmFPS; CCPmFPSActual ] (CCPm) _stopOnBlur = false; // if true; clicking the paused canvas will restart it _stoh = null; // timeout handler _debugOut = ''; // renderer or whatever can set this to a text to be output (showFPS must be on) // sprite control _sprites = null; _sploaded = 0; _spcallback = false; /* function to callback during preload) */ // handlers _renderers = null; _mousemovehnd = null; // includes swipe _mouseuphnd = null; // includes touch end _mousedownhnd = null; // includes touch start _mouseouthnd = null; // no effect on touch screen // working variables _playing = false; _paused = false; _showFPS = false; _preloadComplete = false; _fontFace = 'Arial, Helvetica'; // default text font _fillStyle = ''; // default bg transparent _fontColor = '#888888'; // default id= 0; // use this as an identifier constructor (params) { /* public constructor */ /* canvas: '', fps: 0, width: 0, height: 0, ---- optionals centerCoords: false, autoFit: false, stopOnBlur: true, monitorClick: false, monitorHover: false, fontFace: '', fillStyle: '', fontColor: '', showFPS: true, render hover tapdown tapup mouseout */ // Optional parameters if (('autoFit' in params) === false ) params.autoFit = false; if (('stopOnBlur' in params) === false ) params.stopOnBlur = true; if (('monitorClick' in params) === false) params.monitorClick = false; if (('monitorHover' in params) === false) params.monitorHover = false; if (('centerCoords' in params) === false) params.centerCoords = true; this._centerCoords = params.centerCoords; this._canvas = [null,0,0,null,0,1]; this._perfMan = [0,0,0,28,0]; this._sprites = []; this._autosprites = []; this._renderers = []; this._mousemovehnd= []; this._mouseuphnd= []; this._mousedownhnd= []; this._mouseouthnd= []; this._mouseev = { pressing: false, isTouch: false, x: 0, y: 0, initX: 0, initY: 0, deltaX: 0, deltaY: 0, speedX: 0, speedY: 0, lastEvent: new Date().getTime(), elapsedTime: 0 }; if (!params.fps || parseInt(params.fps) < 1) params.fps = 1; this._canvas = [getElement(params.canvas),params.width,params.height,null,0,0]; this.resetSize(params.width,params.height); // IMPORTANT: the OBJECT defines the canvas buffer, NOT the context this._perfMan = [0,0,Math.floor(1000/params.fps),params.fps,0]; this._canvas[CCCanvasObject].style.display = "block"; this._canvas[CCCanvasObject].focus(); if (params.monitorClick) { $(this._canvas[CCCanvasObject]).on("mousedown",this.mousedown.bind(this,false)); $(this._canvas[CCCanvasObject]).on("mouseup",this.mouseup.bind(this)); $(this._canvas[CCCanvasObject]).on("touchstart",this.mousedown.bind(this,true)); $(this._canvas[CCCanvasObject]).on("touchend",this.mouseup.bind(this)); $(this._canvas[CCCanvasObject]).on("touchcancel",this.mouseup.bind(this)); $(this._canvas[CCCanvasObject]).on("touchmove",this.mousemove.bind(this)); $(this._canvas[CCCanvasObject]).on("mousemove",this.mousemove.bind(this)); $(this._canvas[CCCanvasObject]).on("mouseout",this.mouseout.bind(this)); } else if (params.monitorHover) { $(this._canvas[CCCanvasObject]).on("mousemove",this.mousemove.bind(this)); } else if (params.stopOnBlur) { $(this._canvas[CCCanvasObject]).on("touchend",this.mouseup.bind(this)); $(this._canvas[CCCanvasObject]).on("mouseup",this.mouseup.bind(this)); $(this._canvas[CCCanvasObject]).on("mouseout",this.mouseout.bind(this)); } this._stopOnBlur = params.stopOnBlur; if (params.stopOnBlur) { $(this._canvas[CCCanvasObject]).on("onblur",this.stop.bind(this)); var hidden = "hidden"; if (hidden in document) { $(this._canvas[CCCanvasObject]).on("visibilitychange",this.stop.bind(this)); } window.onblur = this.stop.bind(this); } this._canvas[CCCanvasObjectRatio] = params.width/params.height; this._canvas[CCCanvasObjectScale] = 1; this._canvas[CCCanvasContext].save(); this._canvas[CCCanvasObject].style.padding = '0'; if (params.autoFit) { this._canvas[CCCanvasObject].style.border = '0'; this._canvas[CCCanvasObject].parentNode.style.minHeight = "100%"; this._canvas[CCCanvasObject].parentNode.style.overflow = "hidden"; this.resize(); $(window).resize(this.resize.bind(this)); } if ('fillStyle' in params) this._fillStyle = params.fillStyle; if ('showFPS' in params) this._showFPS = params.showFPS; if ('fontColor' in params) this._fontColor = params.fontColor; if ('fontFace' in params) this._fontFace = params.fontFace; if ('render' in params) this._renderers.push(params.render); if ('hover' in params) this._mousemovehnd.push(params.hover); if ('tapdown' in params) this._mousedownhnd.push(params.tapdown); if ('tapup' in params) this._mouseuphnd.push(params.tapup); if ('mouseout' in params) this._mouseouthnd.push(params.mouseout); this._canvas[CCCanvasContext].fillStyle = this._fillStyle == '' ? 'transparent' : this._fillStyle; } resetSize(w,h) { //if (this._canvas[1] != 0) this._canvas[CCCanvasContext].restore(); this._canvas[1] = w; this._canvas[2] = h; this._canvas[CCCanvasObject].width = w; this._canvas[CCCanvasObject].height = h; this._canvas[CCCanvasContext] = this._canvas[CCCanvasObject].getContext('2d'); this._canvas[CCCanvasObjectRatio] = w/h; this._canvas[CCCanvasContext].save(); } resize() { // zooms in/out (sets scale) //ParentD = componentDimensions(this._canvas[CCCanvasObject].parentNode); // <-- will never resize because it fits the canvas with fixed width/height (body) var ParentD = windowDimensions(); var ParentRatio = ParentD[0] / ParentD[1]; if (ParentRatio>this._canvas[CCCanvasObjectRatio]) { this._canvas[CCCanvasObjectScale] = ParentD[1] / this._canvas[CCCanvasHeight]; } else { this._canvas[CCCanvasObjectScale] = ParentD[0] / this._canvas[CCCanvasWidth]; } var nW = this._canvas[CCCanvasWidth] * this._canvas[CCCanvasObjectScale]; var nH = this._canvas[CCCanvasHeight] * this._canvas[CCCanvasObjectScale]; this._canvas[CCCanvasObject].style.width = nW + "px"; this._canvas[CCCanvasObject].style.height = nH + "px"; } getDistance(x1,y1,x2,y2) { // Phytagoras anyone? var dX = x1-x2; var dY = y1-y2; return Math.sqrt(dX*dX+dY*dY); } getMouseCoordinates(e) { var rect = this._canvas[CCCanvasObject].getBoundingClientRect(); if (this._mobile === false || "undefined" === typeof e.touches) { //this._debugOut += "no e.touches"; var cX = e.clientX; var cY = e.clientY; this._mobile = false; } else { // mobile is (null or true) and e.touches exist //this._debugOut += "e.touches"; var touch = e.touches[0] || e.changedTouches[0]; var cX = touch.pageX-window.scrollX; var cY = touch.pageY-window.scrollY; this._mobile = true; } var posx = Math.floor(this._canvas[CCCanvasWidth]*(cX-rect.left)/(rect.right-rect.left)); var posy = Math.floor(this._canvas[CCCanvasHeight]*(cY-rect.top)/(rect.bottom-rect.top)); return [posx,posy]; } mousedown(istouch,e) { /* private */ try { var ev = e||event; if (ev.originalEvent) ev = ev.originalEvent; if (istouch) this._mobile = true; var epos = this.getMouseCoordinates(ev); this._mouseev = { pressing: true, isTouch: istouch && istouch === true?true:false, x: epos[0] - (this._centerCoords?this._canvas[CCCanvasWidth]/2:0), y: epos[1] - (this._centerCoords?this._canvas[CCCanvasHeight]/2:0), initX: epos[0] - (this._centerCoords?this._canvas[CCCanvasWidth]/2:0), initY: epos[1] - (this._centerCoords?this._canvas[CCCanvasHeight]/2:0), deltaX: 0, deltaY: 0, speedX: 0, speedY: 0, lastEvent: new Date().getTime(), elapsedTime: 0 }; // handlers for (var c=0;c1 ) // too low, increase FPS this._perfMan[CCPmDelay]--; if (this._perfMan[CCPmCounter]>this._perfMan[CCPmFPS]*1.05) // too fast, decrease FPS this._perfMan[CCPmDelay]++; this._perfMan[CCPmCounter] = 0; } // call renderers this.render(delay); if (this._showFPS) { this._canvas[CCCanvasContext].fillStyle = this._fontColor; this._canvas[CCCanvasContext].font = Math.floor(this._debugZoom*10) + 'px sans-serif'; this._canvas[CCCanvasContext].fillText("FPS: " + this._perfMan[CCPmFPSActual]+" (set:"+this._perfMan[CCPmDelay]+"ms, actual:" + delay + "ms)" + (this._error?"e":"") + (this._paused != false?" PAUSED":" PLAYING"),1, 12); this._canvas[CCCanvasContext].fillText("Width, Height, Ratio, Scale: " + this._canvas[CCCanvasWidth] + "," + this._canvas[CCCanvasHeight] + "," + this._canvas[CCCanvasObjectRatio] + "," + this._canvas[CCCanvasObjectScale],1, 24); this._canvas[CCCanvasContext].fillText("I/O mouseev.x, mouseeev.y: " +(this._mouseev.pressing?"pressing" +(this._mobile===true?" (touch)":(this._mobile===false?" (mouse)":" (unknown)")) + this._mouseev.x + "," + this._mouseev.y :"idle"),1, 36); if (this._debugOut != '') this._canvas[CCCanvasContext].fillText("debugOut: " + this._debugOut,1, 48); } this._perfMan[CCPmLastTick] = microtime; if (this._paused == 2) this._paused = true; else if (this._paused == false) this._stoh = setTimeout(this.tick.bind(this),this._perfMan[CCPmDelay]); } render(delay) { /* public */ this._canvas[CCCanvasContext].restore(); this._canvas[CCCanvasContext].save(); this._canvas[CCCanvasContext].clearRect(0,0,this._canvas[CCCanvasWidth],this._canvas[CCCanvasHeight]); if (this._fillStyle != '') { this._canvas[CCCanvasContext].fillStyle = this._fillStyle; this._canvas[CCCanvasContext].fillRect(0,0,this._canvas[CCCanvasWidth],this._canvas[CCCanvasHeight]); } // handlers if (delay == null || delay == 0) delay = this._perfMan[CCPmDelay]; for (var c=0;c 10 && params.fontColor.substr(0,3) != "rgb") { var gd = params.fontColor.split(","); switch (gd[2]) { default: case "0": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(useX,myY,useX,myY+params.fontSize/1.33); break; case "1": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(myX-useX,myY,myX+useX,myY); break; case "2": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(useX,myY+params.fontSize/1.33,useX,myY); break; case "3": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(myX+useX,myY,myX-useX,myY); break; } myGradient.addColorStop(0,this.toRGBA(gd[0],params.alpha)); myGradient.addColorStop(1,this.toRGBA(gd[1],params.alpha)); this._canvas[CCCanvasContext].fillStyle = myGradient; } else this._canvas[CCCanvasContext].fillStyle = params.fontColor; this._canvas[CCCanvasContext].translate(myX,myY); this._canvas[CCCanvasContext].rotate(params.rotation); this._canvas[CCCanvasContext].fillText(params.text, -useX, params.fontSize/1.33); this._canvas[CCCanvasContext].restore(); return measure; } drawSprite(params) { /* public draws one of the sprites */ /* sprite: index of sprite, x: 0, y: 0, --- optionals: width: 100, height: 100 alpha: 1, rotation: 0, cellX: 0, cellY: 0 */ // if only width or only height defined, will draw proportional. If both missing, draw 1:1 // where is regarding the CENTER of the image, and CENTER of canvas (if center coords) if (params.sprite >= this._sprites.length || this._sprites[params.sprite][CCSwidth]==0) { // probably not loaded console.log("Sprite not loaded: " + params.sprite); return false; } if ('alpha' in params === false) params.alpha = 1; if ('rotation' in params === false) params.rotation = 0; if ('cellX' in params === false) params.cellX = 0; if ('cellY' in params === false) params.cellY = 0; if ('width' in params === false) params.width = 0; if ('height' in params === false) params.height = 0; this._canvas[CCCanvasContext].save(); // save current context var cellWidth = this._sprites[params.sprite][CCSwidth]/this._sprites[params.sprite][CCScols]; var cellHeight = this._sprites[params.sprite][CCSheight]/this._sprites[params.sprite][CCSrows]; var cellStartX = params.cellX*cellWidth; var cellStartY = params.cellY*cellHeight; if (params.width != 0 && params.height == 0) { var outputWidth = params.width; var ratio = cellWidth/cellHeight; var outputHeight = params.width/ratio; } else if (params.width == 0 && params.height != 1) { var outputHeight = params.height; var ratio = cellWidth/cellHeight; var outputWidth = params.height*ratio; } else if (params.width == 0 && params.height == 0) { var outputWidth = cellWidth; var outputHeight = cellHeight; } else { var outputWidth = params.width; var outputHeight = params.height; } var whereX = params.x + ((this._centerCoords?(this._canvas[CCCanvasWidth]/2):0) - outputWidth/2); var whereY = params.y + ((this._centerCoords?(this._canvas[CCCanvasHeight]/2):0) - outputHeight/2); this._canvas[CCCanvasContext].globalAlpha = params.alpha; if (params.rotation != 0) { // if it is rotated, use translate/rotate this._canvas[CCCanvasContext].translate(whereX+(outputWidth/2),whereY+outputHeight/2); this._canvas[CCCanvasContext].rotate(params.rotation); this._canvas[CCCanvasContext].drawImage(this._sprites[params.sprite][CCSimg],cellStartX,cellStartY,cellWidth,cellHeight,-outputWidth/2,-outputHeight/2,outputWidth,outputHeight); } else { // if not rotated, we can simply echo it /*if (flipW) { this._canvas[CCCanvasContext].scale(-1,1); this._canvas[CCCanvasContext].drawImage(this._sprites[params.sprite][CCSimg],cellStartX,cellStartY,cellWidth,cellHeight,-whereX-outputWidth,whereY,outputWidth,outputHeight); } else {*/ this._canvas[CCCanvasContext].drawImage(this._sprites[params.sprite][CCSimg],cellStartX,cellStartY,cellWidth,cellHeight,+whereX,whereY,outputWidth,outputHeight); //} } this._canvas[CCCanvasContext].restore(); // restore context before this call return true; } line(params) { /* public draws line */ /* startX: 0, startY: 0, endX: 0, endY: 0, --- optional: alpha: 1, lineStrike: '#000000', lineWidth: 1, dotted: [2,2] dotted: dotted line, two values: pixels drawn, pixels not draw. when using a gradient on the lineStrike, note that straight lines cannot use a gradient perpendicular to them */ if ('alpha' in params === false) params.alpha = 1; if ('lineStrike' in params === false) params.lineStrike = this.toRGBA(this._fontColor,params.alpha); if ('lineWidth' in params === false) params.lineWidth = 1; if ('dotted' in params === false || params.dotted == null) params.dotted = false; this._canvas[CCCanvasContext].save(); // save context before this call if (this._centerCoords) { var sX = params.startX+(this._canvas[CCCanvasWidth]/2); var sY = params.startY+(this._canvas[CCCanvasHeight]/2); var eX = params.endX+(this._canvas[CCCanvasWidth]/2); var eY = params.endY+(this._canvas[CCCanvasHeight]/2); } else { var sX = params.startX; var sY = params.startY; var eX = params.endX; var eY = params.endY; } if (params.lineStrike != null && params.lineStrike != "") { // GRADIENT format: #xxxxxx,#xxxxxx,d where d is direction (0-3) if (params.lineStrike.length==7) this._canvas[CCCanvasContext].strokeStyle = this.toRGBA(params.lineStrike,params.alpha); else if (params.lineStrike.length > 10 && params.lineStrike.substr(0,3) != "rgb") { var gd = params.lineStrike.split(","); var leftX = sX>eX?eX:sX; var rightX = sXeY?eY:sY; var bottomY = sY 10 && params.lineStrike.substr(0,3) != "rgb") { var gd = params.lineStrike.split(","); switch (gd[2]) { default: case "0": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(whereX,whereY+params.radius,whereX,whereY-params.radius); break; case "1": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(whereX-params.radius,whereY,whereX+params.radius,whereY); break; case "2": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(whereX,whereY-params.radius,whereX,whereY+params.radius); break; case "3": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(whereX+params.radius,whereY,whereX-params.radius,whereY); break; } myGradient.addColorStop(0,this.toRGBA(gd[0],params.alpha)); myGradient.addColorStop(1,this.toRGBA(gd[1],params.alpha)); this._canvas[CCCanvasContext].strokeStyle = myGradient; } else this._canvas[CCCanvasContext].strokeStyle = params.lineStrike; } if (params.fill != null && params.fill != "") { if (params.fill.length == 7) this._canvas[CCCanvasContext].fillStyle = this.toRGBA(params.fill,params.alpha); else if (params.fill.length == 17 && params.fill.substr(0,3) != "rgb") { // linear var gd = params.fill.split(","); switch (gd[2]) { default: case "0": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,endY,-radius,topY); break; case "1": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,topY,radius,topY); break; case "2": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,topY,-radius,endY); break; case "3": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(radius,topY,-radius,topY); break; } myGradient.addColorStop(0,this.toRGBA(gd[0],params.alpha)); myGradient.addColorStop(1,this.toRGBA(gd[1],params.alpha)); this._canvas[CCCanvasContext].fillStyle = myGradient; } else if (params.fill.length == 15 && params.fill.substr(0,3) != "rgb") { // circle format: #xxxxxx,#xxxxxx var gd = params.fill.split(","); var myGradient = this._canvas[CCCanvasContext].createRadialGradient(0,0,0,0,0,radius); myGradient.addColorStop(0,this.toRGBA(gd[0],params.alpha)); myGradient.addColorStop(1,this.toRGBA(gd[1],params.alpha)); this._canvas[CCCanvasContext].fillStyle = myGradient; } } this._canvas[CCCanvasContext].beginPath(); if (params.fill != null && params.fill != '') { this._canvas[CCCanvasContext].moveTo(whereX,whereY); this._canvas[CCCanvasContext].arc(whereX,whereY, params.radius, params.angleStart, params.angleEnd); this._canvas[CCCanvasContext].fill(); } else { this._canvas[CCCanvasContext].arc(whereX,whereY, params.radius, params.angleStart, params.angleEnd); } if (params.lineStrike != null && params.lineStrike != '' && params.lineWidth>0) this._canvas[CCCanvasContext].stroke(); this._canvas[CCCanvasContext].closePath(); this._canvas[CCCanvasContext].restore(); // restore context before this call } circle(params) { // accepts parameter radius params.isSquare = false; if ('radius' in params !== false) params.width = params.radius*2; return this.draw(params); } rect(params) { params.isSquare = true; return this.draw(params); } draw(params) { /* public, if not square is a circle. (position is ALWAYS the center) */ /* x: 0, y: 0, width: 10, --- optional: height: 10, isSquare: false, rotation: 0, alpha: 1, lineStrike: '#000000', fill: null, lineWidth: 1 */ // where is regarding the CENTER of the image, default is a square // lineStrike and fill: #xxxxxx (or null) // circles use only width if ('alpha' in params === false) params.alpha = 1; if ('rotation' in params === false) params.rotation = 0; if ('lineWidth' in params === false) params.lineWidth = 1; if ('lineStrike' in params === false) params.lineStrike = this.toRGBA(this._fontColor,params.alpha); else params.lineStrike = this.toRGBA(params.lineStrike,params.alpha); if ('fill' in params === false) params.fill = null; if ('height' in params === false) params.height = params.width; // on circles, this is not required if ('isSquare' in params === false) params.isSquare = true; // default is square this._canvas[CCCanvasContext].save(); // save context before this call this._canvas[CCCanvasContext].lineWidth = params.lineWidth; var whereX = params.x+(this._centerCoords?(this._canvas[CCCanvasWidth]/2):0); var whereY = params.y+(this._centerCoords?(this._canvas[CCCanvasHeight]/2):0); var radius = params.width/2; var topY = params.isSquare?-(params.height/2):-radius; var endY = params.isSquare?(params.height/2):radius; if (params.lineStrike && params.lineStrike != '') { if (params.lineStrike.length == 7) this._canvas[CCCanvasContext].strokeStyle = this.toRGBA(params.lineStrike,params.alpha); else if (params.lineStrike.length > 10 && params.lineStrike.substr(0,3) != "rgb") { var gd = params.lineStrike.split(","); switch (gd[2]) { default: case "0": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,endY,-radius,topY); break; case "1": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,topY,radius,topY); break; case "2": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,topY,-radius,endY); break; case "3": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(radius,topY,-radius,topY); break; } myGradient.addColorStop(0,this.toRGBA(gd[0],params.alpha)); myGradient.addColorStop(1,this.toRGBA(gd[1],params.alpha)); this._canvas[CCCanvasContext].strokeStyle = myGradient; } else this._canvas[CCCanvasContext].strokeStyle = params.lineStrike; } if (params.fill != null && params.fill != "") { if (params.fill.length == 7) this._canvas[CCCanvasContext].fillStyle = this.toRGBA(params.fill,params.alpha); else if (params.fill.length == 17 && params.fill.substr(0,3) != "rgb") { // linear var gd = params.fill.split(","); switch (gd[2]) { default: case "0": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,endY,-radius,topY); break; case "1": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,topY,radius,topY); break; case "2": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(-radius,topY,-radius,endY); break; case "3": var myGradient = this._canvas[CCCanvasContext].createLinearGradient(radius,topY,-radius,topY); break; } myGradient.addColorStop(0,this.toRGBA(gd[0],params.alpha)); myGradient.addColorStop(1,this.toRGBA(gd[1],params.alpha)); this._canvas[CCCanvasContext].fillStyle = myGradient; } else if (params.fill.length == 15 && params.fill.substr(0,3) != "rgb") { // circle format: #xxxxxx,#xxxxxx var gd = params.fill.split(","); var myGradient = this._canvas[CCCanvasContext].createRadialGradient(0,0,0,0,0,radius); myGradient.addColorStop(0,this.toRGBA(gd[0],params.alpha)); myGradient.addColorStop(1,this.toRGBA(gd[1],params.alpha)); this._canvas[CCCanvasContext].fillStyle = myGradient; } } // draw this._canvas[CCCanvasContext].translate(whereX,whereY); this._canvas[CCCanvasContext].rotate(params.rotation); this._canvas[CCCanvasContext].beginPath(); if (params.isSquare) this._canvas[CCCanvasContext].rect(-radius,-(params.height/2),params.width,params.height); else { this._canvas[CCCanvasContext].arc(0,0, radius, 0, 2*Math.PI); } if (params.fill != null && params.fill != '') this._canvas[CCCanvasContext].fill(); if (params.lineWidth > 0 && params.lineStrike != null && params.lineStrike != '') this._canvas[CCCanvasContext].stroke(); this._canvas[CCCanvasContext].closePath(); this._canvas[CCCanvasContext].restore(); // restore context before this call } drawPolygonDirect(params) { // instead of sending a polygon and a center, send the raw coordinates for the polygon (so no need for scale, rotation or center). /* points: [], // don't forget to close --- optional: alpha: 1, lineWidth: 1, lineStrike: '#000000', fill: null, clip: false */ if ('alpha' in params === false) params.alpha = 1; if ('lineWidth' in params === false) params.lineWidth = 1; if ('lineStrike' in params === false) params.lineStrike = this.toRGBA(this._fontColor,params.alpha); else params.lineStrike = this.toRGBA(params.lineStrike,params.alpha); if ('fill' in params === false) params.fill = null; if ('clip' in params === false) params.clip = false; var points = params.points; if (!params.clip) { if (params.lineStrike != null && params.lineStrike != '') { if (params.lineStrike.length == 7) this._canvas[CCCanvasContext].strokeStyle = this.toRGBA(params.lineStrike,params.alpha); else this._canvas[CCCanvasContext].strokeStyle = params.lineStrike; } if (params.fill != null && params.fill != "" && params.fill.length == 7) this._canvas[CCCanvasContext].fillStyle = this.toRGBA(params.fill,params.alpha); } this._canvas[CCCanvasContext].lineWidth=params.lineWidth; this._canvas[CCCanvasContext].beginPath(); this._canvas[CCCanvasContext].moveTo(points[0][0],points[0][1]); for (var p=1;p 0 && params.lineStrike != null) this._canvas[CCCanvasContext].stroke(); this._canvas[CCCanvasContext].closePath(); } } drawPolygon(params) { // center has the center of the polygon for rotation, or you can set yourself. If null, will recalculate /* points: [], // don't forget to close center: [0,0], --- optional: alpha: 1, rotation: 0, lineWidth: 1, lineStrike: '#000000', fill: null, scale: 1 clip: false Check the CCPolygon.. constants for some point lists (use scale to fix the proper radius) */ if ('alpha' in params === false) params.alpha = 1; if ('rotation' in params === false) params.rotation = 0; if ('lineWidth' in params === false) params.lineWidth = 1; if ('lineStrike' in params === false) params.lineStrike = this.toRGBA(this._fontColor,params.alpha); else params.lineStrike = this.toRGBA(params.lineStrike,params.alpha); if ('fill' in params === false) params.fill = null; if ('scale' in params === false) params.scale = 1; if ('clip' in params === false) params.clip = false; if (!params.clip) { if (params.lineStrike != null && params.lineStrike != '') { if (params.lineStrike.length == 7) this._canvas[CCCanvasContext].strokeStyle = this.toRGBA(params.lineStrike,params.alpha); else this._canvas[CCCanvasContext].strokeStyle = params.lineStrike; } if (params.fill != null && params.fill != "" && params.fill.length == 7) this._canvas[CCCanvasContext].fillStyle = this.toRGBA(params.fill,params.alpha); } if (params.scale != 1) { var newPoints = []; // JS sends everything by reference for(var p=0;p 0 && params.lineStrike != null) this._canvas[CCCanvasContext].stroke(); this._canvas[CCCanvasContext].closePath(); this._canvas[CCCanvasContext].restore(); // restore context before this call } } addSprite(file,cellsCols,cellsRows) { /* public */ if (cellsCols == null || parseInt(cellsCols)<1) cellsCols = 1; if (cellsRows == null || parseInt(cellsRows)<1) cellsRows = 1; var nextSprite = this._sprites.length; this._sprites[nextSprite] = [file,cellsCols,cellsRows,new Image(),0,0]; // file str, cells cols, cells rows, image, image width, image height this._sprites[nextSprite][CCSimg].onload = this.spriteLoaded.bind(this); return nextSprite; } startPreload(callbackf) { /* public */ this._spcallback = callbackf; if (this._sprites.length>0) this.showLoading(); for (var c=0;c 0) { this._sprites[s][CCSwidth] = parseInt(this._sprites[s][CCSimg].width); this._sprites[s][CCSheight] = parseInt(this._sprites[s][CCSimg].height); } else { var tmp = new Image(); // some browsers will not properly fill width/height in the image object WHILE it's pre-loaded tmp.src = this._sprites[s][CCSfile]; // since we know it's now loaded, this WILL fill width/heigth this._sprites[s][CCSwidth] = parseInt(tmp.width); this._sprites[s][CCSheight] = parseInt(tmp.height); if (tmp.width == 0 || tmp.height == 0) { // error on download, file does not exist, etc TODO: raise error console.log("Failed to load sprite " + this._sprites[s][CCSfile]); this._sploaded--; // try again this._sprites[s][CCSimg] = new Image(); this._sprites[s][CCSimg].src = this._sprites[s][CCSfile]; this._preloadComplete = false; } var tmp = null; } //console.log("Sprite " + s + ": " + this._sprites[s][CCSwidth] + "," + this._sprites[s][CCSheight]); } } this._spcallback(this._sploaded/size); } doFullScreen () { var isInFullScreen = (document.fullScreenElement && document.fullScreenElement !== null) || // alternative standard method (document.mozFullScreen || document.webkitIsFullScreen); var docElm = document.documentElement; if (docElm.requestFullscreen) { docElm.requestFullscreen(); } else if (docElm.mozRequestFullScreen) { docElm.mozRequestFullScreen(); } else if (docElm.webkitRequestFullScreen) { docElm.webkitRequestFullScreen(); } else { var wscript = new ActiveXObject("Wscript.shell"); // IE wscript.SendKeys("{F11}"); } } smoothing(percent,mode) { /* public */ // send a percentage of a movement position, it will cause smoothing // mode = 0 or true (default) both ends slow // mode = 1 starting smooth (looks like accelerating) // mode = 2 end smooth (looks like braking) if (mode == null || mode === true) mode = 0; if (percent<0) percent = 0; if (percent>1) percent = 1; if (mode != 0) percent /= 2; if (mode == 2) percent += 0.5; var a = Math.PI * percent; var percent = -(Math.cos(a)-1)/2; // new percent if (mode == 1) percent*=2; else if (mode == 2) percent = (percent - 0.5)*2; return percent; } fadeInOut(percent) { // will send a blinking result between 0 and 1 given a percent 0 to 100, slow on 1 return Math.cos((Math.PI*percent)-Math.PI/2); } } // dashedLine for canvas var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype; if (CP && CP.lineTo) { CP.dashedLine = function(x, y, x2, y2, da) { if (!da) da = [10,5]; this.save(); var dx = (x2-x), dy = (y2-y); var len = Math.sqrt(dx*dx + dy*dy); var rot = Math.atan2(dy, dx); this.translate(x, y); this.moveTo(0, 0); this.rotate(rot); var dc = da.length; var di = 0, draw = true; x = 0; while (len > x) { x += da[di++ % dc]; if (x > len) x = len; draw ? this.lineTo(x, 0): this.moveTo(x, 0); draw = !draw; } this.restore(); } }